---
# System prepended metadata

title: '第四章：卷積神經網路 (Convolutional Neural Networks, CNN)'
tags: [機器學習]

---

# 第四章：卷積神經網路 (Convolutional Neural Networks, CNN)
>上課筆記
* 上課影片連結
    * ==[**卷積神經網路 (Convolutional Neural Networks, CNN)**](https://youtu.be/hYdO9CscNes)==

---

## 網路架構設計：影像分類

### 模型輸入與輸出

*   **影像輸入**：
    *   模型專為影像設計。
    *   假設所有輸入影像具有 **相同的大小**，例如 $100 \times 100$ 的解析度。常見做法是將不同大小的圖片 **Rescale** 成統一尺寸後再輸入系統。
    *   對電腦而言，彩色圖片是一個 **三維的 Tensor**。
        *   維度：**寬 $\times$ 高 $\times$ Channel 數**。
        *   Channel 代表顏色通道，例如 **RGB 有3個 channel**。黑白圖片有 1 個 Channel。
        *   每一個 Pixel 的數值代表該顏色的強度。
    *   輸入模型的 Tensor 可以表示為 $x$。
![image](https://hackmd.io/_uploads/BkrZ2xX3kx.png)
*   **模型輸出**：
    *   目標是**影像分類**，判斷圖片中包含的物體。
    *   將每一個類別表示成一個 **One-Hot Vector** $\hat{y}$。
        *   向量的長度等於模型可以辨識的不同種類的數量。
        *   正確類別對應的維度數值為 1，其餘為 0。
    *   模型輸出的機率分佈為 $y'$，通過 **[Softmax](https://hackmd.io/@Jaychao2099/iamrobot3#%E7%B6%B2%E8%B7%AF%E8%BC%B8%E5%87%BA%E8%88%87-Softmax-%E5%87%BD%E6%95%B8)** 函數得到。
    *   訓練目標是最小化 $y'$ 和 $\hat{y}$ 之間的 **[Cross Entropy](https://hackmd.io/@Jaychao2099/iamrobot3#%E4%BA%A4%E5%8F%89%E7%86%B5-Cross-entropy)** 損失函數。
![image](https://hackmd.io/_uploads/BJ6_sxX31e.png)

### 與全連接網路的比較

*   傳統的做法是將三維的 Tensor **拉直 (Flatten)** 成一個巨大的向量，作為**全連接網路 (Fully Connected Network)** 的輸入。
    *   若輸入為 $100 \times 100 \times 3$ 的影像，則輸入向量的長度為 $3 \times 10^4$。
    *   全連接網路的第一層若有 1000 個 Neuron，則 Weight 的數量將會非常龐大 ($1000 \times 100 \times 100 \times 3 = 3 \times 10^7$)。
    *   過多的參數容易導致 **Overfitting (過度擬合)**。
*   **問題**：在影像處理中，真的需要使用全連接網路嗎？
    *   考慮到影像本身的特性，可能不需要每個 Neuron 都與輸入的每一個 Dimension 都有一個 Weight。
![image](https://hackmd.io/_uploads/Skku3xXh1x.png)

---

## CNN 的核心概念

### 觀察一：局部模式的重要性 (Local Patterns)

*   **關鍵思想**：影像中重要的 **Pattern (模式)**，例如鳥嘴、眼睛、鳥爪等，通常比整張圖片要小得多。
![image](https://hackmd.io/_uploads/Hk5ZTlQ3yl.png)
*   **Neuron 的感受野 (Receptive Field)**：
    *   一個 Neuron **不需要看到整張完整的圖片**，只需要看到圖片的一小部分 (Receptive Field) 就可以偵測到某些關鍵的 Pattern。
    *   在 CNN 中，每個 Neuron 只關心其 **Receptive Field** 內發生的事情。
    *   ==**簡化一：讓每個 Neuron 只看圖片的一小部分。**==
    *   **Receptive Field 的特性**：
        *   大小可以自訂，例如 $3 \times 3 \times 3$ (寬 $\times$ 高 $\times$ Channel)。小的立方體代表 Receptive Field 內的數值。
        *   同一個範圍可以有多個不同的 Neuron 負責偵測不同的 Pattern。
        *   不同的 Neuron 可以有**不同大小**的 Receptive Field (例如 $3 \times 3$, $11 \times 11$)。
        *   Receptive Field 可以只覆蓋 **部分 Channel**。
        *   Receptive Field 可以是 **非正方形** 的 (長方形)。
        *   Receptive Field 可以 **重疊**。移動 Receptive Field 的步長稱為 **Stride**。
        *   為了覆蓋影像邊緣，可以使用 **Padding (填充)**，通常是 **補零 (Zero Padding)**。
![image](https://hackmd.io/_uploads/BJsy0eQnJg.png)
![image](https://hackmd.io/_uploads/B1emAeQnye.png)

### 觀察二：模式的位置不變性 (Pattern Translation Invariance)

*   **關鍵思想**：**相同的 Pattern 可能出現在圖片的不同區域**。例如，鳥嘴可能出現在圖片的左上角或中間。
*   ![image](https://hackmd.io/_uploads/HyWl1-Qn1l.png)
*   **參數共享 (Parameter Sharing)**：
    *   如果相同的 Pattern 出現在不同的位置，是否需要在每個位置都設置一個專門偵測該 Pattern 的 Neuron？
    *   ==**簡化二：讓不同 Receptive Field 的 Neuron 共享參數 (Share Weights)**。==
        *   共享參數意味著這些 Neuron 的 **weights 完全一樣**。
        *   即使參數一樣，由於它們的 **輸入 (Receptive Field 內的數值)** 不同，它們的 **輸出也會不同**。
    *   **兩個守備相同 Receptive Field 的 Neuron 不會共享參數**，因為它們的輸出將永遠相同。
    *   在典型的 CNN 設定中，**每個 Receptive Field 都有一組 Neuron (例如 64 個)** 負責守備。
    *   這些在不同 Receptive Field 但偵測相同 Pattern 的 Neuron **共享同一組參數**。
    *   **Filter**：共享的參數組稱為一個 **Filter** 或 **Kernel**。
        *   每個 Filter 的大小為 $3 \times 3 \times \text{channel}$ 的 Tensor $(w_1,w_2,...)$。
        *   每個 Filter 負責偵測一個小的 Pattern。
        *   一個 Convolutional Layer 中通常有 **多個 Filter**。
![image](https://hackmd.io/_uploads/Sy5IkZmhkl.png)
![image](https://hackmd.io/_uploads/B1RYebQnJx.png)

### 卷積層 (Convolutional Layer)

*   **定義**：結合了 **Receptive Field** 的局部連接性和 **Parameter Sharing** 的網路層。
![image](https://hackmd.io/_uploads/H156Z-7n1x.png)
*   **兩種觀點：Neuron 版本 vs. Filter 版本**
    > [!Tip] **兩個視角等價**
    > ![image](https://hackmd.io/_uploads/Bk0JvZQnkg.png)
    *   **Neuron 版本**：每個 Neuron 只考慮一個 Receptive Field，不同 Receptive Field 的 Neuron 共享參數。
    *   **Filter 版本**：有一組 **Filter** (大小為 $3 \times 3 \times \text{channel}$ 的 Tensor) 在輸入影像上進行 **卷積 (Convolution)** 操作，每個 Filter 偵測一個特定的 Pattern。
        *   **卷積操作**：將 Filter 放在影像的左上角，計算 Filter 權重與對應影像區域數值的 **內積 (Inner Product)**。然後，Filter 以 **Stride** 的步長在影像上滑動，重複計算。
        *   每個 Filter 卷積後會產生一個 **Feature Map (特徵圖)**，表示該 Filter 在影像不同位置的激活程度。
        *   若 Convolutional Layer 有 $N$ 個 Filter，則會產生 $N$ 個 Feature Map，可以看作是一個新的圖片，其 Channel 數為 $N$。![image](https://hackmd.io/_uploads/rkiGrZXn1e.png)

        | Neuron Version Story | Filter Version Story |
        | -------- | -------- |
        | 每個 Neuron 只考慮一個 Field |有一組 Filter 偵測小的特徵|
        | 具有不同 Field 的 Neuron 共用參數|每個 Filter 都會對輸入影像進行卷積|
*   **Benefit of Convolutional Layer**:
    *   能夠有效利用影像的局部性 (Receptive Field)。
    *   能夠檢測不同區域的相同模式 (Parameter Sharing)。
    *   相較於全連接層，**模型 Bias 較大**，但更適合影像任務。
*   **多個卷積層**：可以堆疊多個卷積層，**視為新的 image**。
    *   第二層卷積的 Filter 的深度 (Channel 數) 必須與前一層輸出的 Feature Map 的 Channel 數相同。
    *   隨著網路層數的加深，即使 Filter 大小保持不變 ($3 \times 3$)，網路也能夠看到原始影像中**更大的範圍** (例如兩層 $3 \times 3$ 卷積相當於一層 $5 \times 5$ 的感受野(Receptive Field))。
![image](https://hackmd.io/_uploads/HJYIUbQnke.png)

### 觀察三：對影像進行 Subsampling(子採樣)不會改變影像中物體的本質
*   **關鍵思想**：去除影像中的 **某些rows、columns**，並不影響辨別其特徵。例如，縮小後的鳥的圖片仍然可以被識別為鳥。
![image](https://hackmd.io/_uploads/rJ2yqbQ31g.png)

#### 池化層 (Pooling Layer)
*   **目的**：**降低 Feature Map 的解析度**，減少後續計算量，並提高模型對微小變形和位置變化的[強健性(robustness)](https://en.wikipedia.org/wiki/Robustness_(computer_science))。
*   **特性**：
    *   **沒有需要學習的參數 (Non-parametric)**，類似於 Activation Function，算是一個 operator。
    *   有多種不同的 Pooling 方式，例如：
        *   **Max Pooling (最大池化)**：在一個區域內選擇 **最大的數值** 作為輸出。
        *   Min Pooling (最小池化)。
        *   Average Pooling (平均池化)。
        *   幾何平均池化。
    *   **Pooling Size (池化尺寸)** 和 **Stride** 可以自訂，例如 $2 \times 2$ 的池化尺寸。
    *   Pooling 操作通常在每個 Feature Map 上獨立進行，**不改變 Channel 數**。
*   **運作方式**：將 Feature Map 分成若干個不重疊或重疊的區域 (根據 Stride)，然後在每個區域內執行 Pooling 操作。
![image](https://hackmd.io/_uploads/S1E55-Xhye.png)
*   **Convolutional Layers + Pooling**：CNN 的常見架構是 **卷積層與池化層交替堆疊**。例如：(Convolution $\rightarrow$ Pooling) $\times N$。
*   **近年趨勢**：由於運算能力提升，一些網路架構開始 **丟棄 Pooling 層**，完全使用卷積層 (Full Convolutional Network)。
![image](https://hackmd.io/_uploads/HkrIcbm3kx.png)

### 扁平化 (Flatten) 與全連接層

*   在經過多個卷積層和池化層後，需要將最終的 Feature Map **扁平化 (Flatten)**，也就是將其拉直成一個 **向量**。
*   這個向量會被輸入到 **一個或多個全連接層 (Fully Connected Layers)**。
*   最後通常會使用 **Softmax** 函數輸出每個類別的機率。
![image](https://hackmd.io/_uploads/HJt29bQhJe.png)

---

## CNN 的應用

### 影像辨識

*   經典的 CNN 架構用於影像分類任務。

### 下圍棋 (AlphaGo)

*   **輸入**：將 $19 \times 19$ 的棋盤看作是一個 $19 \times 19$ 的**圖片**。
    *   每個位置的棋子狀態 (黑子、白子、無子) 可以用數值表示 (例如 1, -1, 0)。
    *   AlphaGo 使用 **48 個 Channel** 來描述棋盤上每一個位置的狀態，包含是否被叫吃、周圍顏色等資訊。
    *   輸入 Tensor 的大小為 $19 \times 19 \times 48$。
*   **輸出**：預測下一步應該落子的位置，是一個有 $19 \times 19$ 個類別的 **分類問題**。
*   **為什麼 CNN 適用於圍棋？**
    *   **局部模式**：圍棋中許多重要的 Pattern (例如吃子、連接) 只需要觀察 **局部範圍** ($5 \times 5$ 甚至更小) 即可判斷。AlphaGo 的第一層使用了 $5 \times 5$ 的 Filter。
    *   **位置不變性**：相同的 Pattern (例如吃子) 可能出現在棋盤上的任何位置。
![image](https://hackmd.io/_uploads/HJBOsbX2Je.png)
*   **AlphaGo 的網路架構**:
    *   將棋盤視為 $19 \times 19 \times 48$ 的圖片。
    *   使用 **Zero Padding**。
    *   第一層：$5 \times 5$ 的 Kernel Size，**192 個 Filter** ($k=192$)，Stride=1，使用 **ReLU (Rectifier Nonlinearity)** 激活函數。
    *   第二層到第 12 層：$3 \times 3$ 的 Kernel Size，**192 個 Filter**，Stride=1，使用 ReLU 激活函數。
    *   最後加上 Softmax 層進行分類。
    *   **關鍵發現**：AlphaGo **沒有使用 Pooling 層**。這表明 Pooling 並非 CNN 的必要組成部分，其適用性取決於具體的任務特性。圍棋是一個非常精細的任務，隨意進行 Subsampling 可能會損失關鍵信息。

### 其他應用

*   **[語音處理 (Speech)](https://dl.acm.org/doi/10.1109/TASLP.2014.2339736)**。
*   **[自然語言處理 (Natural Language Processing)](https://www.aclweb.org/anthology/S15-2079/)**。
*   **注意事項**：將 CNN 應用於非影像領域 (如語音、文字) 時，Receptive Field 和參數共享的設計需要仔細考慮目標資料的特性，可能與影像上的設計不同。

---

## CNN 的局限性

### 對尺度 (Scaling) 和旋轉 (Rotation) 不具不變性 (Not Invariant)
*   如果 CNN 在特定大小的物體上訓練良好，當測試時物體大小發生變化，可能無法正確識別。
*   即使形狀相同，放大或縮小後的圖片，其像素數值在拉直成向量後是不同的，對 CNN 而言是不同的輸入。
### 資料增強 (Data Augmentation)：
為了提高 CNN 對尺度和旋轉的[強健性(robustness)](https://en.wikipedia.org/wiki/Robustness_(computer_science))，通常需要進行資料增強，包括隨機裁剪、放大、旋轉訓練圖片，讓模型學習不同尺度和角度的 Pattern。
### Spatial Transformer Layer：
存在一些網路架構 (例如 Spatial Transformer Layer) 旨在解決 CNN 的尺度和旋轉不變性問題。[2017 上課影片](https://youtu.be/SoCywZ1hZak)

---

回[主目錄](https://hackmd.io/@Jaychao2099/aitothemoon/)