CNNとは?畳み込みニューラルネットワークを図解
畳み込みニューラルネットワーク(CNN)の仕組みを初心者向けに直感的に図解。フィルタ走査、プーリング、学習の仕組みまでわかりやすく解説します。
TL;DR: CNN(Convolutional Neural Network、畳み込みニューラルネットワーク)は、コンピュータにとっての「視覚専用の脳」のようなものです。画像全体を一度に見るのではなく、小さな「虫眼鏡」で局所的な領域をスキャンし 直線や角などの単純な特徴を見つけ それらを組み合わせて形を作り 最終的に「猫 🐱」「犬 🐶」「車 🚗」を判別します。
1. CNNが「猫」を認識するプロセス 🐱#
コンピュータに猫を見分ける方法を教える場面を想像してみてください。何千枚もの画像を与えます:
🐱 🐱 🐱 🐱 🐱 (画像1 -> 猫, 画像2 -> 猫)
🐶 🐶 🐶 🐶 (画像3 -> 犬)
🚗 🚗 🚗 (画像4 -> 車)text最初のうちは、コンピュータは「猫とは何か」を全く知りません。耳が尖っていることも、ヒゲがあることも知りません。すべてをゼロから自己学習する必要があります。
では、コンピュータは画像をどのように「見て」いるのでしょうか?
2. コンピュータから見た画像の世界#
人間の目には鮮やかな景色に見える画像も、コンピュータにとっては単なる巨大な数値の表(ピクセル行列)に過ぎません。
5x5のグレースケール画像の例:
0 0 0 0 0
0 255 255 0 0
0 255 255 0 0
0 0 0 0 0
0 0 0 0 0text0は完全な黒を表します。255は完全な白を表します。- 中間の値(
1〜254)はさまざまな濃淡のグレーを表します。
カラー画像の場合、各ピクセルは RGB(赤・緑・青) の3つの数値を持ちます:
(255, 0, 0)鮮やかな赤(0, 255, 0)鮮やかな緑(0, 0, 255)鮮やかな青
[!NOTE] コンピュータにとって、 の画像は芸術作品ではなく、縦横に並んだ600万個以上の数字の塊です。
3. 虫眼鏡で画像を見る(畳み込みとフィルタ)#
何百万ものピクセル値をそのまま従来の全結合ニューラルネットワークに入力すると、パラメータ数が膨大になり、隣り合うピクセル同士の位置関係(空間情報)が失われてしまいます。
CNNはこの問題をフィルタ(Kernel)と呼ばれる小さな虫眼鏡を使って解決します:
元の画像 (5x5): 虫眼鏡フィルタ (3x3):
⬜ ⬜ ⬜ ⬜ ⬜ ┌───────────┐
⬜ ⬛ ⬛ ⬜ ⬜ │ ⬜ ⬜ ⬜ │
⬜ ⬜ ⬜ ⬜ ⬜ │ ⬜ ⬛ ⬛ │ (少しずつスライド)
⬜ ⬜ ⬜ ⬜ ⬜ │ ⬜ ⬜ ⬜ │
⬜ ⬜ ⬜ ⬜ ⬜ └───────────┘textこのフィルタを画像の上で左から右、上から下へと一定間隔で滑らせながら計算していきます:
このスライドしながら数値を掛け合わせる処理を「畳み込み(Convolution)」と呼びます。これがCNNの「C」の由来です。
4. フィルタは専門の「探偵チーム」 🕵️#
それぞれのフィルタは、特定の特徴を見つける専門家です:
- 探偵A: 「私は垂直な直線
|を探す専門です」 - 探偵B: 「私は水平な直線
-を探す専門です」 - 探偵C: 「私は斜めの線
/や\を探します」 - 探偵D: 「私は尖った角
Lを探します」
フィルタが担当する特徴と一致する場所に差し掛かると、高い数値を出力します。画像全体をスキャンして得られる新しいマップを特徴マップ(Feature Map)と呼びます:
垂直な直線が見つかった場合:
0 0 1 0
0 0 1 0
0 0 1 0 --> 「ここに縦の直線があるぞ!」text[!TIP] ディープラーニングの最も素晴らしい点は、人間がフィルタの数値を手作業でプログラムする必要がないことです。CNNはデータから最適なフィルタの数値を自動的に学習します!
5. 多層アーキテクチャ(Deep Layers):部品から全体へ#
なぜこれがDeep(深層)と呼ばれるのでしょうか?それは、複数の層(レイヤー)を積み重ねて、単純な概念から複雑な概念へと段階的に組み立てていくからです:
flowchart TD
A["入力画像(ピクセル行列)"] --> B["第1層: エッジ、直線、角、基本色"]
B --> C["第2層: 図形(丸、四角、テクスチャ)"]
C --> D["第3層: 部品(目 + 耳 + 鼻 + ヒゲ)"]
D --> E["第4層: 顔や体の輪郭"]
E --> F["最終判定: 猫 🐱 (確率 95%)"]
- 初期の層: 基本的なエッジや線(
|,-,/, 角など)を検出。 - 中間の層: 線を組み合わせて目や耳などの図形パターンを構築。
- 深い層: パーツを組み合わせて顔全体の構造を認識。
- 出力層(全結合層): すべてのパーツを統合して「これは猫である」と結論づけます。
6. 情報を要約するプーリング(Max Pooling)#
画像には冗長な情報が多く含まれています。重要な特徴を保ちながら計算量を削減するために、特徴マップのサイズを縮小するプーリング(Pooling)という処理を行います。
最も一般的なMax Poolingは、領域ごとに最大の数値だけを残します:
元の 4x4 行列: Max Pooling (2x2 領域):
1 2 | 3 4 ┌─────────┬─────────┐
5 9 | 2 1 │ 9 │ 4 │
-------+------- ======> ├─────────┼─────────┤
4 3 | 8 2 │ 4 │ 8 │
1 2 | 1 7 └─────────┴─────────┘textMax Poolingは、大きな絵画を見た後に「最も際立っている特徴だけをメモに残す」ような感覚です。
7. 間違いから学ぶ仕組み(Lossと勾配降下法)#
初期状態のCNNのフィルタにはランダムな数値が入っています。そのため、猫の画像 🐱 を見せても:
- 猫:
- 犬:
- 車:
このように大外れな予測をしてしまいます。この時、正解とのズレの大きさを測る指標が損失(Loss)です。
学習のプロセスはアーチェリーの練習に似ています:
- 1射目: 的から大きく外れる(Lossが大きい)。
- ズレの確認: 上下にどれくらい外れたかを計測。
- フォーム調整(誤差逆伝播法 & 勾配降下法): 弓を構える角度を微調整。
- 2射目: 的の中心にぐっと近づく!
山の頂上(Loss = 10)
🧍
/ \
/ \ -> 最も急な下り坂の方向へ進む
/ \
/ \___
↓
谷底(Loss = 0.01 -> 正解率99%)text8. PyTorchによるシンプルなCNNの実装例#
PyTorchを使った標準的なCNNのコード例です:
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
# 第1層: 1チャンネル入力(グレースケール)、16枚の3x3フィルタ
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, padding=1)
# 第2層: 16チャンネル入力、32枚の3x3フィルタ
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, padding=1)
# 画像サイズを半分に圧縮するMax Pooling
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# 10クラス分類のための全結合層
self.fc1 = nn.Linear(32 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
# 画像 -> Conv1 -> ReLU -> Pool
x = self.pool(F.relu(self.conv1(x)))
# -> Conv2 -> ReLU -> Pool
x = self.pool(F.relu(self.conv2(x)))
# 1次元ベクトルに平坦化(Flatten)
x = x.view(-1, 32 * 7 * 7)
# 全結合層 -> 分類出力
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
# モデルのインスタンス化
model = SimpleCNN()
print(model)python9. まとめ:CNNを覚えるための6つの重要キーワード#
CNNの全体像を30秒でおさらいすると、以下の6つのステップになります:
1. 画像(IMAGE) ピクセル数値の行列データ
↓
2. 畳み込み(CONVOLUTION) 虫眼鏡フィルタによるスキャン
↓
3. 特徴マップ(FEATURE MAP) 検出された特徴の分布図
↓
4. プーリング(POOLING) 重要情報を残してサイズ縮小
↓
5. 多層結合(DEEP LAYERS) エッジ -> パーツ -> 全体へ合成
↓
6. 予測(PREDICTION) 最終的なクラス判定(猫 95%)text[!TIP] 本質的なポイント: 人間がルールを何千行も
if/elseで書くのではなく、CNN自身が膨大なデータから最適な視覚特徴を数学的に自己獲得する点にあります。