STEP 16:CNNの基礎

🖼️ STEP 16: CNNの基礎

画像認識の革命!畳み込みニューラルネットワークを理解しよう

📋 このステップで学ぶこと

  • CNNとは何か?なぜ画像認識に強いのか?
  • 全結合層(MLP)の問題点
  • 畳み込み(Convolution)の仕組み
  • フィルター(カーネル)の役割
  • ストライドとパディング
  • 特徴マップの理解

🖼️ 1. CNNとは何か?

1-1. CNNの定義

CNN(Convolutional Neural Network、畳み込みニューラルネットワーク)は、画像認識に特化したニューラルネットワークです。

💡 CNNの革命的な成果
  • 2012年 AlexNet:画像認識コンペ(ImageNet)で圧倒的勝利
  • 2015年 ResNet:人間を超える画像認識精度を達成
  • 現在:自動運転、医療画像診断、顔認識など幅広く活用

1-2. CNNが使われている例

📱 身近なCNNの活用例
  • スマホの顔認証:顔の特徴を認識してロック解除
  • Google フォト:自動で人物や場所を分類
  • 自動運転:歩行者、信号、標識を認識
  • 医療診断:レントゲン画像からがんを検出
  • OCR:手書き文字をテキストに変換

😰 2. 全結合層(MLP)の問題点

2-1. 画像を全結合層で処理すると?

STEP 8で作ったMNISTの手書き数字認識を思い出してください。
28×28ピクセルの画像をFlattenで784次元に変換して、全結合層で処理しました。

⚠️ 全結合層の問題点
  • パラメータが多すぎる:224×224×3の画像 → 約15万次元 → パラメータ爆発
  • 位置情報の喪失:画像を1次元に変換すると、「どこに何があるか」が失われる
  • 位置の変化に弱い:猫が左にいても右にいても「同じ猫」と認識できない

2-2. パラメータ数の比較

【パラメータ数の比較:224×224×3 の画像の場合】 ■ 全結合層(MLP)の場合: 入力:224 × 224 × 3 = 150,528 次元 最初の隠れ層(512ユニット)への接続: 150,528 × 512 = 77,070,336 パラメータ(約7700万!) ■ 畳み込み層(CNN)の場合: 3×3 フィルター、32枚の場合: 3 × 3 × 3 × 32 = 864 パラメータ(約900!) → CNNは約89,000分の1のパラメータで済む!

2-3. 位置不変性の問題

以下の図は横スクロールできます。

【全結合層の問題:位置が変わると認識できない】 ■ 学習時の猫の画像 ■ テスト時の猫の画像 ┌─────────────────┐ ┌─────────────────┐ │ │ │ │ │ 🐱 │ │ 🐱 │ │ │ │ │ └─────────────────┘ └─────────────────┘ 左にいる猫 右にいる猫 全結合層は「位置」も含めて学習するため、 同じ猫でも位置が変わると別物と認識してしまう! CNNは「どこにあっても同じ特徴」を学習できる → これを「位置不変性」という

🔍 3. 畳み込み(Convolution)とは?

3-1. 畳み込みの基本アイデア

畳み込み(Convolution)とは、小さなフィルター(カーネル)を画像上でスライドさせながら、局所的な特徴を抽出する操作です。

🔎 虫眼鏡の例え

畳み込みは「虫眼鏡で画像を少しずつ見ていく」イメージです。

虫眼鏡(フィルター)を画像の左上から右下まで動かしながら、
「この部分にはエッジがある」「この部分は滑らか」といった
局所的な特徴を見つけていきます。

3-2. 畳み込みの計算

以下の図は横スクロールできます。

