代表的なCNNアーキテクチャ
田中VPoE:「畳み込み層の仕組みを理解したところで、次は実際に成果を出してきた代表的な CNN アーキテクチャを見ていこう。NetShop の商品画像分類では、どのモデルをベースにするかが精度を大きく左右する。」
あなた:「ImageNet で勝ってきたモデルたちですね。歴史を追うと設計思想の進化が見えてきそうです。」
田中VPoE:「その通り。単に層を深くすればいいわけじゃない。各アーキテクチャがどんな課題を解決してきたのかを理解するのが重要だ。」
CNN アーキテクチャの進化
画像認識の発展は CNN アーキテクチャの進化と密接に結びついています。
AlexNet (2012) → VGG (2014) → GoogLeNet (2014) → ResNet (2015) → EfficientNet (2019)
8層 19層 22層 152層 可変
AlexNet:深層学習の幕開け
2012年の ImageNet コンペティションで従来手法を圧倒し、深層学習ブームの火付け役となりました。
import torch.nn as nn
class AlexNetSimplified(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(64, 192, kernel_size=5, padding=2),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
nn.Conv2d(192, 384, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(384, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.Conv2d(256, 256, kernel_size=3, padding=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=3, stride=2),
)
self.classifier = nn.Sequential(
nn.Dropout(),
nn.Linear(256 * 6 * 6, 4096),
nn.ReLU(inplace=True),
nn.Dropout(),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Linear(4096, num_classes),
)
def forward(self, x):
x = self.features(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
AlexNet の革新点:
- ReLU 活性化関数の採用(Sigmoid より学習が高速)
- Dropout による正則化
- GPU を活用した大規模学習
VGGNet:シンプルさの力
「3x3 の小さなフィルタを深く積み重ねる」という設計思想で高精度を達成しました。
VGG16 の構造:
Block 1: Conv3-64 x 2 + MaxPool → 224→112
Block 2: Conv3-128 x 2 + MaxPool → 112→56
Block 3: Conv3-256 x 3 + MaxPool → 56→28
Block 4: Conv3-512 x 3 + MaxPool → 28→14
Block 5: Conv3-512 x 3 + MaxPool → 14→7
FC: 4096 → 4096 → 1000
設計のポイント:
- 3x3 フィルタ2層 = 5x5 フィルタ1層と同じ受容野だが、パラメータが少ない
- チャンネル数を段階的に増加(64→128→256→512)
- パラメータ数は約1.38億と非常に多い(大部分が全結合層)
ResNet:残差接続の革命
「層を深くするほど精度が下がる」という劣化問題をスキップ接続で解決しました。
通常のブロック: 残差ブロック(ResNet):
x → [Conv] → [Conv] → y x → [Conv] → [Conv] → (+) → y
| ↑
└──── skip ────────┘
y = F(x) + x
class ResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1):
super().__init__()
self.conv1 = nn.Conv2d(in_channels, out_channels, 3,
stride=stride, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)
self.conv2 = nn.Conv2d(out_channels, out_channels, 3,
stride=1, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
# チャンネル数やサイズが異なる場合の調整
self.shortcut = nn.Sequential()
if stride != 1 or in_channels != out_channels:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channels, out_channels, 1,
stride=stride, bias=False),
nn.BatchNorm2d(out_channels)
)
def forward(self, x):
out = self.relu(self.bn1(self.conv1(x)))
out = self.bn2(self.conv2(out))
out += self.shortcut(x) # 残差接続
out = self.relu(out)
return out
ResNet の革新点:
- スキップ接続で勾配消失を防止し、152層でも安定学習
- Identity マッピング:何も学習しなければ入力をそのまま出力
EfficientNet:効率的なスケーリング
幅・深さ・解像度の3軸を同時にバランスよくスケーリングする手法です。
スケーリングの3軸:
- 幅(Width): チャンネル数を増やす
- 深さ(Depth): 層数を増やす
- 解像度(Resolution): 入力画像サイズを大きくする
アーキテクチャ比較
| モデル | 層数 | パラメータ数 | Top-1 精度 | 特徴 |
|---|---|---|---|---|
| AlexNet | 8 | 61M | 63.3% | 深層学習の先駆け |
| VGG16 | 16 | 138M | 74.4% | シンプルな設計 |
| ResNet50 | 50 | 25.6M | 79.3% | 残差接続 |
| EfficientNet-B0 | - | 5.3M | 77.3% | 効率的スケーリング |
| EfficientNet-B7 | - | 66M | 84.3% | 最高精度クラス |
NetShop での使い分け
| 用途 | 推奨モデル | 理由 |
|---|---|---|
| プロトタイプ | ResNet18 | 軽量で学習が速い |
| 本番(精度重視) | ResNet50 / EfficientNet-B3 | 精度とコストのバランス |
| エッジデバイス | MobileNetV3 | 軽量で推論が速い |
| 最高精度 | EfficientNet-B7 | リソースに余裕がある場合 |
まとめ
- AlexNet が深層学習ブームの起点、VGG がシンプルな深層化の有効性を示した
- ResNet の残差接続は超深層ネットワークの学習を可能にした革命的発明
- EfficientNet は複合スケーリングで効率的な精度向上を実現
- 実務ではタスク要件に応じたアーキテクチャ選択が重要
チェックリスト
- AlexNet、VGG、ResNet の主な特徴を説明できる
- 残差接続(Skip Connection)がなぜ有効か理解した
- 残差ブロックを PyTorch で実装できる
- タスクに応じたアーキテクチャの選び方を理解した
推定読了時間: 30分