PyTorch torch.nn.AdaptiveAvgPool2d 関数
torch.nn.AdaptiveAvgPool2dPyTorch の適応的平均プーリングモジュールです。
任意のサイズの入力特徴マップを指定されたターゲットサイズにプーリングでき、kernel_size と stride を手動で計算する必要がありません。
関数定義
torch.nn.AdaptiveAvgPool2d(output_size)
パラメータの説明:
output_size(int または tuple): 出力サイズ。(H, W) または単一の int(正方形)にすることができます。
使用例
例1: 基本的な使い方
特徴マップを固定サイズにプーリングする:
例
import torch
import torch.nn as nn
# 1x1にプーリング
adaptive_pool = nn.AdaptiveAvgPool2d(1)
# 異なるサイズの入力
x1 = torch.randn(1, 64, 32, 32)
x2 = torch.randn(1, 64, 16, 16)
x3 = torch.randn(1, 64, 8, 8)
out1 = adaptive_pool(x1)
out2 = adaptive_pool(x2)
out3 = adaptive_pool(x3)
print("32x32 ->", out1.shape)
print("16x16 ->", out2.shape)
print("8x8 ->", out3.shape)
print("nすべての出力が1x1にプーリングされます")
import torch.nn as nn
# 1x1にプーリング
adaptive_pool = nn.AdaptiveAvgPool2d(1)
# 異なるサイズの入力
x1 = torch.randn(1, 64, 32, 32)
x2 = torch.randn(1, 64, 16, 16)
x3 = torch.randn(1, 64, 8, 8)
out1 = adaptive_pool(x1)
out2 = adaptive_pool(x2)
out3 = adaptive_pool(x3)
print("32x32 ->", out1.shape)
print("16x16 ->", out2.shape)
print("8x8 ->", out3.shape)
print("nすべての出力が1x1にプーリングされます")
例2: 任意のサイズを出力
非正方形にプーリング:
例
import torch
import torch.nn as nn
# 4x4にプーリング
pool = nn.AdaptiveAvgPool2d((4, 4))
x = torch.randn(2, 128, 32, 32)
out = pool(x)
print("入力形状:", x.shape)
print("出力形状:", out.shape) # (2, 128, 4, 4)
# 1x7にプーリング(シーケンスに使用可能)
pool_seq = nn.AdaptiveAvgPool2d((1, 7))
x_seq = torch.randn(2, 64, 10, 20)
out_seq = pool_seq(x_seq)
print("nシーケンスプーリング:", x_seq.shape, "->", out_seq.shape)
import torch.nn as nn
# 4x4にプーリング
pool = nn.AdaptiveAvgPool2d((4, 4))
x = torch.randn(2, 128, 32, 32)
out = pool(x)
print("入力形状:", x.shape)
print("出力形状:", out.shape) # (2, 128, 4, 4)
# 1x7にプーリング(シーケンスに使用可能)
pool_seq = nn.AdaptiveAvgPool2d((1, 7))
x_seq = torch.randn(2, 64, 10, 20)
out_seq = pool_seq(x_seq)
print("nシーケンスプーリング:", x_seq.shape, "->", out_seq.shape)
例3: CNNでの使用
典型的なグローバル平均プーリング:
例
import torch
import torch.nn as nn
class CNNWithGAP(nn.Module):
def __init__(self, num_classes=10):
super(CNNWithGAP, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
)
# グローバル平均プーリング
self.avgpool = nn.AdaptiveAvgPool2d(1)
self.classifier = nn.Linear(256, num_classes)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
model = CNNWithGAP()
x = torch.randn(4, 3, 32, 32)
output = model(x)
print("入力形状:", x.shape)
print("出力形状:", output.shape)
print("n特徴マップがグローバルにプーリングされて単一のベクトルになります")
import torch.nn as nn
class CNNWithGAP(nn.Module):
def __init__(self, num_classes=10):
super(CNNWithGAP, self).__init__()
self.features = nn.Sequential(
nn.Conv2d(3, 64, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(64, 128, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
nn.Conv2d(128, 256, 3, padding=1),
nn.ReLU(),
nn.MaxPool2d(2),
)
# グローバル平均プーリング
self.avgpool = nn.AdaptiveAvgPool2d(1)
self.classifier = nn.Linear(256, num_classes)
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
model = CNNWithGAP()
x = torch.randn(4, 3, 32, 32)
output = model(x)
print("入力形状:", x.shape)
print("出力形状:", output.shape)
print("n特徴マップがグローバルにプーリングされて単一のベクトルになります")
例4: 通常のプーリングとの比較
例
import torch
import torch.nn as nn
# 適応的プーリング vs 通常のプーリング
adaptive = nn.AdaptiveAvgPool2d(2)
regular = nn.AvgPool2d(kernel_size=16, stride=16)
x = torch.randn(1, 64, 32, 32)
out_adaptive = adaptive(x)
out_regular = regular(x)
print("入力:", x.shape)
print("適応的プーリング (出力2x2):", out_adaptive.shape)
print("通常の平均プーリング (16x16):", out_regular.shape)
import torch.nn as nn
# 適応的プーリング vs 通常のプーリング
adaptive = nn.AdaptiveAvgPool2d(2)
regular = nn.AvgPool2d(kernel_size=16, stride=16)
x = torch.randn(1, 64, 32, 32)
out_adaptive = adaptive(x)
out_regular = regular(x)
print("入力:", x.shape)
print("適応的プーリング (出力2x2):", out_adaptive.shape)
print("通常の平均プーリング (16x16):", out_regular.shape)
適応的プーリング vs 通常のプーリング
| タイプ | 利点 | 適用シナリオ |
|---|---|---|
| AdaptiveAvgPool | 入力サイズが任意 | 異なるスケールの入力 |
| AvgPool | 計算がより速い | 固定入力サイズ |
よくある質問
Q1: 適応的プーリングはいつ使うべきですか?
入力サイズが固定されていない場合、または固定サイズに統一する必要がある場合です。
Q2: Global Average Poolingとは何ですか?
AdaptiveAvgPool2d(1) は、各特徴マップを単一の値にプーリングします。
使用シナリオ
- 分類ネットワーク: FC層の代わりにグローバル平均プーリング
- マルチスケール入力: 異なるサイズの画像に対応
- 特徴の集約: 重要な情報を抽出
ヒント:グローバル平均プーリングはパラメータ数を大幅に削減できます。
その他の拡張
PyTorch torch.nn リファレンスマニュアル