【畳み込みの計算例】 入力画像(5×5) フィルター(3×3) ┌───┬───┬───┬───┬───┐ ┌───┬───┬───┐ │ 1 │ 2 │ 3 │ 0 │ 1 │ │ 1 │ 0 │-1 │ ├───┼───┼───┼───┼───┤ ├───┼───┼───┤ │ 0 │ 1 │ 2 │ 3 │ 0 │ │ 1 │ 0 │-1 │ ├───┼───┼───┼───┼───┤ ├───┼───┼───┤ │ 1 │ 2 │ 1 │ 0 │ 1 │ │ 1 │ 0 │-1 │ ├───┼───┼───┼───┼───┤ └───┴───┴───┘ │ 0 │ 1 │ 2 │ 1 │ 0 │ ├───┼───┼───┼───┼───┤ │ 1 │ 0 │ 1 │ 2 │ 1 │ └───┴───┴───┴───┴───┘ 【計算方法】 1. フィルターを画像の左上に置く 2. 対応する要素同士を掛けて、すべて足す 3. フィルターを1ピクセル右にずらして繰り返す 4. 右端まで行ったら1ピクセル下にずらして繰り返す 【左上の計算】 (1×1) + (2×0) + (3×-1) + (0×1) + (1×0) + (2×-1) + (1×1) + (2×0) + (1×-1) = 1 + 0 – 3 + 0 + 0 – 2 + 1 + 0 – 1 = -4

3-3. 特徴マップ

✅ 特徴マップ(Feature Map)とは?

畳み込みの結果として得られる出力を特徴マップと呼びます。

フィルターが検出する特徴(エッジ、模様など)がどこにあるかを示すマップです。

【畳み込みの結果】 入力画像(5×5) + フィルター(3×3) → 特徴マップ(3×3) 出力サイズの計算: (入力サイズ – フィルターサイズ) + 1 = 出力サイズ (5 – 3) + 1 = 3 5×5の画像に3×3のフィルターをかけると、3×3の特徴マップができる

🎨 4. フィルター(カーネル)の役割

4-1. フィルターは何を検出する?

フィルターの値によって、検出する特徴が変わります。
CNNでは、フィルターの値は学習によって自動的に決まります

【代表的なフィルターの例】 ■ 縦エッジ検出フィルター ■ 横エッジ検出フィルター ┌────┬────┬────┐ ┌────┬────┬────┐ │ -1 │ 0 │ 1 │ │ -1 │ -1 │ -1 │ ├────┼────┼────┤ ├────┼────┼────┤ │ -1 │ 0 │ 1 │ │ 0 │ 0 │ 0 │ ├────┼────┼────┤ ├────┼────┼────┤ │ -1 │ 0 │ 1 │ │ 1 │ 1 │ 1 │ └────┴────┴────┘ └────┴────┴────┘ 左右の色の差を検出 上下の色の差を検出 ■ ぼかしフィルター ■ シャープ化フィルター ┌─────┬─────┬─────┐ ┌────┬────┬────┐ │ 1/9 │ 1/9 │ 1/9 │ │ 0 │ -1 │ 0 │ ├─────┼─────┼─────┤ ├────┼────┼────┤ │ 1/9 │ 1/9 │ 1/9 │ │ -1 │ 5 │ -1 │ ├─────┼─────┼─────┤ ├────┼────┼────┤ │ 1/9 │ 1/9 │ 1/9 │ │ 0 │ -1 │ 0 │ └─────┴─────┴─────┘ └────┴────┴────┘ 周囲の平均を取る 輪郭を強調する

4-2. 複数のフィルター

CNNでは、複数のフィルターを使って、様々な特徴を同時に検出します。

【複数フィルターによる特徴抽出】 入力画像(28×28×1) ↓ 32個のフィルター(3×3)を適用 ↓ 32枚の特徴マップ(26×26×32) 各フィルターが異なる特徴を検出: ・フィルター1: 縦のエッジ ・フィルター2: 横のエッジ ・フィルター3: 斜めのエッジ ・フィルター4: 角 … → 多様な特徴を同時に抽出できる!

4-3. 階層的な特徴学習

📌 CNNの階層的な特徴学習

