【深層学習】CNNまとめ（仕組み、ちょっとだけ数式）

こんにちは。画像認識に強みを持つCNN（畳み込みニューラルネットワーク）についてまとめます！

※そもそもの深層学習の仕組みとRNN（再帰型ニューラルネットワーク）についてはこちらの記事でまとめました。良ければご参考くださいm(__)m
[【深層学習】RNN、LSTM、GRUまとめ（仕組み、ちょっとだけ数式）](https://qiita.com/nakamin/items/e96542d4e69feb56bc73)

# アウトライン
1. 多層パーセプトロン
2. CNN（畳み込みニューラルネットワーク）
    - 畳み込み層
    - プーリング層
    - パディング
3. CNNの全体像
4. 参考 

# 1. 多層パーセプトロン
CNN（畳み込みニューラルネットワーク）の中身に入る前に、前提となる**多層パーセプトロンに**ついて簡単に触れます。

<b>多層パーセプトロン（MLP: Multi-Layer Perceptron）</b>は<b>全結合層（fully connected layer）</b>を積み上げたモデルで構成されています。

全結合層とは、**すべての入力ニューロンと出力ニューロンが接続された層**を指します。この構造により、各入力データに対して個別の重みが割り当てられ、全体の特徴を学習できるようになっています。
また、多層パーセプトロンでは<b>非線形活性化関数（例えばReLUやシグモイド関数）</b>が使われており、この活性化関数によって非線形な関係を学習することが可能になります。

例えば、画像分類タスクでよく使われるMNISTデータセット（28×28の手書き数字画像）を処理する際、多層パーセプトロンでは次の手順を踏みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/40d9f0f7-52c6-b42c-b817-586784c63fa5.png)

1. **画像データを1次元配列に変換**
28×28ピクセルの画像データを784次元のベクトルに変換して入力
2. **重みを持つ全結合層を通過**
全結合層を複数積み重ね、画像の特徴を学習
3. **出力層で分類**
最終的に、10クラス（数字0～9）に分類する確率値を出力

## 多層パーセプトロンの課題
全結合層では、入力データの位置関係や隣接するピクセルの関連性を考慮するのが難しいことが課題になります。このため、画像のように2次元構造が重要なデータを扱う場合、<b>CNN（畳み込みニューラルネットワーク）</b>の方が適しています。なぜ難しいのかを深掘っていきます！

### 1. **データの構造を破壊する**
全結合層に入力するためには、2次元の画像データ（例: 28×28のピクセル行列）を1次元の配列（例: 長さ784のベクトル）に変換する必要があります。
この変換により、隣接するピクセル間の空間的な情報（例えば、上下左右の関係）が失われることになります。

例えば、次のような28×28の画像の中で隣り合ったピクセルが持つ意味は、ベクトルに変換された段階で完全に無視されてしまします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/4c39bd16-9da0-8a8d-7aa5-c9df55ab89aa.png)

1. **元の画像**
ピクセルAと𝐵が上下に隣接している。
2. **変換後のベクトル**
𝐴は配列の先頭、Bは配列の中のどこかに位置し、隣接しているかどうかの情報が失われる。これにより、画像中の局所的な特徴を捉えるのが難しくなる。

### 2. **位置の変化に弱い**
全結合層では、入力データが持つ順序に基づいて重みが設定されるため、少しでも位置がずれた場合に、出力に大きな影響があります。

例えば、「手書きの "0"」の画像が、画像全体で1ピクセルだけ右にずれた場合を考えてみましょう。このずれにより入力ベクトルの要素が変化し、全結合層の計算結果が大きく異なってしまいます。
これは、全結合層が画像のピクセルの**絶対位置**に依存しているためです。実際の画像認識では、文字や物体の位置は多少ずれても同じカテゴリとして認識されるべきでありますが、全結合層のみではこの柔軟性が実現できません。

### 3. **パラメータ数の爆発**
全結合層では、入力データの次元ごとに重みが必要です。例えば、28×28ピクセルの画像を扱う場合、1層あたり784個の入力に対して、次の層の各ニューロンごとに784個の重みが必要です。
このパラメータ数の膨大さは、計算リソースや学習効率の面で大きな問題となります。

