PyTorch学習ノート5 - 実践的なCNNの応用

投稿日: 2025/09/22

OGP

前回は、基本的な畳み込みニューラルネットワーク(CNN)の構築と学習方法を学びました。
今回は、より実践的なCNNの応用例を紹介します。

1. CNNの応用例

1.1 畳み込み層とプーリング層の追加

前回のモデルに、さらに畳み込み層とプーリング層を追加してみます。

import torch
import torch.nn as nn
import torch.nn.functional as F

class AdvancedCNN(nn.Module):
    def __init__(self):
        super(AdvancedCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)   # 畳み込み層1
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)  # 畳み込み層2
        self.conv3 = nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1) # 畳み込み層3
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)        # プーリング層
        self.fc1 = nn.Linear(128 * 3 * 3, 256)                              # 全結合層1
        self.fc2 = nn.Linear(256, 10)                                       # 全結合層2

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

前回のモデルでは、2つの畳み込み層と1つのプーリング層を使用しましたが、今回は3つの畳み込み層と3つのプーリング層を追加しています。
これにより、モデルの表現力が向上し、より複雑な特徴を学習できるようになります。

実際に実行してみましょう。

model = AdvancedCNN()
criterion = nn.CrossEntropyLoss()  # クロスエントロピー損失
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)  # Adam最適化手法
# ダミーデータの作成
inputs = torch.randn(100, 1, 28, 28)  # 100サンプル、1チャネル、28x28画像
targets = torch.randint(0, 10, (100,)) # 100サンプル、0-9のラベル

# 学習ループ
for epoch in range(100):  # 100エポック
    model.train()  # モデルを訓練モードに設定
    optimizer.zero_grad()  # 勾配の初期化
    outputs = model(inputs)  # 順伝播
    loss = criterion(outputs, targets)  # 損失の計算
    loss.backward()  # 逆伝播
    optimizer.step()  # パラメータの更新

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/100], Loss: {loss.item():.4f}')

実行してみると、損失が徐々に減少していくことが確認できます。

1.2 モデルの評価

学習が完了したら、モデルの評価を行います。

model.eval()  # モデルを評価モードに設定
with torch.no_grad():
    test_inputs = torch.randn(20, 1, 28, 28)  # 20サンプル、1チャネル、28x28画像
    test_targets = torch.randint(0, 10, (20,)) # 20サンプル、0-9のラベル
    test_outputs = model(test_inputs)          # 順伝播
    _, predicted = torch.max(test_outputs, 1)  # 予測クラスの取得
    accuracy = (predicted == test_targets).sum().item() / test_targets.size(0)
    print(f'Accuracy: {accuracy * 100:.2f}%')

ここでは、ランダムに生成したテストデータを使ってモデルの精度を評価しているので、あくまで参考値ですが、実際のデータセットを使用すれば、より正確な評価が可能です。

1.3 モデルの保存と読み込み

学習したモデルを保存し、後で読み込む方法を紹介します。

# モデルの保存
torch.save(model.state_dict(), 'advanced_cnn.pth')
# モデルの読み込み
model = AdvancedCNN()
model.load_state_dict(torch.load('advanced_cnn.pth'))
model.eval()  # 評価モードに設定

これで、学習したモデルを保存し、必要に応じて再利用できるようになりました。

1.4 まとめ

今回は、より実践的なCNNの応用例として、畳み込み層とプーリング層の追加、モデルの評価、保存と読み込みについて学びました。
これらの技術を活用して、より複雑な画像認識タスクに挑戦してみてください。

次回は、さらに高度なトピックとして、転移学習やデータ拡張について紹介します。
お楽しみに!