浅い層:エッジ、色、テクスチャなど低レベルな特徴
中間層:目、耳、車輪などパーツレベルの特徴
深い層:顔、車、建物など高レベルな特徴

層が深くなるほど、抽象的な特徴を学習します。

⚙️ 5. ストライドとパディング

5-1. ストライド(Stride)

ストライドは、フィルターを動かす歩幅です。

【ストライドの違い】 ■ ストライド = 1(デフォルト) フィルターを1ピクセルずつ動かす 入力 5×5、フィルター 3×3 → 出力 3×3 ■ ストライド = 2 フィルターを2ピクセルずつ動かす 入力 5×5、フィルター 3×3 → 出力 2×2 ストライドを大きくすると: ・出力サイズが小さくなる ・計算量が減る ・情報が失われる可能性がある

5-2. パディング(Padding)

パディングは、入力画像の周囲にピクセルを追加する操作です。

【パディングの効果】 ■ パディングなし(valid) 入力 5×5、フィルター 3×3 → 出力 3×3 → 出力サイズが小さくなる ■ パディングあり(same) 入力の周囲に0を1ピクセル追加 入力 5×5 → 7×7(パディング後) フィルター 3×3 → 出力 5×5 → 出力サイズが入力と同じ! ┌───┬───┬───┬───┬───┬───┬───┐ │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ ← 追加された0 ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 1 │ 2 │ 3 │ 0 │ 1 │ 0 │ ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 0 │ 1 │ 2 │ 3 │ 0 │ 0 │ 元の画像 ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 1 │ 2 │ 1 │ 0 │ 1 │ 0 │ ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 0 │ 1 │ 2 │ 1 │ 0 │ 0 │ ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 1 │ 0 │ 1 │ 2 │ 1 │ 0 │ ├───┼───┼───┼───┼───┼───┼───┤ │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ 0 │ ← 追加された0 └───┴───┴───┴───┴───┴───┴───┘

5-3. 出力サイズの計算式

📐 出力サイズの計算式

出力サイズ = (入力サイズ – フィルターサイズ + 2×パディング) / ストライド + 1

例:入力28×28、フィルター3×3、パディング1、ストライド1
(28 – 3 + 2×1) / 1 + 1 = 28
→ 出力も28×28(same padding)

💻 6. Kerasでの実装

6-1. Conv2Dレイヤー

📝 Conv2Dのパラメータ
  • filters:フィルターの数(出力チャンネル数)
  • kernel_size:フィルターのサイズ(例:(3, 3))
  • strides:ストライド(デフォルト (1, 1))
  • padding:‘valid’ or ‘same’
  • activation:活性化関数
from tensorflow.keras.layers import Conv2D # 基本的なConv2Dレイヤー Conv2D( filters=32, # 32個のフィルター kernel_size=(3, 3), # 3×3のフィルター strides=(1, 1), # ストライド1 padding=’same’, # 出力サイズを入力と同じに activation=’relu’ # ReLU活性化関数 )

6-2. シンプルなCNNモデル

from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv2D, Flatten, Dense from tensorflow.keras.datasets import mnist from tensorflow.keras.utils import to_categorical # データ準備(CNNは4次元入力が必要) (X_train, y_train), (X_test, y_test) = mnist.load_data() X_train = X_train.reshape(-1, 28, 28, 1) / 255.0 # (サンプル数, 高さ, 幅, チャンネル) X_test = X_test.reshape(-1, 28, 28, 1) / 255.0 y_train = to_categorical(y_train) y_test = to_categorical(y_test) # シンプルなCNNモデル model = Sequential([ # 畳み込み層 Conv2D(32, (3, 3), padding=’same’, activation=’relu’, input_shape=(28, 28, 1)), Conv2D(64, (3, 3), padding=’same’, activation=’relu’), # 全結合層につなげる Flatten(), Dense(128, activation=’relu’), Dense(10, activation=’softmax’) ]) model.summary()
実行結果:
Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 conv2d (Conv2D)             (None, 28, 28, 32)        320       
 conv2d_1 (Conv2D)           (None, 28, 28, 64)        18496     
 flatten (Flatten)           (None, 50176)             0         
 dense (Dense)               (None, 128)               6422656   
 dense_1 (Dense)             (None, 10)                1290      