## 余談
ちなみに、CNNのアイデアは、生物の脳、特に**視覚野**の仕組みから着想を得ています。視覚野には、視覚情報を処理するための神経細胞が存在し、その中でも重要なのが次の2種類の細胞です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/da7c9acf-2c42-5b89-883b-271b6d60ad6a.png)

1. **単純型細胞**
単純型細胞は、視覚野の中で**局所的な特徴**を検出する役割を持ちます。例えば、画像の中の縦線や横線、斜め線といった基本的なパターンを見つけられます。
ただし、この細胞には弱点があり、検出した特徴がどの位置にあるかに非常に敏感です。たとえば、縦線を検出しても、その位置が少しでもずれると別の特徴として認識してしまいます。
2. **複雑型細胞**
複雑型細胞は、単純型細胞の弱点を補う役割を果たします。この細胞は、特徴の位置が多少ずれても、同じ特徴として認識することができます。
これにより、画像の中で同じ縦線や横線が少し移動しても、一貫して同じ特徴として捉えることができます。

CNNでは、これらの仕組みを模倣しており、単純型細胞に該当するのが**畳み込み層**、複雑型細胞に該当するのが**プーリング層**です。
つまり、**単純型細胞が局所的な特徴を抽出し、複雑型細胞が移動不変性（特徴の位置に左右されない性質）を付加**することで、画像認識の精度を高めています。
これらを今から説明していきます！

# 2. CNN（畳み込みニューラルネットワーク）
CNNを理解するポイントは、<b>「元の2次元空間の情報を取り込めない」</b>という先ほど挙げた問題に対して、<b>「畳み込み層」</b>を利用していることです。
![sentaku_tatamu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/41a7b6ef-ef4d-d68b-6184-95c3a431983e.png)

## 畳み込み層
畳み込み層は、視覚野の例において単純型細胞に該当します。つまり、**局所的な特徴量の抽出**を担っています。どのように特徴抽出をするかを見ていきましょう。

### フィルター
畳み込み層では、<b>フィルター（カーネルとも言う）</b>を多数用いて、画像（2次元空間の情報を持つ）の特徴抽出を行っています。
ここでは、28×28で784次元のベクトルと持つ手書き文字データを例に考えてみます。

例えば、3×3のフィルターは次のように表されます。
![スクリーンショット 2025-01-07 232623.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/507f37ea-1a61-4864-8518-54fa0e9ef453.png)

このフィルターは、画像に対して特定の演算を加えることで画像を加工する働きをします。
※ 0と1が書いてありますが、これは、上下方向のエッジ（色の境界のうち上下に走る線）を検出するフィルターを表したかったので、1が縦で並ぶフィルターにしました

次に、このフィルターを画像の左隅に合わせて、画像の値をフィルターの積の和を求め、元の画像の中心に書き込みます。この作業をフィルターを<b>スライド</b>させながら画像全体に対して行っていきます。これを**畳み込み演算**と呼びます。
フィルターを適用した結果、エッジが強く出ている領域の数値が高くなっていきます。

なお、今は意図的に縦エッジを認識するフィルターとしましたが、そもそもフィルターに使われる値は重みとしてランダムな値が設定されます。なので、実際には、学習が進むにつれてニューラルネットワーク自身が独自のフィルターを生成することになります。

### 数式
**3×3の畳み込み層**を数式で表すとこのようになります。
なお、フィルターのサイズは中心を決めることができるうように奇数の幅であることが必要です。奇数であればよいので3×3だけでなく、5×5や7×7のサイズにすることもできます。
![スクリーンショット 2025-01-07 232524.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/34dcb9bd-f8b3-1a04-97a1-836d7afcf352.png)

3×3の領域をずらしながら画像全域にわたって出力$Z_{ij}$を計算する層が畳み込み層です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/edecbb90-c62f-44c2-d359-2482bf08e033.png)

この時、3×3の畳み込み層の出力の大きさは28×28から縮んで、26×26になります。

通常の畳み込み層では、フィルターを複数用意します。この数を**チャンネル数**と呼びます。
フィルターとチャンネルの違いが分かりづらいのですが、入力画像のチャンネル数（例えば、RGB画像の3チャンネル）は、各フィルターが学習する特徴の種類（フィルター数）によって拡張されます。各フィルターは1種類の特徴を検出し、その結果として新しいチャンネルを生成します。たとえば、16個のフィルターを適用すると、出力チャンネル数は16になります。

