Feature Maps
特徴マップは、フィルターが画像全体に生成する応答のグリッドであり、フィルターのパターンが現れる位置を示します。計算方法、形状、可視化について解説します。
特徴マップは、畳み込みニューラルネットワーク(CNN)の層にある1つのフィルターの出力です。入力の各位置でフィルターのパターンがどれだけ強く現れるかを記録した、数値の2Dグリッドです。64個のフィルターを持つ畳み込み層は64個の特徴マップを生成し、それらをチャネル数 × 高さ × 幅の形状を持つテンソルにまとめます。このテンソルが次の層の入力になります。初期層の特徴マップはエッジ、色、テクスチャを強調し、深い層のマップは物体の部位や物体全体に反応します。「活性化マップ」も同義語です。また、層のマップ全体をまとめたテンソルも、特徴マップと呼ばれることがよくあります。
特徴マップの計算方法#
カーネルとも呼ばれるフィルターは、通常は入力チャネルごとに3×3の小さなグリッドで、学習済みのモデル重みを保持します。畳み込みではフィルターを入力上でスライドさせ、各位置で重なった値を要素ごとに乗算して合計し、バイアスを加えて1つの出力値を得ます。出力値が大きい場所は、入力がフィルターのパターンと一致することを示します。出力の高さと幅は、入力サイズ、カーネルサイズk、パディングp、ストライドsからfloor((input + 2p - k) / s) + 1で求められます。そのため、パディング1の3×3カーネルはストライド1ではサイズを維持し、ストライド2ではサイズを半分にします。
以下のコードは、左側が暗く右側が明るい小さな画像に垂直エッジカーネルを適用します。
import torch
import torch.nn.functional as F
# 8x8のグレースケール画像:左半分が暗く右半分が明るいため、垂直エッジが1つあります
image = torch.zeros(1, 1, 8, 8)
image[..., 4:] = 1.0
# 垂直エッジに反応する3x3のSobelカーネル
kernel = torch.tensor([[-1.0, 0.0, 1.0], [-2.0, 0.0, 2.0], [-1.0, 0.0, 1.0]]).view(1, 1, 3, 3)
# カーネルを画像上でスライドさせて特徴マップを生成します
feature_map = F.conv2d(image, kernel)
print(feature_map.shape)
print(feature_map[0, 0, 0])torch.Size([1, 1, 6, 6])とtensor([0., 0., 4., 4., 0., 0.])が出力されます。パディングがない場合、8×8の画像から6×6のマップが得られます(8 − 3 + 1 = 6)。値が0以外になるのは、カーネルがエッジにまたがる2列だけです。学習済みCNNは、色やテクスチャに合わせたフィルターとともに、このようなSobelカーネルに似た第1層のフィルターを多数学習します。
ネットワーク内の特徴マップ#
データがCNN内を進むにつれて、特徴マップは通常、高さと幅が小さくなり、チャネル数が増えます。ダウンサンプリングのたびに解像度は半分になり、深いマップの各位置は元画像のより広い受容野を要約します。検出器は複数の深さのマップを保持します。トレードオフには両面があるためです。640×640の画像に対するストライド8のマップは80×80のグリッドで、小さな物体の位置を特定できるだけの細かさがあります。一方、ストライド32のマップは20×20のグリッドで、各セルが大きな物体を認識できる範囲の画像を捉えます。特徴ピラミッドネットワーク(FPN)は異なる深さのマップを統合し、すべてのスケールで正確な位置情報と高レベルの意味情報を得られるようにします。マップを生成するバックボーンは、モデルの主要な特徴抽出段階です。
特徴マップと関連用語の比較#
- フィルター:フィルターは学習済みの重みを保持し、特徴マップはそれを1つの入力に適用した結果です。1つのフィルターは画像ごとに1つの特徴マップを生成します。
- 活性化関数:畳み込みの後に特徴マップの各要素へ適用する、ReLUなどの関数です。マップは活性化の前後に存在し、それぞれ活性化前の値、活性化後の値と呼ばれます。
- 埋め込み表現:埋め込み表現は通常、特徴マップをプーリングまたは平坦化して作成する1Dベクトルです。画像に何が含まれているかを保持し、位置情報を捨てます。埋め込み表現は類似検索やクラスタリングに使われ、空間的な特徴マップはセマンティックセグメンテーションなど、位置情報を必要とするタスクに使われます。
- 顕著性マップ: 顕著性マップは、1つの予測を説明する単一のヒートマップで、多くの場合、特徴マップとその勾配から計算されます。
特徴マップの確認と可視化#
個々のチャネルをグレースケール画像としてプロットすると、各フィルターが何に反応するかがわかります。第1層のマップは、写真をエッジ検出したような画像に見え、深い層のマップは、物体の各部分に重なる粗い塊状になります。PyTorchでは、register_forward_hookで登録したforward hookにより、推論中に任意の層の特徴マップを取得できます。深い層には数百のチャネルがあるため、説明可能なAIツールは通常、それらを1つのヒートマップに集約します。Grad-CAMは、後段の特徴マップの各チャネルにクラススコアの平均勾配で重み付けしてチャネルを合計し、予測の根拠となった画像領域を強調表示します。nano版YOLO26モデルでは、640×640の画像は64×80×80、128×40×40、256×20×20の3つの特徴マップとして検出ヘッドに到達し、visualize=Trueでの予測では、各予測クラスに対する正の勾配で各マップのすべての位置に重み付けする_cam.jpg LayerCAMオーバーレイが保存されます。










