深度學習筆記9:卷積神經網路(CNN)入門
出處:資料科學家養成記 深度學習筆記9:卷積神經網路(CNN)入門
前面的八篇學習筆記,基本上都是圍繞著深度神經網路(DNN)和全連線網路(FCN)在學習。從本篇開始,筆者將跟著大家一起學習和研究深度學習的另一個主題——卷積神經網路(Convolutional Neural Network),也就是我們平常眼熟的 CNN。卷積神經網路作為當前計算機視覺領域的核心技術,發展到如今已是枝繁葉茂。筆者對於這一塊的初步打算是從卷積網路的基本原理講起,將卷積網路的前向傳播和反向傳播過程講清楚,以及如何使用
numpy
和
tensorflow
實現卷積網路。然後會從深度卷積網路的發展歷程出發,對主要的經典深度網路進行深度剖析,對計算機視覺的三大核心任務:影象分別、目標檢測和影象分割等技術演算法進行詳細學習和講解。
從前面的學習中,我們瞭解了深度神經網路的一般結構,它的前向傳播和反向傳播機制,而卷積神經網路相較於深度神經網路,其主要區別就在於卷積層,卷積層的存在使得神經網路具備更強的學習能力。除了卷積層之外,池化層(Pooling layer)的存在也使得卷積神經網路的魯棒性更強,最後則是 DNN 中常見的全連線層(Fully Connected layer)。一個典型的卷積神經網路通常包括這三層。
卷積神經網路的結構
那到底什麼是卷積?
從數學來說,卷積可以理解為一種類似於加權運算一樣的操作。在影象處理中,針對影象的畫素矩陣,卷積操作就是用一個卷積核來逐行逐列的掃描畫素矩陣,並與畫素矩陣做元素相乘,以此得到新的畫素矩陣。這個過程是為卷積。其中卷積核也叫過濾器或者濾波器,濾波器在輸入畫素矩陣上掃過的面積稱之為感受野。可能你還有點暈,讓我來更詳細的解釋下。
卷積過程
且看上面的動圖(這裡感謝一下 NG 大大給我們提供這麼好的教學資料),我們用一個 3x3 的濾波器去掃描一個 5x5 的畫素矩陣,用濾波器中每一個元素與畫素矩陣中感受野內的元素進行乘積運算,可得到了一個 3x3 的輸出畫素矩陣,這個輸出的 3x3 畫素矩陣能夠較大程度的提取原始畫素矩陣的影象特徵,這也是卷積神經網路之所以有效的原因。為防止有同學不清楚卷積是如何計算的,筆者以輸出畫素矩陣中第一個元素 4 為例,演示一下計算過程:
1x1 + 1x0 + 1x1 + 0x0 +1x1 + 1x0 + 0x1 +0x0 + 1x1 = 4
當然,這裡你可能會問:如何確定經過卷積後的輸出矩陣的維度?我們是有計算公式的。假設原始輸入畫素矩陣的 shape 為
nxn
,濾波器的 shape 為
fxf
,那麼輸出畫素矩陣的 shape 為
(n-f+1)x(n-f+1)
。
大體上卷積操作就是這麼個過程,是不是非常簡單。但這裡我們也需要注意兩個問題:第一個就是濾波器移動的步幅問題,上面的例子中我們的濾波器的移動步長為 1 ,即在畫素矩陣上一格一格平移。但如果濾波器是以兩個單位或者更多單位平移呢?這裡就涉及到卷積過程中的 stride 問題。第二個問題涉及到卷積操作的兩個缺點,第一個缺點在於每次做卷積,你的影象就會變小,可能做了幾次卷積之後,你的影象就變成 1x1,這就不好辦了。第二個缺點在於原始輸入畫素矩陣的邊緣和角落的畫素點只能被濾波器掃到一次,而靠近畫素中心點的畫素點則會被多次掃到進行卷積。這就使得邊緣和角落裡的畫素特徵提取不足,這就涉及到卷積過程中的 padding 問題。
針對第一個問題,也就是卷積步長問題,其實也很簡單,就是按照正常的卷積過程去操作,只不過每次多走一個畫素單位而已。且看卷積步幅為 2 的卷積操作示例:
我們用一個 3x3 的濾波器去對原始畫素為 7x7 的影象進行卷積操作,設定卷積步長為 2,可看到輸出畫素矩陣的第二行第一個元素 69 的計算跨越了兩個畫素格點,計算過程為:
3x3 + 4x4 + 8x4 + 7x1 + 8x0 + 3x2 + 4x-1 + 2x0 + 1x3 = 69
加入步長之後我們的輸出畫素矩陣的 shape 的計算公式需要更新一下為:
((n-f)/s+1)x((n-f)/s+1)
。其中
s
為步長。
針對第二個問題,卷積神經網路採用一種叫做 padding 的操作,即對原始畫素邊緣和角落進行零填充,以期能夠在卷積過程中充分利用邊緣和角落的畫素特徵。至於填充多少 0 畫素值,一般有兩個選擇,一是 valid 填充,也就是不填充,所以就不用管它了。我們在意的是有填充,就是第二種,same 填充方法。即填充後,輸入和輸出大小是一致的,對於nxn大小的輸入畫素,如果你用填充了
p
個畫素點之後,
n
就變成了
n+2p
,最後輸出畫素的 shape 計算公式就變成了
((n+2p-f)/s+1)x((n+2p-f)/s+1)
,要想讓
n+2p-f+1=n
的話,輸入輸出大小相等,則
p=(f-1)/2
。所以,一般而言,濾波器的大小
f
都會選擇為奇數個。
實際操作中,padding 的程式設計寫法如下:
def zero_pad(X, pad):
X_pad = np。pad(X, ((0,0), (pad, pad), (pad, pad), (0, 0)), ‘constant’)
return X_pad
numpy 一行程式碼即可搞定。測試效果如下:
np。random。seed(1)
x = np。random。randn(4, 3, 3, 2)
x_pad = zero_pad(x, 2)
fig, axarr = plt。subplots(1, 2)
axarr[0]。set_title(‘x’)
axarr[0]。imshow(x[0,:,:,0])
axarr[1]。set_title(‘x_pad’)
axarr[1]。imshow(x_pad[0,:,:,0])
本節對卷積神經網路的卷積細節進行了詳細的講解和筆記。關於帶有顏色通道的卷積操作我們下次筆記見。
參考資料:
https://www。
coursera。org/learn/mach
ine-learning
https://www。
deeplearning。ai/