また、畳み込み層の出力を**特徴マップ**と呼びます。画像の内容や形状といった特徴（情報）を抽出したものです。例えば、特徴マップにはエッジや模様、形状といった情報が数値化されて含まれています。

例：
- 入力サイズ：28×28×3（RGB画像）
- フィルター数：16
- 出力サイズ：26×26×16（フィルターの数と一致）

### 畳み込みとは
畳み込み演算について説明してきましたが、畳み込みとは結局なんなんでしょうか。
答えとして、畳み込みは**内積**と言えます。

畳み込みは、同じ位置の数値をかけて足すという操作が中心になります。この行為自体、内積の計算ですね。
内積は類似度なので、似たベクトル同士になると値が大きくなります。
似た位置の色が濃く、似ていない位置の色が薄いということです。
つまり、フィルターを画像と見なしたときに、画像の中でフィルターと似た部分を検出する関数が畳み込み層となります。

### パラメータ効率
畳み込み層の強みは特徴抽出だけではありません。第一の強みがその**パラメータ効率**です。3×2の畳み込み層では、フィルター9つとバイアス項1つの10パラメータが必要になりますが、これが全領域を動いて使われるので、10個のパラメータの学習のために画像全域の情報を利用することができます。
このようにパラメータ効率が良く、学習を効率的に行うことができます。

## プーリング層
CNNでは、性能を引き上げるために様々な手法が考案されていますが、これらの手法の中で最も効果があるとされているのが、畳み込み層や全結合層の間に挿入する**プーリング層**です。プーリング層の役割は**移動不変性の付与**であり、先ほどの脳の視覚野においては**複雑型細胞**にあたります。
いくつかのプーリング層がありますが、代表的なものに**最大プーリング**というものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/9d71fe74-f432-2690-04b8-dc75aaebba9c.png)

最大プーリングは2×2や3×3などの領域を決め、その領域の最大値を出力とします。これをプールサイズだけずらしながら（ストライドと言う）、同じように最大値を出力していきます。
結果として、出力は元の画像よりも小さいサイズになり情報が失われたことになりますが、1ピクセルぶんだけ右にスライドさせながら適用することで、元の画像からの出力と形が似ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/c9d5bf83-95ca-85a5-76e7-df64b11ec53f.png)

### 役割
まとめると、プーリング層には二つ役割があります。
1. **情報の圧縮**
画像の中のあるピクセルがその画像の中にある斜めの線の一部であれば、周囲のピクセルも斜めの線の構成要素である可能性が高いです。このような理由で近接する特徴量は相関が高くなることが分かると思います。
一方で、相関が高い特徴を全部保持すると無駄が生じるので、効率が悪くなってしまします。
ここに2×2の最大プーリング層を適用すると、4つの値の最大値を計算することで相関の高い情報を一つにまとめ、特徴量マップの大きさを4分の1にすることができます。

2. **平行移動に対する頑健性を与える**
先ほどの2×2のブロックの最大値を取るため、画像が1ピクセルずれても出力があまり変化しません。その結果、画像の位置が少々ずれても安定した推論結果を与えることができます。

## パディング
プーリングを行うと、出力画像のサイズが元の画像と比べて小さくなってしまうことがありました。そこで、**パディング**という手法が存在します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/9fd08738-a152-9309-ee80-cdb882f6867b.png)

これは畳み込みなどの処理を行う前の画像の周りに、0などの値をもつピクセルを追加することで画像サイズを拡大する手法です。これにより畳み込み演算後の出力サイズを入力サイズと同じに保つことが可能になります。

また、畳み込み演算時に入力データの端部の情報が十分に考慮されない可能性もあり、パディングを施すことで、**端部の特徴**も適切に抽出できるようになります。

# 3. CNNの全体像
今までお話したCNNのざっくりとした全体像を以下に示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/769ea584-e143-2cbc-cb2d-b0a3d0ee3127.png)

実際には、層が深くなるにつれて、チャンネル数が多くなる一方で、画像サイズは小さくなっていきます。また、全体的な特徴を掴めていけるようになります。具体的なイメージを挙げます。

## CNNの基本構造の例
以下は入力画像が28×28×3のデータを10個のクラスに分類する例をあげてCNNの構造を説明した図です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/b7d3d821-8a5c-8c8e-1fde-21bcea636028.png)

