# 【卷積神經網路】 ## 目錄 - Part1. Convolution 運算 - Part2. 特徵偵測 - Part3. Convolution On Colorful image - Part4. Convolution filter hyper parameter - Part5. ReLU - Part6. Pooling Layer - Part7. Fully connected layers - Part8. Softmax layer - Part9. Putting together - Part10. 計算參數量 - Part11. 為什麼CNN有用? - Part12. 訓練CNN - Part13. Backward propagation - Part14. Gradient descent ## Part1. Convolution 運算 透過多項特徵來辨識鬍鬚、臉型、顏色等特徵 並且在輸入到模型中,進行預處理的步驟必須包含「**通過將圖像大小調整為相同尺寸來標準化輸入數據**」 <center> <img src="https://hackmd.io/_uploads/rJYmRmKe1x.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> - 偵測影像中的特徵,例如邊緣線等 - 主要目的是特徵提取 <center> <img src="https://hackmd.io/_uploads/BkVHCQFekg.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part2. 特徵偵測 - **Filter or kernel** 特徵偵測器 → Feature map 偵測結果 (由資料和模型決定) <center> <img src="https://hackmd.io/_uploads/HJALfNtl1e.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - Feature map的大小: Feature Map Size = n - f + 1 = m <center> <img src="https://hackmd.io/_uploads/SyMOG4FgJl.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - Conv. demo: https://deeplizard.com/learn/video/YRhxdVk_sIs <br> ## Part3. Convolution On Colorful image 我們可以調整不同頻道的 filter 來關注某個顏色的特徵 Feature map size: (n × n × nc) * ( f × f × nc) = (n − f + 1) × (n − f + 1) × nf <center> <img src="https://hackmd.io/_uploads/S1tCMVYx1l.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part4. Convolution filter hyper parameter - Kernel size (k x k) - Depth - Padding - Stride ### Kernel size - Feature Map Size = n - f + 1 = m - 使用較小的 Kernel size 通常計算上更快且參數更少 - 用較大的 Kernel size 會捕捉到更大範圍的空間特徵,但可能會增加計算成本 <center> <img src="https://hackmd.io/_uploads/S1uXX4Feyg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> ### Depth - 稱 Channels、Filters / kernels <center> <img src="https://hackmd.io/_uploads/ByPNQEFx1g.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> ### Padding - 當使用較深的模型時,避免feature map持續變小 - 增加角落的pixel的貢獻 <center> <img src="https://hackmd.io/_uploads/SyTUmEFgyg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> ### Stride - 增加模型訓練效率 - 減少重複使用相同的pixel - 控制feature map的大小 - Example: Stride = 1 <center> <img src="https://hackmd.io/_uploads/rJpqQ4Kgkl.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - Example: Stride = 2 <center> <img src="https://hackmd.io/_uploads/H1d3mVtxkg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> ### Feature map Example - 公式: \begin{align} \left( \frac{n+2p-f}{s} + 1 \right) \times \left( \frac{n+2p-f}{s} + 1 \right) \\ \end{align} - Stride = 2、Padding = 0 <center> <img src="https://hackmd.io/_uploads/rJ3zV4Fxyg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> \begin{equation} \left( \frac{5 + (2 \times 0) - 3}{2} + 1 \right) \times \left( \frac{5 + (2 \times 0) - 3}{2} + 1 \right) = 2 \times 2 \end{equation} - Stride = 1、Padding = 1 <center> <img src="https://hackmd.io/_uploads/S1o1rNYlkg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> \begin{equation} \left( \frac{5 + (2 \times 1) - 3}{1} + 1 \right) \times \left( \frac{5 + (2 \times 1) - 3}{1} + 1 \right) = 5 \times 5 \end{equation} <br> ## Part5. ReLU <center> <img src="https://hackmd.io/_uploads/HJ0-BEYlkx.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - 將負數轉為0、保留正數 <center> <img src="https://hackmd.io/_uploads/SJfNrEYx1x.png" style=" width: 50%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part6. Pooling Layer <center> <img src="https://hackmd.io/_uploads/By2HrEFxke.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - 減少 feature map 的大小 - 在不丟失重要資訊的情況下減少訓練參數 - 也叫 Subsampling or Downsampling - 常使用的 pooling layer : 2x2 kernels、strides = 2、no padding - 其他 pooling 方法:average pooling、sum pooling :::success **重點筆記**: 為什麼pooling有用 - 相鄰的pixel通常具有相似的特徵(尤其是初期的layer) - 避免模型受到微小特徵差異的影響 - 在不丟失重要資訊的情況下減少訓練參數 - 太大的stride會丟失重要資訊 ::: <br> ## Part7. Fully connected layers <center> <img src="https://hackmd.io/_uploads/Bka_rEKlyg.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> - FC Layer 上的所有點都和下一層的每個點連接 - 也叫 Dense Layer <br> ## Part8. Softmax layer <center> <img src="https://hackmd.io/_uploads/Syt9HEYgyg.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <center> <img src="https://hackmd.io/_uploads/rJg2HNKeke.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part9. Putting together - A 4 Layer CNN <center> <img src="https://hackmd.io/_uploads/HJIaH4Yeyx.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <center> <img src="https://hackmd.io/_uploads/HJURHNtl1l.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part10. 計算參數量 ### 參數vs超參數 - 參數 (parameter) 1. 需要在訓練過程中讓模型去學習的變數 2. 又叫可學習的參數或權重(weights) 3. 隱藏層中的 convolutional layer 和 fully connected layer 都有權重 - 超參數 (hyperparameter) 1. 在訓練開始前由我們手動設定 2. 例如:節點數、activation function <br> ## Part11. 為什麼CNN有用? - 如果使用一般的神經網絡 1. 一張28 x 28的灰階圖片有784個pixels 2. 參照CNN裡的Conv_1: 32 filters for 26 x 26 feature maps = 21,632 nodes 3. 參數量 = 784 * 21632 = 16,959,488 (一層) 4. Conv_1參數量:320 ### CNN的優點 - **可以使用更大的 Stride 和 Max Pooling 來減少特徵圖的大小** - Parameter sharing:一個 filter 的參數可以用在 image 的不同地方 - Sparsity of connection: 在不丟失重要資訊的情況下捨棄一些pixels - Invariance: 特徵可以出現在各個位置 ### CNN背後的假設 - 低階的特徵會靠比較近 - 特徵可以出現在不同位置 - 高階的特徵是由低階特徵組成 <br> ## Part12. 訓練CNN ### Conv filter學到了什麼 - 前面的層學低階的特徵 Ex: 邊緣、線條 - 靠中間的層學中階的特徵 Ex: 眼睛 - 後面的層學高階的特徵 Ex: 鳥、花 ### Filter是如何學習的 - **隨機初始**權重 (weights) - 將單張或多張圖片**前向傳遞** (forward propagation) - 計算**誤差** - 使用**反向傳遞** (backward propagation) 和梯度下降來更新權重 - **傳遞更多圖片** (one epoch) - **反覆**執行,直到訓練損失達到滿意程度 :::info **注意事項**: 訓練過程需要 Loss Function 來告訴模型結果好壞 ::: ### Loss function - Cross entropy: 計算兩個機率分佈間的差異 \begin{equation} L = -y \cdot \log({\hat{y}}) \end{equation} 1. Binary cross entropy -> binary class 2. Categorical cross entropy -> multiclass - 其他loss functions 1. 迴歸任務 (regression): Mean square error (MSE): Mean Square Error (MSE) = (目標 - 預測)^2 2. 更多:L1, L2、Hinge Loss、Mean Absolute Error (MAE) <br> ## Part13. Backward propagation - 為濾波器的權重值訓練過程 <center> <img src="https://hackmd.io/_uploads/r1HQDNKgkl.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <center> <img src="https://hackmd.io/_uploads/HygRXvNYgJx.png" style=" width: 90%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center> <br> ## Part14. Gradient descent ### Loss function - 使用反向傳遞更新參數: $wx + b$ - 找到一組產生最低訓練損失的參數 - 更新的過程就是梯度下降 (gradient descent) - 稍微改變W會對損失E影響多少? \begin{equation} Gradient = \frac{dE}{dw} \end{equation} :::success **重點筆記**: - 如果gradient為正數,代表損失隨著權重增加而增加 - 如果gradient為負數,代表損失隨著權重增加而減少 - Gradient的值會告訴模型該往哪邊移動 ::: ### Learning rate \begin{equation} w_{new} = w_{old} - \lambda \times \frac{dE_T}{dw_{new}} \end{equation} - $\lambda$ is learning rate - Learning rate 決定我們更新的步幅 - 找到最佳的 learning rate 可以避免模型卡在區域最佳解以及超過全域最佳解 ### Gradient descent的方法 - Batch gradient descent - 每次看完全部資料才更新權重: 增加計算資源以及時間 - Stochastic gradient descent - 每次看完一筆資料就更新權重: 計算很快、不穩定且有可能訓練很久 - Mini-batch gradient descent - 每次看完一批資料就更新權重: 增加訓練速度並達到global minimum、Batch size → 8~256 ### Gradient descent的問題 - 需要決定 learning rate - 使用固定的 learning rate 容易使模型卡在區域最佳解以及超過全域最佳解 - Solution:Momentum、Learning rate schedule <center> <img src="https://hackmd.io/_uploads/S1lAv4Fgyg.png" style=" width: 70%; height: auto;"> <div style=" border-bottom: 3px solid #d9d9d9; display: inline-block; color: #999; padding: 3px;"> </div> </center>