=================================================================
Total params: 6,442,762

※ Flattenの後のDenseでパラメータが多くなる
→ 次のSTEPで学ぶプーリング層で解決!

📝 STEP 16 のまとめ

✅ このステップで学んだこと
  • CNN:画像認識に特化したニューラルネットワーク
  • 全結合層の問題:パラメータ爆発、位置情報の喪失
  • 畳み込み:フィルターをスライドさせて局所的な特徴を抽出
  • フィルター:エッジ、模様などの特徴を検出(学習で自動決定)
  • ストライド:フィルターを動かす歩幅
  • パディング:入力の周囲にピクセルを追加して出力サイズを調整
  • 特徴マップ:畳み込みの結果、特徴の位置を示すマップ
💡 覚えておくべきコード
# 畳み込み層の基本 Conv2D(32, (3, 3), padding=’same’, activation=’relu’) # 入力形状(画像の場合) input_shape=(高さ, 幅, チャンネル数) # 例:グレースケール28×28 → (28, 28, 1) # 例:カラー224×224 → (224, 224, 3)
🚀 次のステップへ

畳み込み層を理解したので、次のSTEP 17ではプーリング層を学びます。

特徴マップを縮小して、パラメータ数を減らしながら重要な特徴を保持する方法です!

📝 練習問題

問題1 やさしい

CNNの利点

全結合層(MLP)と比較したCNNの利点として、正しくないものを選んでください。

  • A. パラメータ数が少ない
  • B. 位置不変性がある
  • C. 必ず100%の精度が出る
  • D. 局所的な特徴を抽出できる
正解:C

CNNは優れた手法ですが、100%の精度を保証するものではありません。A、B、Dは正しいCNNの利点です。

問題2 やさしい

畳み込みの計算

入力画像が7×7、フィルターが3×3、パディングなし、ストライド1の場合、出力サイズはいくつになりますか?

  • A. 3×3
  • B. 5×5
  • C. 7×7
  • D. 9×9
正解:B
出力サイズ = (入力 – フィルター) / ストライド + 1 = (7 – 3) / 1 + 1 = 4 + 1 = 5
問題3 ふつう

パディングの効果

padding=’same’ を使う主な理由として、正しいものを選んでください。

  • A. 計算速度を上げるため
  • B. 出力サイズを入力と同じに保つため
  • C. フィルター数を増やすため
  • D. 活性化関数を適用するため
正解:B

padding=’same’は入力の周囲にパディングを追加し、出力サイズを入力と同じに保ちます。これにより、深いネットワークでも特徴マップのサイズを制御しやすくなります。

問題4 ふつう

フィルターの学習

CNNのフィルター(カーネル)の値について、正しい説明を選んでください。

  • A. プログラマーが手動で設定する
  • B. 常にランダムな値を使う
  • C. 学習によって自動的に決まる
  • D. 画像のサイズによって固定される
正解:C

CNNのフィルターの値は、訓練データを使った学習によって自動的に最適化されます。初期値はランダムですが、逆伝播によって更新されていきます。

問題5 むずかしい

出力サイズの計算

入力32×32、フィルター5×5、パディング2、ストライド2の場合、出力サイズはいくつになりますか?

  • A. 14×14
  • B. 15×15
  • C. 16×16
  • D. 17×17
正解:C
出力サイズ = (入力 – フィルター + 2×パディング) / ストライド + 1 = (32 – 5 + 2×2) / 2 + 1 = (32 – 5 + 4) / 2 + 1 = 31 / 2 + 1 = 15.5 + 1 = 16(小数点以下切り捨て + 1)
📝

学習メモ

ディープラーニング基礎 - Step 16

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE