前面的八篇學(xué)習(xí)筆記,基本上都是圍繞著深度神經(jīng)網(wǎng)絡(luò)(DNN)和全連接網(wǎng)絡(luò)(FCN)在學(xué)習(xí)。從本篇開(kāi)始,筆者將跟著大家一起學(xué)習(xí)和研究深度學(xué)習(xí)的另一個(gè)主題——卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Network),也就是我們平常眼熟的 CNN。卷積神經(jīng)網(wǎng)絡(luò)作為當(dāng)前計(jì)算機(jī)視覺(jué)領(lǐng)域的核心技術(shù),發(fā)展到如今已是枝繁葉茂。筆者對(duì)于這一塊的初步打算是從卷積網(wǎng)絡(luò)的基本原理講起,將卷積網(wǎng)絡(luò)的前向傳播和反向傳播過(guò)程講清楚,以及如何使用 numpy 和 tensorflow 實(shí)現(xiàn)卷積網(wǎng)絡(luò)。然后會(huì)從深度卷積網(wǎng)絡(luò)的發(fā)展歷程出發(fā),對(duì)主要的經(jīng)典深度網(wǎng)絡(luò)進(jìn)行深度剖析,對(duì)計(jì)算機(jī)視覺(jué)的三大核心任務(wù):圖像分別、目標(biāo)檢測(cè)和圖像分割等技術(shù)算法進(jìn)行詳細(xì)學(xué)習(xí)和講解。
從前面的學(xué)習(xí)中,我們了解了深度神經(jīng)網(wǎng)絡(luò)的一般結(jié)構(gòu),它的前向傳播和反向傳播機(jī)制,而卷積神經(jīng)網(wǎng)絡(luò)相較于深度神經(jīng)網(wǎng)絡(luò),其主要區(qū)別就在于卷積層,卷積層的存在使得神經(jīng)網(wǎng)絡(luò)具備更強(qiáng)的學(xué)習(xí)能力。除了卷積層之外,池化層(Pooling layer)的存在也使得卷積神經(jīng)網(wǎng)絡(luò)的魯棒性更強(qiáng),最后則是 DNN 中常見(jiàn)的全連接層(Fully Connected layer)。一個(gè)典型的卷積神經(jīng)網(wǎng)絡(luò)通常包括這三層。
卷積神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)
那到底什么是卷積?
從數(shù)學(xué)來(lái)說(shuō),卷積可以理解為一種類似于加權(quán)運(yùn)算一樣的操作。在圖像處理中,針對(duì)圖像的像素矩陣,卷積操作就是用一個(gè)卷積核來(lái)逐行逐列的掃描像素矩陣,并與像素矩陣做元素相乘,以此得到新的像素矩陣。這個(gè)過(guò)程是為卷積。其中卷積核也叫過(guò)濾器或者濾波器,濾波器在輸入像素矩陣上掃過(guò)的面積稱之為感受野??赡苣氵€有點(diǎn)暈,讓我來(lái)更詳細(xì)的解釋下。
卷積過(guò)程
且看上面的動(dòng)圖(這里感謝一下 NG 大大給我們提供這么好的教學(xué)資料),我們用一個(gè) 3x3 的濾波器去掃描一個(gè) 5x5 的像素矩陣,用濾波器中每一個(gè)元素與像素矩陣中感受野內(nèi)的元素進(jìn)行乘積運(yùn)算,可得到了一個(gè) 3x3 的輸出像素矩陣,這個(gè)輸出的 3x3 像素矩陣能夠較大程度的提取原始像素矩陣的圖像特征,這也是卷積神經(jīng)網(wǎng)絡(luò)之所以有效的原因。為防止有同學(xué)不清楚卷積是如何計(jì)算的,筆者以輸出像素矩陣中第一個(gè)元素 4 為例,演示一下計(jì)算過(guò)程:
1x1 + 1x0 + 1x1 + 0x0 +1x1 + 1x0 + 0x1 +0x0 + 1x1 = 4
當(dāng)然,這里你可能會(huì)問(wèn):如何確定經(jīng)過(guò)卷積后的輸出矩陣的維度?我們是有計(jì)算公式的。假設(shè)原始輸入像素矩陣的 shape 為 nxn,濾波器的 shape 為 fxf,那么輸出像素矩陣的 shape 為 (n-f+1)x(n-f+1) 。
大體上卷積操作就是這么個(gè)過(guò)程,是不是非常簡(jiǎn)單。但這里我們也需要注意兩個(gè)問(wèn)題:第一個(gè)就是濾波器移動(dòng)的步幅問(wèn)題,上面的例子中我們的濾波器的移動(dòng)步長(zhǎng)為 1 ,即在像素矩陣上一格一格平移。但如果濾波器是以兩個(gè)單位或者更多單位平移呢?這里就涉及到卷積過(guò)程中的 stride 問(wèn)題。第二個(gè)問(wèn)題涉及到卷積操作的兩個(gè)缺點(diǎn),第一個(gè)缺點(diǎn)在于每次做卷積,你的圖像就會(huì)變小,可能做了幾次卷積之后,你的圖像就變成 1x1,這就不好辦了。第二個(gè)缺點(diǎn)在于原始輸入像素矩陣的邊緣和角落的像素點(diǎn)只能被濾波器掃到一次,而靠近像素中心點(diǎn)的像素點(diǎn)則會(huì)被多次掃到進(jìn)行卷積。這就使得邊緣和角落里的像素特征提取不足,這就涉及到卷積過(guò)程中的 padding 問(wèn)題。
針對(duì)第一個(gè)問(wèn)題,也就是卷積步長(zhǎng)問(wèn)題,其實(shí)也很簡(jiǎn)單,就是按照正常的卷積過(guò)程去操作,只不過(guò)每次多走一個(gè)像素單位而已。且看卷積步幅為 2 的卷積操作示例:
我們用一個(gè) 3x3 的濾波器去對(duì)原始像素為 7x7 的圖像進(jìn)行卷積操作,設(shè)定卷積步長(zhǎng)為 2,可看到輸出像素矩陣的第二行第一個(gè)元素 69 的計(jì)算跨越了兩個(gè)像素格點(diǎn),計(jì)算過(guò)程為:
3x3 + 4x4 + 8x4 + 7x1 + 8x0 + 3x2 + 4x-1 + 2x0 + 1x3 = 69
加入步長(zhǎng)之后我們的輸出像素矩陣的 shape 的計(jì)算公式需要更新一下為:
((n-f)/s+1)x((n-f)/s+1) 。其中 s 為步長(zhǎng)。
針對(duì)第二個(gè)問(wèn)題,卷積神經(jīng)網(wǎng)絡(luò)采用一種叫做 padding 的操作,即對(duì)原始像素邊緣和角落進(jìn)行零填充,以期能夠在卷積過(guò)程中充分利用邊緣和角落的像素特征。至于填充多少 0 像素值,一般有兩個(gè)選擇,一是 valid 填充,也就是不填充,所以就不用管它了。我們?cè)谝獾氖怯刑畛?,就是第二種,same 填充方法。即填充后,輸入和輸出大小是一致的,對(duì)于nxn大小的輸入像素,如果你用填充了 p 個(gè)像素點(diǎn)之后,n 就變成了 n+2p,最后輸出像素的 shape 計(jì)算公式就變成了 ((n+2p-f)/s+1)x((n+2p-f)/s+1),要想讓 n+2p-f+1=n 的話,輸入輸出大小相等,則 p=(f-1)/2。所以,一般而言,濾波器的大小 f 都會(huì)選擇為奇數(shù)個(gè)。
實(shí)際操作中,padding 的編程寫法如下:
def zero_pad(X, pad):
X_pad = np.pad(X, ((0,0), (pad, pad), (pad, pad), (0, 0)), 'constant')
return X_pad
numpy 一行代碼即可搞定。測(cè)試效果如下:
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])
本節(jié)對(duì)卷積神經(jīng)網(wǎng)絡(luò)的卷積細(xì)節(jié)進(jìn)行了詳細(xì)的講解和筆記。關(guān)于帶有顏色通道的卷積操作我們下次筆記見(jiàn)。
本文由《自興動(dòng)腦人工智能》項(xiàng)目部 凱文 投稿。
-
人工智能
+關(guān)注
關(guān)注
1791文章
47314瀏覽量
238646 -
機(jī)器學(xué)習(xí)
+關(guān)注
關(guān)注
66文章
8420瀏覽量
132685 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5503瀏覽量
121206
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論