フィルタ / カーネル(CNN) ふぃるた / かーねる(しーえぬえぬ)
フィルタカーネルCNN畳み込み特徴検出パラメータ共有
フィルタ / カーネル(CNN)について教えて
簡単に言うとこんな感じ!
CNNのフィルタ(カーネル)は「特定のパターンを探す虫眼鏡」みたいなものだよ。3×3の小さな行列が画像全体をスライドしながら「この辺にエッジがあるか?」と確認していく。フィルタの重みはランダムから始まり、学習で「何を検出すべきか」を自動で学ぶんだ!
フィルタ / カーネルとは
フィルタ(Filter) またはカーネル(Kernel) は、CNNの畳み込み層に含まれる小さな重み行列です。入力画像や特徴マップの局所領域(受容野)との内積を計算することで、その領域における特定の特徴の強さを検出します。
フィルタは学習によって最適化されます。初期値はランダムですが、バックプロパゲーションを通じて「損失が小さくなるような特徴を検出するフィルタ」に更新されます。結果として、人間が意図しなくてもエッジ検出・ブラー・シャープネスなどに対応するフィルタが自然と学習されます。
CNNでは同じフィルタを入力全体にスライドさせるパラメータ共有を行います。これにより、3×3フィルタは画像のどの位置に同じパターンが現れても検出でき、かつパラメータ数を大幅に削減できます。
フィルタの例
# エッジ検出フィルタの例(手作りの古典的フィルタ)
Sobel(縦エッジ検出): Laplacian(全方向エッジ):
[-1 0 1] [0 -1 0]
[-2 0 2] [-1 4 -1]
[-1 0 1] [0 -1 0]
# CNNではこれらを人間が設計するのではなく、
# 学習によって自動的に最適なフィルタが決まる
import torch.nn as nn
# 1つの畳み込み層は「out_channels個」のフィルタを持つ
conv = nn.Conv2d(
in_channels=3, # 入力チャンネル(RGB=3)
out_channels=64, # フィルタの枚数
kernel_size=3 # 各フィルタのサイズ(3×3)
)
# フィルタの形状: (64個, 3チャンネル, 3×3) = 1,728パラメータ
print(conv.weight.shape) # → torch.Size([64, 3, 3, 3])
歴史と背景
- 1960〜70年代:画像処理でSobel・Prewittなどの手作りフィルタが使われる
- 1989年:LeCunのLeNetでフィルタの重みを学習で決める手法を提案
- 2012年:AlexNetでAlexeyらが多数のフィルタを重ねた深いCNNの有効性を実証
- 現在:深層学習のフィルタは完全に学習で決まり、人間には解釈しにくい抽象的な特徴を学習している
フィルタサイズの選択
| フィルタサイズ | 受容野の広さ | 主な用途 |
|---|---|---|
| 1×1 | なし(チャンネル変換のみ) | 次元削減、非線形性追加 |
| 3×3 | 局所(最もよく使われる) | 一般的な特徴検出 |
| 5×5 | やや広い | 初期のCNN。現在は3×3を2回重ねる方が多い |
| 7×7 | 広い | 最初の層でのみ使うことがある(ResNetなど) |
| 深さ方向(Depthwise) | チャンネルごと | MobileNetの軽量化 |
関連用語
- 畳み込み層 — フィルタを内包する層
- 特徴マップ — フィルタを適用して得られる出力
- ストライド / パディング — フィルタのスライド方法を制御
- MobileNet — 軽量フィルタ(Depthwise Conv)を使うモデル