--- tags: Knock Knock! Deep Learning --- Day 18 / DL x CV / 圖像與 CNN === Day 10 我們用 PyTorch 介紹過 MNIST 手寫數字辨識。當時用的簡單模型就是 Convoluation Neural Network (CNN),常用在抽取圖像特徵,搭配 pooling layer 減少 overfitting 的機會。等了這麼久,終於要來真正認識 CNN 的架構以及他跟圖像的結合了。 ## Motivation 一張圖片其實挺大的。就算是 MNIST 裡的手寫數字圖,28 x 28 pixels 還只有一個 color channel,就已經有 784 個不同的特徵了。RNN 在每個 timestep 接收的文字轉成 word vector 可能不過 300 的大小,一張這麼小的圖片當作 model 的 input 就已經是文字的兩三倍負擔,遑論正常大小和 RGB 3 個 color channel 的 image input 會有多驚人! 如果想要拿這麼大的 image data 來訓練 neural network,那 fully-connected layer 肯定是招架不住,因為 hidden layer 每個 node 都要連接 input 的每個維度,parameter 的數量會非常龐大。 但仔細想一下,每個 hidden node 目標是學習到對目標任務有用的某個特徵,那有需要讓每個 hidden node 都連接到整張圖片的所有角落嗎?假設我們在做車的種類判別,那可能會需要提取車的輪廓、車的標誌、車的顏色等等特徵,但這些特徵通常都只是整張圖片的一小部分。也就是說,我們需要一個架構能夠提取局部特徵就好,來減低 network 的負擔。 CNN 就是這樣一個適合圖像的 model。讓我們來看一看 CNN 怎麼提取局部特徵,並有效降低所需要的 parameter 數量。 ## CNN 一個典型的 CNN 會有這些 layer: 1. **Input layer**:$W \times H \times C$,寬 x 高 x channel 的大小 2. **Convolutional layer**:會有很多 filter 掃過圖片,提取局部特徵 3. **ReLU layer**:activation 4. **Pooling layer**:downsampling,集合小局部的特徵成為大局部的特徵 5. **Fully-connected layer**:連接到 ouput 做 softmax 以進行 classification 2 - 4 可以重複很多層,中間加入 normalization layer 亦可。 在介紹重點層之前,要知道 CNN 跟一般 fully-connected netowrk 不一樣的是他的 3D input 讓中間幾層也都是 3D 的形狀,`weight x height x depth`。Depth 可以想成 feature 數量,每一個 feature 都來自上一層 `weight x height` 的某個局部以及 `depth` 的全部。這在思考時需要稍加留意。  *—— 左:一般 neural network。右:CNN。[2]* 接下來主要介紹 convolutional layer 和 pooling layer。 ### Convolutional Layer 每層 conv layer 都由幾個 **filter** 或稱 **kernel** 作用在 input 上形成一個 activation map 作為下一層的 feature。每個 filter 會掃過整個 input 一一提取局部特徵,且 filter 的 depth 會和 input 一樣。 我們拿 32 x 32 x 3 的 input 和 5 x 5 x 3 的 filter 為例,一個 filter 和一張 image 做 convolution 大概是這樣:  *—— Convolution with 1 filter。[1]* 一個 filter 其實就是一組 weights $W$,將這個 input 局部 $X_i$ 的每個 node 連接到 hidden node,進行 $W \odot X_i + b$ 的運算($\odot$ 是 element-wise multiplication)。其實跟之前見過的 fully-connected layer 很像,只是每個 hidden node 連接到更小的 input 範圍。我們稱這個局部 $X_i$ 為這個 hidden node 的 **receptive field**。 而在 input 邊緣的部分,因為比較少被重複掃過,整個 activation map 也會小一點。以這組的大小來說 output 會是 28 x 28。 > 不懂為什麼的話可以拿紙畫一下 7 x 7 的 image 有幾個 3 x 3 大小的小正方形,也就會觀察出 output 大小會是 $(w - f + 1) \times (h - f + 1)$,$w \times h$ 是 input 大小,$f$ 是 filter 大小。 這邊可以觀察到整個 filter 是重複利用的,所以一個 5 x 5 x 3 的 filter 只會有 75 個 weights!跟之前相比有效率非常多。 為了對每個局部學習不一樣的特徵,我們會有很多不同的 filter 重複一樣的步驟:  *—— Convolution with multiple filters。[1]* 假如有 $k$ 個 filter,就會形成 $k$ 個 activation map,下一層的 depth 也是 $k$。這一層的 parameters 不算 bias 的話只會有 $75 k$ 個,相當節能減碳。 #### Stride and Padding Filter 掃過去的過程可以有些不同設定,例如從原本一次移一格變成兩格,這個大小稱為 **stride**。 而在邊角的時候也不一定要 filter 在 input 上,可以選擇讓 filter 超過邊界,而在超過的 input 加 **padding**。Padding 時還可以選擇要都填 0、延伸邊界、或其他一些選擇。  *—— Zero-padding。[1]* 另外還有一些不常見的設定,有興趣可以參考 [PyTorch Conv2d](https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html#torch.nn.Conv2d)。可以視任務特性選擇這些設定,或是用預設大概也不會差太多。不過記得這些設定也會影響 output size 的算法! ### Pooling Layer Pooling 通常出現在 activation 之後,進入下個 convolutional layer 之前。為了減少 parameters 數量以避免 overfitting,會先用 pooling 把局部結果集合起來,決定更大局部的大致特徵。另外 pooling 是 depth-wise 的,也就是每個 depth channel 不會和其他 channel 互動,自己做自己的 pooling。 以 **max pooling** 來說,假設 filter size 是 2 x 2,stride 是 2,那大概會長這樣:  *—— Max pooling。[1]* 原本 input 每 2 x 2 個局部結果取 max 當作大區域的代表,而 output 也減少了 2 x 2 倍。注意到 pooling layer 其實沒有 parameter 需要訓練,可以把它想成單純的 function。 除了 max pooling,另外常見的還有 average pooling 取平均。那麼兩者要怎麼選擇呢?因為 max pooling 只選了最大的 activation,他會喪失比較多訊息,但如果你的任務主要就是只想保留顯著的特徵,那麼 max pooling 是個好選擇。反之如果你的主要目標需要藉由提取比較完整的全局特徵來達成,那麼 average pooling 可能就會表現比較好。 ### Layer 疊疊樂 介紹完後,應該大致知道為什麼 convolutional layer 可以提取局部特徵而且能減少 network parameter,還有 pooling layer 可以藉由篩選局部最有用的特徵縮減 output 大小以避免 overfitting。 到這邊已經可以建立自己的 network 架構了。其實要建立一個還不錯的 CNN 可以很無腦,大致上就循環 `CONV-RELU-POOL` 接到 `FC`: ``` INPUT - [(CONV-RELU) * N - POOL?] * M - (FC - RELU) * K - SOFTMAX ``` 早期 CNN 的架構設計反而比不上把他建得更深來得更能讓 performance 飛快提升。之後 performance 比較難快速提升後,才有些比較有趣的架構設計,例如之前提過 ResNet 的 residual,和 GoogleLeNet 的 inception module 等等。有興趣可以看看延伸閱讀的連結。 ## What is Each Layer Doing? Network 中每一層都在抽取不同 level 的 abstract feature,這個之前應該有提到。前面幾層會捉摸靠近圖像本身的 generic feature,例如邊角、明暗、線條角度等等。後面幾層慢慢抽絲剝繭,理出跟預測任務最相關的 specific feature,例如人的五官、車的輪胎等等。 Visualize 一下每一層的 output,就能證明這件事:  *—— 每層學到不同 level 的 feature。[4]* 而把 network 建深而不是建廣的理由,就是因為 higher-level feature 很多其實都來自相同的 lower-level feature,所以一層一層的提取讓這些 feature 可以重複使用,增加效率。相反的,一個很廣但沒幾層的 network,想必每一層都重複提取了很多 low-level 特徵,大部分時候就比較沒效率了。 ## Checkpoint - 把 image 直接當作 fully-connected network 的 input,會有什麼問題?為什麼 CNN 可以避免這種問題? - 假設有一層 convolutional layer 有 64 個 filter,每個 filter 大小為 7 x 7 x 3。那麼 input 一張大小為 35 x 35 x 3 的圖片,output 大小為何?假設沒有 padding,stride 為 1。 - 承上題,不計 bias,這一層有多少 parameters? - 假設有一層 max pooling layer,每個 filter 大小為 5 x 5。那麼 input 一張大小為 35 x 35 x 3 的圖片,output 大小為何?假設沒有 padding,stride 為 5。 - 承上題,不計 bias,這一層有多少 parameters? -  圖為 Day 9 做 MNIST 示範的 CNN 架構。圖中標示的大小為 output 大小。請找出 Conv 有多少 filter 以及 filter 的合理設定。同樣的請找出 MaxPool filter 的合理設定。 ## 參考資料 1. [CS231n Lecture Slides: Convolutional Neural Networks](http://cs231n.stanford.edu/slides/2020/lecture_5.pdf) 2. [👍 CS231n Lecture Notes: Convolutional Neural Networks (CNNs / ConvNets)](https://cs231n.github.io/convolutional-networks/) 3. [CS231n Lecture Slides: CNN Architectures](http://cs231n.stanford.edu/slides/2020/lecture_9.pdf) 4. [Convolutional Neural Networks Explained](https://twopointseven.github.io/2017-10-29/cnn/) ## 延伸閱讀 1. [(He et al., 2015) Deep Residual Learning for Image Recognition](https://arxiv.org/pdf/1512.03385.pdf) 2. [(Szegedy et al., 2015) Going Deeper with Convolutions](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43022.pdf)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up