構造は以下のとおりです。

1. **入力画像**
MNIST（手書き数字データ）は通常グレースケール画像だが、ここではRGB画像に拡張したものとして考える。
2. **畳み込み層 + ReLU層**
【1番目の畳み込み層】
特徴：各フィルターがエッジや基本的な模様を検出
ReLU層：畳み込みの結果に非線形性を追加
3. **最大プーリング層**
特徴：空間的なサイズを縮小し、移動不変性を付加
4. **2番目の畳み込み層 + ReLU層**
【2番目の畳み込み層】
特徴：より複雑なパターンや局所的な特徴を検出
ReLU層：畳み込みの結果に非線形性を追加
5. **最大プーリング層**
特徴：特徴マップをさらに圧縮し、移動不変性を強化
6. **全結合層**
特徴マップを1次元に変換し、全結合層に入力
特徴マップを統合し、画像全体の特徴を学習
7. **出力層 (Softmax層)**
各クラスに分類される確率値を出力

### サイズの計算
入力サイズや出力サイズの計算がどうなっているのか分かりづらいので、説明していきます。
以下は畳み込み層や最大プーリング層を通った際に、どのような出力サイズになるのかを示した図です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/20f056af-316e-0d92-56a5-f96789dac4ce.png)
記載の計算を経て、画像サイズがどんどん小さくなっていきます。

次に、全結合層に入力されるサイズになるのかを示した図です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3830602/147c6a2c-0465-e547-51c4-1a564f4cc826.png)
最後のプーリング層の出力をフラット（1次元）にして全結合層に入力します。

### 優位性
最後に、今まで述べたCNNの優位性を以下に示します。

1. **畳み込み層で局所的な特徴を学習**
ピクセルの空間的関係を保ちながら、エッジや模様といった特徴を抽出する
2. **プーリング層で移動に対する頑健性を付与**
特徴が少し位置を変えても同じものとして扱えるようになる
3. **パラメータ効率が高い**
フィルターを共有することで、学習に必要な計算量やメモリを削減できる


これらの理由から、CNNは画像認識のように空間的な構造が重要なタスクにおいて、多層パーセプトロンよりも圧倒的に適してます。

---

以上です。読んでいただきありがとうございました。

# 4. 参考
以下の記事と本を参考にさせていただきました。
- [畳み込みニューラルネットワーク(CNN)をわかりやすく基本から実装まで解説](https://zero2one.jp/learningblog/cnn-for-beginners/?srsltid=AfmBOoo_8qt9aEZPHR0UdyF-kWeCyBNs01ObuBy3ju8ppv3d9I7_ZfQM)
- [本質を捉えたデータ分析のための分析モデル入門](https://www.amazon.co.jp/%E6%9C%AC%E8%B3%AA%E3%82%92%E6%8D%89%E3%81%88%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E5%88%86%E6%9E%90%E3%83%A2%E3%83%87%E3%83%AB%E5%85%A5%E9%96%80-%E7%B5%B1%E8%A8%88%E3%83%A2%E3%83%87%E3%83%AB%E3%80%81%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92%E3%80%81%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92%E7%AD%89-%E7%94%A8%E9%80%94%E3%83%BB%E7%89%B9%E5%BE%B4%E3%81%8B%E3%82%89%E5%8E%9F%E7%90%86%E3%81%BE%E3%81%A7%E4%B8%80%E6%B0%97%E9%80%9A%E8%B2%AB-%E6%9D%89%E5%B1%B1%E8%81%A1/dp/4802613776)
- [物体・画像認識と時系列データ処理入門 [TensorFlow2/PyTorch対応第2版]](https://www.amazon.co.jp/%E7%89%A9%E4%BD%93%E3%83%BB%E7%94%BB%E5%83%8F%E8%AA%8D%E8%AD%98%E3%81%A8%E6%99%82%E7%B3%BB%E5%88%97%E3%83%87%E3%83%BC%E3%82%BF%E5%87%A6%E7%90%86%E5%85%A5%E9%96%80-TensorFlow2-PyTorch%E5%AF%BE%E5%BF%9C%E7%AC%AC2%E7%89%88-NumPy-PyTorch%E3%81%AB%E3%82%88%E3%82%8B%E5%AE%9F%E8%A3%85%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0/dp/4798063541)