Shikata Ga Nai

Private? There is no such things.

20. 画像データの分析② 〜CNN(畳み込みニューラルネットワーク)の基礎〜

Hello there, ('ω')ノ

📌 1. CNN(畳み込みニューラルネットワーク)とは?

CNNは、画像認識に特化したニューラルネットワークで、畳み込み層(Convolutional Layer) を使って画像の特徴を抽出します。

✅ CNNの基本構造

CNNの主な構造は以下のとおりです。

層(Layer) 役割
畳み込み層(Convolutional Layer) 画像の特徴(エッジ・パターン)を抽出
活性化関数(ReLU) 非線形性を追加(学習を進めやすくする)
プーリング層(Pooling Layer) 特徴を圧縮して計算を効率化
全結合層(Fully Connected Layer) 画像を最終的なカテゴリに分類

「畳み込み+プーリング」を繰り返し、画像の特徴を学習!


📌 2. 畳み込み層(Convolutional Layer)の仕組み

畳み込み層では、フィルター(カーネル) を使って画像から特徴を抽出します。

例えば、以下のような3×3のフィルターを画像に適用すると、エッジ(輪郭)が強調されます。

入力画像 (5×5)
1  2  3  4  5  
6  7  8  9  10  
11 12 13 14 15  
16 17 18 19 20  
21 22 23 24 25  

フィルター (3×3)
0  1  0  
1 -4  1  
0  1  0  

出力(畳み込み後の画像)
(エッジが強調されたデータ)

フィルターが画像をスキャンし、特徴を学習!
エッジ・線・色の変化など、特徴を捉える!


📌 3. CNNモデルをPyTorchで実装

まずは、PyTorch を使って CNNモデルを構築 し、MNISTデータセット(手書き数字)で学習させます!

✅ PyTorchの準備

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

✅ データの読み込み(MNIST手書き数字データセット)

# データ変換(前処理)
transform = transforms.Compose([
    transforms.ToTensor(),  # Tensorに変換
    transforms.Normalize((0.5,), (0.5,))  # 正規化
])

# データセットのダウンロード&読み込み
train_dataset = torchvision.datasets.MNIST(root="./data", train=True, transform=transform, download=True)
test_dataset = torchvision.datasets.MNIST(root="./data", train=False, transform=transform, download=True)

# データローダー
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)

データをTensorに変換し、[0,1] の範囲にスケーリング!
ミニバッチ(64枚ずつ)で学習を進める!


📌 4. CNNモデルの構築

✅ CNNの定義

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        
        # 畳み込み層1(入力: 1チャンネル, 出力: 32チャンネル, カーネルサイズ: 3)
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        
        # 畳み込み層2(出力: 64チャンネル)
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, padding=1)
        
        # 全結合層
        self.fc1 = nn.Linear(64 * 7 * 7, 128)  # 7×7はプーリング後のサイズ
        self.fc2 = nn.Linear(128, 10)  # 出力は10クラス(0〜9の数字)

    def forward(self, x):
        x = self.pool(self.relu(self.conv1(x)))  # 畳み込み → ReLU → プーリング
        x = self.pool(self.relu(self.conv2(x)))  # 畳み込み → ReLU → プーリング
        x = x.view(-1, 64 * 7 * 7)  # フラット化
        x = self.relu(self.fc1(x))  # 全結合層1
        x = self.fc2(x)  # 全結合層2(出力)
        return x

畳み込み層(Conv2D)で特徴を抽出!
ReLU関数で活性化!
プーリング層(MaxPool2D)で次元を圧縮!
全結合層(Fully Connected)で分類!


📌 5. モデルの学習

# モデルの作成
model = CNN()

# 損失関数と最適化手法
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 学習
num_epochs = 5
for epoch in range(num_epochs):
    for images, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    
    print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")

誤差逆伝播(Backpropagation)で学習!
Adam最適化でパラメータ更新!


📌 6. モデルの評価

# テストデータで評価
correct = 0
total = 0
with torch.no_grad():
    for images, labels in test_loader:
        outputs = model(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f"Accuracy: {100 * correct / total:.2f}%")

モデルの精度を計算!
MNISTの手書き数字を高精度で分類!


🎯 まとめ

CNNは画像認識に特化したディープラーニングモデル!
畳み込み層(Conv2D)を使って画像の特徴を学習!
PyTorchを使ってCNNを実装し、MNISTの手書き数字を分類!
実際に学習し、テストデータで精度を評価!

Best regards, (^^ゞ