卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)
本文翻譯自?Convolutional Neural Networks(CNNs / ConvNets),更多內(nèi)容請(qǐng)?jiān)L問(wèn):http://cs231n.github.io/。
原來(lái)譯文:https://blog.csdn.net/Consu_Yasin/article/details/78052411?
???????卷積神經(jīng)網(wǎng)絡(luò)非常類(lèi)似于普通的神經(jīng)網(wǎng)絡(luò):它們都是由具有可以學(xué)習(xí)的權(quán)重和偏置的神經(jīng)元組成。每一個(gè)神經(jīng)元接收一些輸入,然后進(jìn)行點(diǎn)積和可選的非線(xiàn)性運(yùn)算。而整個(gè)網(wǎng)絡(luò)仍然表示一個(gè)可微的得分函數(shù):從原始的圖像像素映射到類(lèi)得分。在最后一層(全連接層)也有損失函數(shù)(例如 SVM / Softmax),而且訓(xùn)練普通神經(jīng)網(wǎng)絡(luò)的已有技巧 / 技術(shù)都可以應(yīng)用。
???????然而差別在哪里呢?卷積網(wǎng)絡(luò)結(jié)構(gòu)具有特殊的圖像輸入,這個(gè)顯式的輸入假設(shè)使得網(wǎng)絡(luò)結(jié)構(gòu)具有一些特定的性質(zhì)。這些性質(zhì)使得前向函數(shù)能夠高效的實(shí)現(xiàn),并且極大的減少網(wǎng)絡(luò)的參數(shù)個(gè)數(shù)。
結(jié)構(gòu)概覽
???????回顧:普通神經(jīng)網(wǎng)絡(luò)。神經(jīng)網(wǎng)絡(luò)接收一個(gè)輸入(向量),然后通過(guò)一系列的隱藏層對(duì)輸入進(jìn)行變換。每一個(gè)隱藏層都由神經(jīng)元的集合組成,每一個(gè)神經(jīng)元與前一層的所有神經(jīng)元連接,而同一層的神經(jīng)元之間完全獨(dú)立,也不共享任何連接。最后的全連接層稱(chēng)為“輸出層”,在分類(lèi)情形下它表示類(lèi)得分。
???????普通神經(jīng)網(wǎng)絡(luò)不能適用所有圖像。CIFAR-10 數(shù)據(jù)集中的圖像大小只有 32x32x3 (寬 32,高 32,3 個(gè)顏色通道),因此一個(gè)普通神經(jīng)網(wǎng)絡(luò)的第一個(gè)隱藏層的一個(gè)全連接神經(jīng)元的參數(shù)個(gè)數(shù)是 32*32* 3 = 3072。這樣的大小看起來(lái)好像很容易處理,但顯然全連接結(jié)構(gòu)不能擴(kuò)展到大圖像。例如,一張更可觀(guān)的圖像,它的大小為 200x200x3,那么一個(gè)神經(jīng)元的就有 200*200*3 = 120,000 個(gè)參數(shù)。而且,我們幾乎總是需要很多這樣的神經(jīng)元,因此參數(shù)合在一起會(huì)快速的增長(zhǎng)。很明顯,這樣的全連接是浪費(fèi)的,而且大量的參數(shù)會(huì)很快的導(dǎo)致過(guò)擬合。
???????神經(jīng)元的 3D 方體(?,volume)。卷積神經(jīng)網(wǎng)絡(luò)充分的利用了輸入是圖像這一事實(shí),而且以一種更有意義的方式來(lái)限制它們的結(jié)構(gòu)。特別的,不像普通神經(jīng)網(wǎng)絡(luò),卷積網(wǎng)絡(luò)中的層以 3 維(寬、高、深度,這里的深度不是指整個(gè)網(wǎng)絡(luò)的深度——網(wǎng)絡(luò)中所有層的個(gè)數(shù),而是指激活方體的第三個(gè)維度)的方式來(lái)排列神經(jīng)元。例如,CIFAR-10 中的圖像是維數(shù)為 32x32x3(寬、高、深度)的激活輸入方體。我們馬上就會(huì)看到,卷積網(wǎng)絡(luò)層中的神經(jīng)元不是以全連接的方式連接到前一層的所有神經(jīng)元,而是只與一個(gè)小局部相連。而且,依據(jù)卷積網(wǎng)絡(luò)結(jié)構(gòu),用于 CIFAR-10 的卷積網(wǎng)絡(luò)的最后的輸出層的維數(shù)是 1x1x10,就把整張圖像簡(jiǎn)化成一個(gè)沿著深度方向的類(lèi)得分向量。下圖是兩種網(wǎng)絡(luò)的一個(gè)可視化:
左圖:普通的 3 層神經(jīng)網(wǎng)絡(luò)。右圖:卷積網(wǎng)絡(luò),同一層的神經(jīng)元使用三維(寬、高、深度)來(lái)可視化。卷積網(wǎng)絡(luò)的每一層把神經(jīng)元的激活的 3D 的輸入方體變換為 3D 的輸出方體。在這個(gè)例子里,紅色的輸入層保存圖像,所以它的寬度和高度是圖像的維數(shù),而深度是 3 (紅、綠、藍(lán)通道)。
卷積網(wǎng)絡(luò)由層組成。每一層都有一個(gè) API:它把 3D 的輸入方體通過(guò)一個(gè)可微函數(shù)(參數(shù)可有可無(wú))變成一個(gè) 3D 的輸出方體。
組成卷積網(wǎng)絡(luò)的層
???????正如我們?cè)谇懊嬲f(shuō)的,一個(gè)簡(jiǎn)單的卷積網(wǎng)絡(luò)是層的一個(gè)序列,每一個(gè)層通過(guò)一個(gè)可微函數(shù)把一個(gè)激活方體變成另一個(gè)。我們使用三種主要類(lèi)型的層:卷積層(Convolutional Layer)、池化層(Pooling Layer)和全連接層(Fully-Connected Layer)來(lái)建立卷積網(wǎng)絡(luò)結(jié)構(gòu)。我們將這三種類(lèi)型的層堆疊起來(lái)形成整個(gè)卷積網(wǎng)絡(luò)的結(jié)構(gòu)(architecture)。
???????結(jié)構(gòu)例子:概覽。我們會(huì)在以后更詳細(xì)的描述卷積網(wǎng)絡(luò),但一個(gè)用于 CIFAR-10 分類(lèi)的簡(jiǎn)單卷積網(wǎng)絡(luò)具有結(jié)構(gòu) [INPUT - CONV - RELU - POOL - FC]。更詳細(xì)的:
- INPUT [32x32x3] 保留圖像的原始像素值,這里的情形是寬 32,高 32,和具有 R,G,B 三個(gè)顏色通道的圖像。
- CONV 層計(jì)算與輸入局部連接的神經(jīng)元的輸出,每一個(gè)神經(jīng)元計(jì)算它們的權(quán)重與局部連接的輸入單元的權(quán)重的點(diǎn)積。如果我們使用 12 個(gè)過(guò)濾器,則得到 [32x32x12] 的單元。
- RELU 層逐元素的使用激活函數(shù)?max{0, x}。它保持單元的大小 [32x32x12] 不變。
- POOL 層沿著空間維度(寬、高)進(jìn)行降采樣運(yùn)算,得到如 [16x16x12] 的單元。
- FC(fully-connected)層計(jì)算類(lèi)得分,得到的單元大小為 [1x1x10],其中 10 個(gè)數(shù)中的每一個(gè)對(duì)應(yīng)到一個(gè)類(lèi)得分(CIFAR-10 總共 10 個(gè)類(lèi)別)。顧名思義,與普通神經(jīng)網(wǎng)絡(luò)一樣,這個(gè)層的每一個(gè)神經(jīng)元都與前一層的所有神經(jīng)元連接。
???????使用這種方法,卷積網(wǎng)絡(luò)一層一層的把原始圖像的原始像素值變換成最后的類(lèi)得分。注意到一些層包含參數(shù),而另一些層沒(méi)有。特別的,CONV / FC 層進(jìn)行的變換不僅是輸入方體的激活的函數(shù),也是神經(jīng)元的參數(shù)(權(quán)重和偏置)的函數(shù)。另一方面,RELU / POOL 層實(shí)現(xiàn)固定的函數(shù)。CONV / FC 層的參數(shù)通過(guò)梯度下降算法訓(xùn)練,使得卷積網(wǎng)絡(luò)計(jì)算的類(lèi)得分和訓(xùn)練集中的每一張圖像的類(lèi)標(biāo)號(hào)一致。
???????綜合來(lái)說(shuō):
- 卷積網(wǎng)絡(luò)結(jié)構(gòu)是把圖像方體變成輸出方體(如保存類(lèi)得分)的變換的層列表的最簡(jiǎn)單的情形
- 只有幾種不同類(lèi)型的層而已(例如,當(dāng)前 CONV / FC / RELU / POOL 最流行)
- 每一層都接收 3D 的輸入方體,然后通過(guò)一個(gè)可微函數(shù)把它變成 3D 輸出方體
- 每一層可能有參數(shù),也可能沒(méi)有(例如,CONV / FC 層有,而 RELU / POOL 層沒(méi)有)
- 每一層可能有額外的超參數(shù),也可能沒(méi)有(例如,CONV / FC / POOL 有,而 RELU 沒(méi)有)
一個(gè)樣例卷機(jī)網(wǎng)絡(luò)的激活。初始的方體保存原始圖像像素(左邊),而最后的方體保存類(lèi)得分(右邊)。沿著處理路徑的每一個(gè)激活的方體由列來(lái)顯示。由于很難可視化 3D 方體,所以通過(guò)行來(lái)展示每一個(gè)方體的切片。最后一層的方體保存每一個(gè)類(lèi)的得分,這里我們僅列出了排名前 5 的得分,及它們的標(biāo)簽。訪(fǎng)問(wèn)網(wǎng)站查看完整的?web-based demo。這里展示的是小型VGGNet(后面會(huì)討論)的結(jié)構(gòu)。
???????現(xiàn)在我們來(lái)描述特定層的超參數(shù)和它們連接的細(xì)節(jié)。
卷積層
???????卷積層(convolutional layer,Conv layer)是卷積網(wǎng)絡(luò)的核心模塊,它對(duì)卷積網(wǎng)絡(luò)的計(jì)算性能提升最多。
???????直觀(guān)概覽。首先來(lái)看看沒(méi)有腦 / 神經(jīng)元類(lèi)比的卷積層的計(jì)算。它的參數(shù)由可學(xué)習(xí)的過(guò)濾器組成。每一個(gè)過(guò)濾器都是一個(gè)小的沿著寬和高方向的空間區(qū)塊,但也可以擴(kuò)展到輸入方體的整個(gè)深度。例如,卷積網(wǎng)絡(luò)的第一層的一個(gè)典型的過(guò)濾器具有 5x5x3 的大小(也就是寬和高 5 個(gè)像素,而 3 是因?yàn)閳D像有 3 個(gè)顏色通道)。在前向傳播階段,我們沿著輸入方體的寬和高滑動(dòng)(更精確的,卷積)每一個(gè)過(guò)濾器,在每一個(gè)位置計(jì)算輸入和過(guò)濾器元素之間的點(diǎn)積。這將產(chǎn)生一個(gè) 2 維的激活映射(activation map),它是對(duì)過(guò)濾器在每一個(gè)空間位置的響應(yīng)。直觀(guān)的,網(wǎng)絡(luò)學(xué)習(xí)的過(guò)濾器會(huì)在看到某些類(lèi)型的可見(jiàn)特征(例如,網(wǎng)絡(luò)第一層的某些方向的邊緣,或者某些顏色的斑塊,或網(wǎng)絡(luò)上層的最終的蜂窩似或輪似的模式)的時(shí)候激活。在每一個(gè) CONV 層我們有過(guò)濾器的一個(gè)集合,它們每一個(gè)都產(chǎn)生一個(gè)分離的 2 維激活映射。沿著深度維數(shù)方向把這些激活映射堆疊起來(lái)就產(chǎn)生了輸出方體。
???????腦觀(guān)點(diǎn)。如果從腦 / 神經(jīng)元的類(lèi)比來(lái)看,3D 輸出方體的每一個(gè)元素都可以解釋成神經(jīng)元的輸出,這些神經(jīng)元只依賴(lài)輸入的一個(gè)小區(qū)域,而且它們與左右空間的神經(jīng)元共享參數(shù)(因?yàn)樗鼈兌际褂孟嗤倪^(guò)濾器)。現(xiàn)在我們來(lái)闡述神經(jīng)元連接的細(xì)節(jié),它們的空間排列,以及它們的參數(shù)共享方式。
???????局部連接。當(dāng)我們處理高維輸入(如圖像)的時(shí)候,把神經(jīng)元與它前一層的所有神經(jīng)元連接是不現(xiàn)實(shí)的。實(shí)際上,我們只把它和前一層的一個(gè)小區(qū)域相連。這個(gè)連接的空間范圍是稱(chēng)為神經(jīng)元的感受野(receptive field)的一個(gè)超參數(shù),它等價(jià)于過(guò)濾器的大小。沿著深度軸的連接范圍總是等于輸入方體的深度。需要再次強(qiáng)調(diào)的是我們?cè)谔幚砜臻g維度(寬和高)和深度維度的時(shí)候是不對(duì)稱(chēng)的:連接在沿著輸入方體的空間(寬和高)方向是局部的,而在深度方向則總是等于整個(gè)深度。
???????例1。假設(shè)輸入方體大小為 [32x32x3](例如一張 RGB CIFAR-10 圖像)。如果感受野(或過(guò)濾器大小)為 5x5,則卷積層的每一個(gè)神經(jīng)元連接到輸入方體的 [5x5x3] 的區(qū)域,總共有 5*5*3 = 75 個(gè)權(quán)重(再加 1 個(gè)偏置參數(shù))。注意,沿著深度方向的連接范圍必須是 3,因?yàn)樗褪禽斎敕襟w的深度。
???????例2。假設(shè)輸入方體的大小是 [16x16x20]。則使用 3x3 大小的感受野,卷積層的每一個(gè)神經(jīng)元與輸入方體有 3*3*20 = 180 個(gè)連接。再次注意,連接在空間上是局部的(如 3x3),但在輸入深度上是整體的。
左圖:一個(gè)樣例輸入方體(紅色,例如一張 32x32x3 的 CIFAR-10 圖像),和一個(gè)樣例第一個(gè)卷積層的神經(jīng)元方體。卷積層的每一個(gè)神經(jīng)元在空間上都連接到輸入方體的一個(gè)局部,但要連接整個(gè)深度(例如,所有的顏色通道)。注意,沿著深度有多個(gè)神經(jīng)元(如圖片上有 5 個(gè)),每一個(gè)都連接到輸入的相同區(qū)域(見(jiàn)下文 depth column 的討論)。右圖:與普通神經(jīng)網(wǎng)絡(luò)的神經(jīng)元一樣:它們?nèi)匀灰?jì)算權(quán)重與輸入的點(diǎn)積,然后再進(jìn)行非線(xiàn)性激活,只是它們的連接被限制到局部空間。
???????空間排列。我們已經(jīng)解釋了卷積層的每一個(gè)神經(jīng)元與輸入方體的連接,但我們還沒(méi)有討論輸出方體中神經(jīng)元的個(gè)數(shù)以及它們的排列方式。有三個(gè)超參數(shù)控制著輸出方體的大小:深度(depth),步幅(stride)和?0-填充(zero-padding)。我們分別討論如下:
???????輸出方體的大小可以通過(guò)輸入方體的大小(W),卷積層神經(jīng)元的感受野的大小(F),使用的過(guò)濾器的步幅(S),以及邊界 0-填充的量(P)的一個(gè)函數(shù)來(lái)計(jì)算。你可以確認(rèn)一下,計(jì)算輸出神經(jīng)元個(gè)數(shù)的正確公式是 (W?-?F?+ 2?P) /?S?+ 1。例如,對(duì)于 7x7 的輸入,步幅為 1 的 3x3 過(guò)濾器,以及 0 個(gè)填充,我們得到 5x5 的輸出。如果步幅為 2,則得到 3x3 的輸出。讓我們來(lái)看一個(gè)更圖形化的例子:
空間排列的說(shuō)明。在這個(gè)例子中,空間維數(shù)只有一個(gè)(x-軸),一個(gè)神經(jīng)元的感受野的大小為 F = 3,輸入大小為 W = 5,0-填充個(gè)數(shù) P = 1。左圖:步幅 S = 1,從而輸出大小為 (5 - 3 + 2) / 1 + 1 = 5。右圖:步幅 S = 2,輸出大小為 (5 - 3 + 2) / 2 + 1 = 3。注意,步幅 S = 3 不能用,因?yàn)樗黄ヅ浞襟w的大小。用方程的術(shù)語(yǔ)來(lái)說(shuō),這可由 (5 - 3 + 2) = 4 不被 3 整除來(lái)確定。
這個(gè)例子中,神經(jīng)元的權(quán)重是 [1, 0, -1](圖中最右側(cè)),偏置是 0。這些權(quán)重被所有黃色的神經(jīng)元共享(見(jiàn)下文參數(shù)共享)。
???????使用 0-填充。注意到在上面例子的左圖,輸入和輸出的維數(shù)都是 5。這之所以成立,是因?yàn)楦惺芤笆?3 而我們使用了 1 的 0-填充。如果沒(méi)有使用 0-填充,則輸出的空間維數(shù)只有 3。一般的,如果步幅?S?= 1,則設(shè)置 0-填充?P?= (F?- 1) / 2 就能確保輸入方體和輸出方體具有相同的空間維數(shù)。使用這種方式的 0-填充非常常見(jiàn),我們?cè)谶M(jìn)一步講卷積結(jié)構(gòu)的時(shí)候會(huì)討論這樣做的充足理由。
???????步幅的限制。再次注意到空間排列超參數(shù)是兩兩相互制約的。例如,當(dāng)輸入大小是?W?= 10 時(shí),如果沒(méi)有 0-填充?P?= 0,并且過(guò)濾器的大小?F?= 3,則不能使用步幅?S?= 2,因?yàn)?(W?-?F?+ 2?P) /?S?+ 1 = (10 - 3 + 0) / 2 + 1 = 4.5,也就是說(shuō),不是一個(gè)整數(shù),這意味著神經(jīng)元不是整齊和對(duì)稱(chēng)的與輸入做卷積。因此,超參數(shù)這樣設(shè)置是無(wú)效的,而且一個(gè)卷積庫(kù)(ConvNet library)會(huì)拋出一個(gè)例外,或者使用 0 的 0-填充,或者截?cái)噍斎?#xff0c;或其它方式來(lái)匹配這些超參數(shù)。我們將在卷積網(wǎng)絡(luò)結(jié)構(gòu)那一節(jié)看到,合適的設(shè)置卷積網(wǎng)絡(luò)的大小使得所有的維數(shù)都匹配確實(shí)令人頭痛,而這是 0-填充以及其它一些設(shè)計(jì)指導(dǎo)會(huì)幫我們顯著緩解的。
???????現(xiàn)實(shí)例子。Krizhevsky 等人的結(jié)構(gòu)贏得了 2012 年的 ImageNet 比賽,它接受的圖像大小是 [227x227x3]。在第一個(gè)卷積層,神經(jīng)元的感受野大小?F?= 11,步幅?S?= 4,0-填充?P?= 0。因?yàn)?(227 - 11) / 4 + 1 = 55,以及卷積層具有深度?K?= 96,所以卷積層的輸出方體大小為 [55x55x96]。這個(gè)有 55*55*96 個(gè)神經(jīng)元的方體中的每一個(gè)神經(jīng)元都與輸入方體的大小為 [11x11x3] 的區(qū)域相連。另外,每一個(gè)深度列(depth column)中的 96 個(gè)神經(jīng)元都連接到輸入方體的相同 [11x11x3] 的區(qū)域,當(dāng)然它們的權(quán)重不一樣。有趣的是,他們的論文中說(shuō)輸入圖像大小是 224x224,這顯然是不正確的,因?yàn)?(224 - 11) / 4 + 1 并不是一個(gè)整數(shù)。這在卷積網(wǎng)絡(luò)的歷史中困擾了很多人,而且很少有人知道發(fā)生了什么。我們自己最好的猜測(cè)是 Alex 使用了 3 個(gè)額外像素的 0-填充,而他沒(méi)有在論文中指出。
???????參數(shù)共享。卷積層中使用參數(shù)共享方式來(lái)控制參數(shù)個(gè)數(shù)。使用上面現(xiàn)實(shí)的例子,我們已經(jīng)知道在第一個(gè)卷積層中有 55*55*96 = 290,400 個(gè)神經(jīng)元,每一個(gè)神經(jīng)元都有 11*11*3 = 363 個(gè)權(quán)重和 1 個(gè)偏置。加起來(lái),在第一個(gè)卷積層就有 290400*363 =105,705,600 個(gè)參數(shù)。顯然,這個(gè)數(shù)非常大。
???????一個(gè)被證明能夠極大的減少參數(shù)個(gè)數(shù)的合理的假設(shè)是:如果一個(gè)特征對(duì)某個(gè)空間位置 (x,y)的計(jì)算是有用的,則它對(duì)不同位置 (x2,y2)的計(jì)算也是有用的。換句話(huà)說(shuō),如果記一個(gè)深度的二維切片為?depth slice?(例如,一個(gè)大小為 [55x55x96] 的方體有 96 個(gè) depth slice,每一個(gè)大小為 [55x55]),我們將限制每一個(gè) depth slice,使得它的所有神經(jīng)元都使用相同的權(quán)重和偏置。使用這種參數(shù)共享模式,我們的例子的第一個(gè)卷積層只有 96 個(gè)權(quán)重集(每一個(gè) depth slice 對(duì)應(yīng)一個(gè)),因此共有 96*11*11*3 = 34,848 個(gè)權(quán)重,或者 34,944 個(gè)參數(shù)(+96 個(gè)偏置)。也就是,每一個(gè) depth slice 中的所有 55*55 個(gè)神經(jīng)元都使用相同的參數(shù)。在實(shí)際的反向傳播過(guò)程中,方體中的每一個(gè)神經(jīng)元都會(huì)對(duì)參數(shù)求梯度,但每個(gè) depth slice 中的這些梯度都會(huì)加到一起,而且權(quán)重也只更新一次。
???????注意到,如果一個(gè) depth slice 中的所有神經(jīng)元都使用相同的權(quán)重向量,則卷積層在前向傳播過(guò)程時(shí),每個(gè) depth slice 計(jì)算神經(jīng)元的權(quán)重與輸入方體的卷積(因此得名:卷積層)。這也是為什么通常把權(quán)重集稱(chēng)為過(guò)濾器(filter)(或核,kernel),它與輸入進(jìn)行卷積。
?
學(xué)到的過(guò)濾器的例子(Krizhevsky et al)。96 個(gè)過(guò)濾器中的每一個(gè)都具有大小 [11x11x3],而且都被每一個(gè) depth slice 中的 55*55 個(gè)神經(jīng)元共享。注意到參數(shù)共享這個(gè)假設(shè)是合理的:如果在圖像中某個(gè)位置檢測(cè)到一個(gè)水平邊緣是重要的,則由于圖像的平移不變結(jié)構(gòu),直觀(guān)的說(shuō),在其他位置也是有用的。從而,不需要在卷積層的輸出方體中的 55*55 個(gè)位置中的每一個(gè)都重新去學(xué)習(xí)檢測(cè)水平邊緣。
???????注意,有時(shí)參數(shù)共享假設(shè)可能沒(méi)有意義。特別是如果卷積網(wǎng)絡(luò)的輸入圖像具有特定的中心結(jié)構(gòu)這種情況更是如此,在這里,我們期望,比如,學(xué)到圖像的一側(cè)相對(duì)于另一側(cè)完全不同的特征。一個(gè)實(shí)際例子是,當(dāng)輸入是居于圖像中心的人臉時(shí)。你可能期望在不同的空間位置學(xué)習(xí)到不同的眼睛或頭發(fā)特征。這種情況通常會(huì)放松參數(shù)共享模式,取而代之的是局部連接層(Locally-Connected Layer)。
???????Numpy 例子。為了讓討論變得更精確,我們把相同的想法用代碼和特定的例子來(lái)表達(dá)。假設(shè)輸入方體是一個(gè) numpy 數(shù)組?X。則:
- 在位置?(x, y)中?depth column(或?fibre)是激活 X[x, y, :]。
- 在深度?d?的?depth slice,或等價(jià)的,activation map?是激活 X[:, :, d]。
???????卷積層例子。假設(shè)輸入方體具有形狀?X.shape: (11, 11, 4)。再假設(shè)我們不使用 0-填充(P?= 0),過(guò)濾器大小?F?= 5,步幅?S?= 2。則輸出方體的的空間大小是 (11 - 5) / 2 + 1 = 4,即寬和高是 4。輸出方體的激活映射(稱(chēng)它為?V)看起來(lái)如下(在這個(gè)例子中只有其中的一些元素被計(jì)算):
- V[0, 0, 0] = np.sum(X[:5, :5, :] * W0) + b0
- V[1, 0, 0] = np.sum(X[2:7, :5, :] * W0) + b0
- V[2, 0, 0] = np.sum(X[4:9, :5, :] * W0) + b0
- V[3, 0, 0] = np.sum(X[6:11, :5, :] * W0) + b0
???????記住在 numpy 中, 上面的運(yùn)算符 * 指數(shù)組中的元素級(jí)乘法。同時(shí)要注意神經(jīng)元的權(quán)重向量是?W0,而?b0?是偏置。這里,W0?假設(shè)具有形狀?W0.shape: (5, 5, 4),因?yàn)檫^(guò)濾器大小是 5 以及輸入方體的深度是 4。而且在每一個(gè)點(diǎn),我們像通常的神經(jīng)網(wǎng)絡(luò)一樣計(jì)算點(diǎn)積。另外,我們使用相同的權(quán)重和偏置(由于參數(shù)共享),同時(shí)沿著寬度方向的維數(shù)以 2 的步長(zhǎng)(也就是步幅)增長(zhǎng)。要構(gòu)造輸出方體的第二個(gè)激活映射,我們有:
- V[0, 0, 1] = np.sum(X[:5, :5, :] * W1) + b1
- V[1, 0, 1] = np.sum(X[2:7, :5, :] * W1) + b1
- V[2, 0, 1] = np.sum(X[4:9, :5, :] * W1) + b1
- V[3, 0, 1] = np.sum(X[6:11, :5, :] * W1) + b1
- V[0, 1, 1] = np.sum(X[:5, 2:7, :] * W1) + b1(沿著 y 方向的例子)
- V[2, 3, 1] = np.sum(X[4:9, 6:11, :] * W1) + b1(沿著兩個(gè)方向的例子)
這里我們看到,V?的深度維數(shù)的下標(biāo)是 1,因?yàn)槲覀冇?jì)算的是第二個(gè)激活映射,而且現(xiàn)在使用的參數(shù)(W1)也不同。為了簡(jiǎn)單起見(jiàn),卷積層的輸出數(shù)組?V?的其它部分并沒(méi)有全部計(jì)算。另外,這些激活映射之后通常都會(huì)使用像 ReLU 這樣的激活函數(shù),雖然這里并沒(méi)有演示。
???????總結(jié)。總而言之,卷積層:
- 接收一個(gè)大小為?W1×H1×D1W1×H1×D1?方體
- 需要 4 個(gè)超參數(shù):?
- 濾波器個(gè)數(shù)?KK,
- 濾波器大小?FF,
- 步幅?SS,
- 0-填充數(shù)量?PP
- 產(chǎn)生一個(gè)大小為?W2×H2×D2W2×H2×D2?的方體:?
- W2=(W1?F+2P)/S+1W2=(W1?F+2P)/S+1
- H2=(H1?F+2P)/S+1H2=(H1?F+2P)/S+1?(寬和高對(duì)稱(chēng)的計(jì)算)
- D2=KD2=K
- 使用參數(shù)共享,每個(gè)濾波器引入?F?F?D1F?F?D1?個(gè)權(quán)重,總共?(F?F?D1)?K(F?F?D1)?K?個(gè)權(quán)重和?KK?個(gè)偏置
- 輸出方體中,第?dd?個(gè) depth slice(具有大小W2×H2W2×H2)是第?dd?個(gè)濾波器與輸入方體進(jìn)行步幅為SS的有效卷積(valid convolution),再使用第dd個(gè)偏置的結(jié)果
常用的超參數(shù)設(shè)置是?F=3,S=1,P=1F=3,S=1,P=1。然而也有其它常見(jiàn)約定和經(jīng)驗(yàn)法則來(lái)設(shè)置超參數(shù)。見(jiàn)下面的卷積網(wǎng)絡(luò)結(jié)構(gòu)一節(jié)。
???????卷積演示。下面是一個(gè)卷積層的演示動(dòng)圖。由于 3D 方體很難可視化,所有方體(輸入方體(藍(lán)色),權(quán)重方體(紅色),輸出方體(綠色))使用 depth slice 的按行堆疊來(lái)進(jìn)行可視化。輸入方體大小為?W1=5,H1=5,D1=3W1=5,H1=5,D1=3,卷積層參數(shù)為K=2,F=3,S=2,P=1K=2,F=3,S=2,P=1。也就是說(shuō),我們有兩個(gè)大小為?3×33×3?的過(guò)濾器,并且步幅為 2。因此,輸出方體的空間大小為 (5 - 3 + 2) / 2 + 1 = 3。另外,因?yàn)閷?duì)輸入方體使用了?P=1P=1?的填充,使得輸入方體的外邊界為 0。下面的可視化是對(duì)輸出激活(綠色)的重復(fù),顯示每一個(gè)元素都是通過(guò)高亮輸入(藍(lán)色)和過(guò)濾器(紅色)的元素相乘,然后相加,再加上偏置得來(lái)的。
動(dòng)圖鏈接
???????作為矩陣乘法實(shí)現(xiàn)。注意,卷積運(yùn)算本質(zhì)上是過(guò)濾器與輸入的局部區(qū)域之間的點(diǎn)積。卷積層的常用實(shí)現(xiàn)模式充分利用了這一點(diǎn),把卷積層的前向傳播格式化為大的矩陣乘法,如下:
???????這個(gè)方法的缺點(diǎn)是它要使用大量的內(nèi)存,因?yàn)檩斎敕襟w電話(huà)中一些值會(huì)在?X_col?中重復(fù)多次。然而,它的好處是存在很多的我們可以充分利用的矩陣乘法的高效實(shí)現(xiàn)(比如,經(jīng)常使用的?BLAS?API)。另外,相同的?im2col?的思想也可以用于進(jìn)行池化運(yùn)算(我們將在后面討論)。
???????反向傳播。(對(duì)于數(shù)據(jù)和權(quán)重的)卷積運(yùn)算的反向過(guò)程也是卷積(只不過(guò)過(guò)濾器是空間翻轉(zhuǎn)的)。這可以使用非常簡(jiǎn)單的 1 維例子來(lái)推導(dǎo)(這里略過(guò))。
???????1x1 卷積。在?Network in Network?首次提出后,一些論文也使用 1x1 的卷積。一些具有信號(hào)處理背景的人第一次看到 1x1 卷積的時(shí)候會(huì)很困惑,因?yàn)檎P盘?hào)都是 2 維的,因此 1x1 的卷積沒(méi)有意義(它只是進(jìn)行逐點(diǎn)的伸縮)。然而,在卷積網(wǎng)絡(luò)中情況卻不是這樣,因?yàn)槲覀儸F(xiàn)在是在 3 維輸入方體進(jìn)行操作,而且過(guò)濾器永遠(yuǎn)在輸入方體的整個(gè)深度上擴(kuò)展。例如,如果輸入大小是 [32x32x3],則使用 1x1 卷積進(jìn)行 3 維點(diǎn)積是有效的(因?yàn)檩斎肷疃扔?3 個(gè)通道)。
???????Dilated convolutions。最近的發(fā)展(例如,Fisher Yu 和 Vladlen Koltun 的論文)往卷積層上又引入了一個(gè)稱(chēng)為?dilation?的超參數(shù)。到目前為止,我們討論的卷積過(guò)濾器都是接觸的,然而,也可以有單元之間是分離的過(guò)濾器。例如,1 維的時(shí)候,一個(gè)大小為 3 的過(guò)濾器在輸入 x 上進(jìn)行計(jì)算:w[0]*x[0]+w[1]*x[1]+w[2]*x[2],這是 dilation 為 0 的情況。對(duì)于 dilation 為 1 的過(guò)濾器,則計(jì)算?w[0]*x[0]+w[1]*x[2]+w[2]*x[4]。換句話(huà)說(shuō),權(quán)重使用的時(shí)候是有間隔的。當(dāng)與 0-dilated 的過(guò)濾器進(jìn)行聯(lián)合使用的時(shí)候,這變得非常有用,因?yàn)樗挥煤苌俚膶泳湍芨叨鹊娜诤陷斎氲目臻g信息。例如,如果你堆疊兩個(gè) 3x3 的卷積層,你可以確認(rèn)第二個(gè)層的神經(jīng)元是輸入的的 5x5 的圖塊的函數(shù)(我們說(shuō)這些神經(jīng)元的有效感受野是 5x5)。假如我們使用 dilated convolution,則這些有效感受野會(huì)更快的增長(zhǎng)。
池化層
???????在卷積結(jié)構(gòu)中通常會(huì)在相繼的卷積層之間周期性的插入池化層(Pooling Layer),它的作用是逐漸的減少表示的空間大小,從而減少網(wǎng)絡(luò)的參數(shù)的個(gè)數(shù)核計(jì)算量,進(jìn)而控制過(guò)擬合。池化層在輸入的每個(gè) depth slice 上使用 MAX 操作獨(dú)立的計(jì)算,改變它的空間大小。池化層最常用的形式是在輸入的每個(gè) depth slice 上使用 2x2 大小的過(guò)濾器和步幅為 2 的降采樣,忽略其中 75% 的激活。每一個(gè) MAX 操作都是對(duì) 4 個(gè)數(shù)(depth slice 中的 2x2 小區(qū)域)取最大。另外,網(wǎng)絡(luò)的深度保持不變。一般的,池化層:
- 接收大小為W1×H1×D1W1×H1×D1?的方體
- 需要 2 個(gè)超參數(shù):?
- 空間范圍?FF
- 步幅SS
- 產(chǎn)生大小為?W2×H2×D2W2×H2×D2?的方體,其中:?
- W2=(W1?F)/S+1W2=(W1?F)/S+1
- H2=(H1?F)/S+1H2=(H1?F)/S+1
- D2=D1D2=D1
- 不引入新的參數(shù),因?yàn)樗怯?jì)算輸入的固定函數(shù)
- 池化層通常不使用 0-填充
???????值得注意的是實(shí)際中常用的最大池化層(max pooling layer)只有兩種:F=3,S=2F=3,S=2的池化層(也稱(chēng)為重疊池化)和更常見(jiàn)的?F=2,S=2F=2,S=2?的池化層。具有更大感受野的池化大小是有害的。
???????一般池化。除了最大池化,池化單元還可以進(jìn)行其它函數(shù)運(yùn)算,比如平均池化(average pooling)和?L2-范數(shù)池化(L2-norm pooling)。平均池化在過(guò)去較為常用,因?yàn)橄啾戎?#xff0c;最大池化在實(shí)際中性能更好。
池化層對(duì)輸入方體的每一個(gè) depth slice 在空間上進(jìn)行獨(dú)立的降采樣。左圖:在這個(gè)例子中,對(duì)大小為 [224x224x64] 的輸入方體進(jìn)行過(guò)濾器大小為 2 和步幅為 2 的池化,得到大小為 [112x112x64] 的輸出方體。這里注意到方體的深度保持不變。右圖:最常用的降采樣操作是取最大值的最大池化(max pooling),這里顯示的是步幅為 2 的最大池化,每一次都對(duì) 4 個(gè)數(shù)(2x2 的小方塊)取最大值。
???????反向傳播。對(duì) max(x, y) 的反向傳播操作可以簡(jiǎn)單的解釋成只是對(duì)正向過(guò)程的最大值的輸入進(jìn)行梯度運(yùn)算。因此,在池化層的正向過(guò)程中通常要追蹤最大激活(有時(shí)也稱(chēng)為開(kāi)關(guān)(switches))的下標(biāo),使得反向傳播很高效。
???????不使用池化。很多人不喜歡池化運(yùn)算,并且認(rèn)為我們可以不需要它。例如,Striving for Simplicity: The All Convolutional Net?建議忽略池化層而用只有不停重復(fù)的卷積層的結(jié)構(gòu)來(lái)取代。為了減小表示的大小,他們建議在卷積層中使用大的步幅。不使用池化層對(duì)訓(xùn)練好的生成模型,例如變分自編碼器(variational autoencodes, VAEs)或生成對(duì)抗網(wǎng)絡(luò)(generative adversarial networks, GANs),也被發(fā)現(xiàn)是重要的。現(xiàn)在看起來(lái),未來(lái)不使用池化層的結(jié)構(gòu)會(huì)很少。
標(biāo)準(zhǔn)化層
???????在卷積網(wǎng)絡(luò)結(jié)構(gòu)中使用了很多類(lèi)型的標(biāo)準(zhǔn)化層(normalization layer),有時(shí)是為了實(shí)現(xiàn)在生物腦中觀(guān)察到的抑制模式的意圖。然而這些層已經(jīng)不再受歡迎,因?yàn)樵趯?shí)際使用時(shí)它們的作用很小(如果有的話(huà))。要了解各種類(lèi)型的標(biāo)準(zhǔn)化,參考 Alex Krizhevsky 的分析?cuba-convnet library API。
全連接層
???????正如普通神經(jīng)網(wǎng)絡(luò)中那樣,全連接層(fully-connected layer,FC layer)中的神經(jīng)元與它前一層的所有激活都先連。因此,這種激活可以通過(guò)矩陣乘法,然后加上偏置來(lái)計(jì)算。(請(qǐng)參考這一系列的?Neural Network?獲取更多信息)
全連接層轉(zhuǎn)化為卷積層
???????全連接層(FC layer)和卷積層(CONV layer)僅有的區(qū)別是:卷積層中的神經(jīng)元只連接到輸入的局部區(qū)域,而且很多的神經(jīng)元共享參數(shù)。然而,這兩種層中的神經(jīng)元都要計(jì)算點(diǎn)積,因此它們的函數(shù)形式是一樣的。從而,將全連接層轉(zhuǎn)化為卷積層是可行的:
- 對(duì)任意卷積層,存在一個(gè)全連接層能實(shí)現(xiàn)相同的前向函數(shù),對(duì)應(yīng)的權(quán)重矩陣是一個(gè)只在特定塊非零(由于局部連接)的大矩陣,而且很多塊的權(quán)重相等(由于參數(shù)共享)。
- 反過(guò)來(lái),任意的全連接層可以轉(zhuǎn)化為卷積層。例如,對(duì)于具有?K=4096K=4096?個(gè)神經(jīng)元,且與大小為?7×7×5127×7×512?的輸入方體相連的全連接層,可以等價(jià)的的表示成?F=7,P=0,S=1,K=4096F=7,P=0,S=1,K=4096?的卷積層。換句話(huà)說(shuō),我們令過(guò)濾器的大小恰好等于輸入方體的大小,從而得到?1×1×40961×1×4096?的輸出,也就是對(duì)輸入方體的每一個(gè) depth slice 進(jìn)行卷積,它的結(jié)果與原來(lái)全連接層的一樣。
???????FC->CONV 的轉(zhuǎn)化。在這兩個(gè)轉(zhuǎn)化中,將全連接層轉(zhuǎn)化為卷積層在實(shí)際中特別有用。考慮一個(gè)卷積網(wǎng)絡(luò)結(jié)構(gòu),它以 224x224x3 的圖像作為輸入,然后使用一系列的卷積層和池化層將圖像簡(jiǎn)化為大小為 7x7x512 的激活方體(在后面我們將要看到的 AlexNet 中,這由 5 個(gè)池化層得到,每一個(gè)在空間上使用因子為 2 的降采樣,使得最后的空間大小為 224/2/2/2/2/2 = 7)。之后,AlexNet 使用兩個(gè)大小為 4096 的全連接層,最后再接一個(gè)具有 1000 個(gè)神經(jīng)元的全連接層來(lái)計(jì)算類(lèi)得分。我們可以把這三個(gè)全連接層轉(zhuǎn)化為卷積層:
- 將第一個(gè)全連接層用具有大小為?F=7F=7?的過(guò)濾器的卷積層替換,把 [7x7x512] 的輸入方體變?yōu)?[1x1x4096] 的輸出方體
- 將第二個(gè)全連接層用具有大小為?F=1F=1?的過(guò)濾器的卷積層替換,得到 [1x1x4096] 的輸出方體
- 類(lèi)似的,替換最后一個(gè)全連接層,其中?F=1F=1,最后的輸出大小為 [1x1x1000]
???????每一個(gè)這樣的轉(zhuǎn)化在實(shí)際中都要將全連接層的權(quán)重矩陣重新塑形為卷積層的過(guò)濾器。這種轉(zhuǎn)化只用一個(gè)前向傳播過(guò)程,在大圖像中沿著空間位置滑動(dòng)的進(jìn)行原來(lái)的卷積,被證明是非常高效的。
???????例如,如果一張 224x224 的圖像給出 [7x7x512] 的輸出,也就是簡(jiǎn)化 32 倍,那么對(duì)于一張 384x384 的圖像,在轉(zhuǎn)化結(jié)構(gòu)下將給出等價(jià)的大小為 [12x12x512] 的方體,因?yàn)?384 / 32 = 12。然后再通過(guò)我們剛剛由全連接層轉(zhuǎn)化來(lái)的卷積層,給出大小為 [6x6x1000] 的最終方體,因?yàn)?(12 - 7) / 1 + 1 = 6。注意,對(duì)于一幅 384x384 的圖像,我們不再得到大小為 [1x1x1000] 的單個(gè)類(lèi)得分向量,而是得到類(lèi)得分的整個(gè) 6x6 的數(shù)組。
對(duì) 384x384 的圖像使用步幅為 32 個(gè)像素的 224x224 剪切,再獨(dú)立的使用原來(lái)的卷積網(wǎng)絡(luò)(含有全連接層),得到的結(jié)果和轉(zhuǎn)化來(lái)的卷積網(wǎng)絡(luò)的是一樣的。
???????自然的,轉(zhuǎn)化來(lái)的卷積網(wǎng)絡(luò)只計(jì)算一次,比原來(lái)的卷積網(wǎng)絡(luò)計(jì)算 36 次要高效很多,因?yàn)檫@ 36 次其實(shí)可以共享計(jì)算。這種技術(shù)在實(shí)際中經(jīng)常用來(lái)得到更好的性能,例如,通常把圖像調(diào)整為更大的形狀,然后使用轉(zhuǎn)化的卷積網(wǎng)絡(luò)來(lái)計(jì)算多個(gè)空間位置的類(lèi)得分,再對(duì)這些類(lèi)得分進(jìn)行平均。
???????最后,如果步幅小于 32 個(gè)像素,我們?cè)鯓幽芨咝У膶⒃瓉?lái)的卷積網(wǎng)絡(luò)應(yīng)用到圖像?我們可以多次使用前向過(guò)程來(lái)得到。例如,如果我們想要使用 16 個(gè)像素的步幅,那我們可以將兩個(gè)用轉(zhuǎn)化來(lái)的卷積網(wǎng)絡(luò)得到的方體組合起來(lái):首先是對(duì)原始圖像的,然后是對(duì)沿著寬和高各平移 16 個(gè)像素的圖像的。
- 一個(gè)用 IPython Notebook 寫(xiě)的?Net Surgery?顯示怎樣實(shí)際的用代碼(使用 Caffe)進(jìn)行轉(zhuǎn)化。
卷積網(wǎng)絡(luò)結(jié)構(gòu)
???????我們已經(jīng)知道卷積網(wǎng)絡(luò)通常只由三種類(lèi)型的層組成:卷積層(CONV layer)、池化層(POOL layer,如果沒(méi)有特別聲明,都假設(shè)是 MAX pool)和全連接層(fully-connected layer,FC layer)。我們也會(huì)顯式的寫(xiě)出整流線(xiàn)性單元(RELU)激活函數(shù),它非線(xiàn)性的應(yīng)用到每個(gè)元素。這一節(jié)我們討論怎樣將這些層堆疊起來(lái)形成整個(gè)卷積網(wǎng)絡(luò)。
層模式
???????卷積網(wǎng)絡(luò)最常見(jiàn)的形式是堆疊一些 CONV-RELU 層,之后是 POOL 層,然后重復(fù)這個(gè)模式直到圖像在空間上已經(jīng)被融合成小的尺寸。在某些節(jié)點(diǎn),還通常要過(guò)渡到全連接層。最后的全連接層保存輸出,例如類(lèi)得分。換句話(huà)說(shuō),最常用的卷積網(wǎng)絡(luò)遵循下述模式:
INPUT -> [[CONV -> RELU]*N -> POOL?]*M -> [FC -> RELU]*K -> FC- 1
其中?*?表示重復(fù),POOL??表示可選的池化層。另外,N >= 0(且通常?N <= 3),M >= 0,K >= 0(且通常?K < 3)。例如,一些經(jīng)常見(jiàn)到的卷積網(wǎng)絡(luò)結(jié)構(gòu)有如下模式:
- INPUT -> FC,實(shí)現(xiàn)線(xiàn)性分類(lèi)器。這里?N = M = K = 0。
- INPUT -> CONV -> RELU -> FC。
- INPUT -> [CONV -> RELU -> POOL]*2 -> FC -> RELU -> FC。這里我們看到 POOL 層之間只有一個(gè) CONV 層。
- INPUT -> [CONV -> RELU -> CONV -> RELU -> POOL]*3 -> [FC -> RELU]*2 -> FC。這里 POOL 層之間堆疊了兩個(gè) CONV 層。這對(duì)大而深的網(wǎng)絡(luò)來(lái)說(shuō)是個(gè)好想法,因?yàn)樵诰哂衅茐男缘某鼗\(yùn)算之前堆疊多個(gè) CONV 層能夠?qū)斎敕襟w提取出更多復(fù)雜的特征。
???????相比大感受野的卷積層優(yōu)先選擇堆疊小過(guò)濾器的卷積層。假設(shè)你接連堆疊三個(gè) 3x3 的卷積層(當(dāng)然,它們之間還有非線(xiàn)性運(yùn)算)。在第一個(gè)卷積層上的神經(jīng)元對(duì)輸入方體有 3x3 的視野,而第二層上的神經(jīng)元對(duì)第一層也有 3x3 的視野,從而對(duì)輸入方體有 5x5 的視野。類(lèi)似的,第三層的神經(jīng)元對(duì)第二層有 3x3 的視野,從而對(duì)輸入方體有 7x7 的視野。假設(shè)我們只用一個(gè)具有 7x7 感受野的卷積層替代這三個(gè) 3x3 的卷積層。這些神經(jīng)元雖然在空間范圍上對(duì)輸入方體的感受野也恰好是 7x7,但是卻有一些缺點(diǎn)。首先,這些神經(jīng)元只對(duì)輸入計(jì)算了線(xiàn)性函數(shù),而三個(gè)卷積層的堆疊卻包含非線(xiàn)性從而使得特征更富有表示性。第二,如果我們假設(shè)所有方體的通道數(shù)都是?CC,那么單個(gè) 7x7 卷積層具有?C×(7×7×C)=49C2C×(7×7×C)=49C2?個(gè)參數(shù),而三個(gè) 3x3 卷積層只有?3×(C×(3×3×C))=27C23×(C×(3×3×C))=27C2?個(gè)參數(shù)。直觀(guān)上,相比于單個(gè)具有大過(guò)濾器的卷積層,堆疊多個(gè)小過(guò)濾器的卷積層能表達(dá)輸入的更強(qiáng)大的特征,而且參數(shù)更少。但這也有實(shí)現(xiàn)上的缺點(diǎn),就是我們需要更多的內(nèi)存來(lái)保存中間卷積層的結(jié)果,好讓我們能進(jìn)行反向傳播。
???????背離趨勢(shì)。值得注意的是,由層進(jìn)行線(xiàn)性堆疊的約定范式最近已經(jīng)發(fā)生改變,如 Google 的 Inception 結(jié)構(gòu),以及最近微軟亞洲研究院(Microsoft Research Asia)的(state of the art)殘差網(wǎng)絡(luò),這兩個(gè)網(wǎng)絡(luò)(細(xì)節(jié)見(jiàn)下面案例研究一節(jié))都具有錯(cuò)綜復(fù)雜的連接結(jié)構(gòu)。
???????實(shí)踐:在 ImageNet 上使用什么網(wǎng)絡(luò)最好。如果你正在為網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計(jì)而苦苦思索,那么很高興告訴你 90% 及以上的應(yīng)用是不需要擔(dān)憂(yōu)這個(gè)問(wèn)題的。我把這總結(jié)為一個(gè)觀(guān)點(diǎn):“不要做英雄”,與其為一個(gè)問(wèn)題設(shè)計(jì)自己的結(jié)構(gòu),不如看看當(dāng)前哪些網(wǎng)絡(luò)在 ImageNet 上性能最好,然后下載一個(gè)預(yù)訓(xùn)練模型再用你自己的數(shù)據(jù)來(lái)精調(diào)。你幾乎不需要痛苦的訓(xùn)練或設(shè)計(jì)一個(gè)卷積網(wǎng)絡(luò)。我在?Deep Learning school?也說(shuō)了這一觀(guān)點(diǎn)。
層大小模式
???????到目前為止,我們還沒(méi)有注意卷積網(wǎng)絡(luò)中每一層的超參數(shù)的常用設(shè)置。我們將首先陳述一些結(jié)構(gòu)大小的常用經(jīng)驗(yàn)法則,然后基于這些法則來(lái)做一些分析:
???????輸入層(input layer)(保存圖像)應(yīng)當(dāng)可以被 2 除很多次。常見(jiàn)的大小包括 32(如 CIFAR-10),64,96(如 STL-10),或者 224(如常用的 ImageNet 卷積網(wǎng)絡(luò)),384 和 512。
???????卷積層(conv layer)應(yīng)該使用小過(guò)濾器(比如 3x3,至多 5x5),使用步幅?S=1S=1,而且最重要的是使用 0-填充來(lái)確保卷積層不會(huì)改變輸入的空間維數(shù)。也就是說(shuō),如果?F=1F=1,則用?P=1P=1?的 0-填充來(lái)保持輸入的原始大小。當(dāng)?F=5F=5?時(shí),P=2P=2。對(duì)一般的?FF,設(shè)置?P=(F?1)/2P=(F?1)/2?來(lái)保持輸入的大小。如果你一定要使用大尺寸的過(guò)濾器(比如 7x7 或更大),則通常是在輸入圖像之后的第一個(gè)卷積層使用。
???????池化層(pool layer)負(fù)責(zé)對(duì)輸入的空間維數(shù)進(jìn)行降采樣。最常用的設(shè)置是使用步幅為 2 (S=2S=2)的 2x2(F=2F=2)感受野的最大池化(max-pooling),這恰好忽略了輸入方體激活的 75%(因?yàn)閷?duì)寬和高進(jìn)行 2 個(gè)單位的降采樣)。另外一個(gè)不常用的設(shè)置是使用步幅為 2 的 3x3 感受野。很少見(jiàn)到用于最大池化的感受野的大小超過(guò) 3,因?yàn)檫@樣的池化太高度聚合而過(guò)多損失信息導(dǎo)致性能很差。
???????減輕頭痛程度。上面的模式令人很愉快,因?yàn)樗械木矸e層都保持輸入的空間尺寸,而池化層則只負(fù)責(zé)在空間上進(jìn)行降采樣。如果換一種方式,我們使用步幅超過(guò) 1 或者不對(duì)卷積層的輸入進(jìn)行 0-填充,則我們要非常仔細(xì)的在卷積網(wǎng)絡(luò)結(jié)構(gòu)中跟蹤輸入方體以確保所有的步幅和過(guò)濾器起作用,以及卷積網(wǎng)絡(luò)結(jié)構(gòu)能好的和對(duì)稱(chēng)的串聯(lián)起來(lái)。
???????為什么在卷積層中使用步幅 1。小的步幅在實(shí)際中效果更好。而且步幅為 1 使得卷積層只需要改變輸入方體的深度,而將所有空間降采樣的任務(wù)留給池化層。
???????為什么使用填充。使用 0-填充,除了在上面說(shuō)的能在經(jīng)過(guò)卷積層之后還保持空間大小的好處之外,它實(shí)際上還能提升性能。如果不使用 0-填充而僅進(jìn)行有效卷積,則在每一個(gè)卷積層之后方體的大小都會(huì)輕微減小,而且邊界信息會(huì)很快的消失。
???????內(nèi)存限制的讓步。在某些情況下(特別是早期的卷積網(wǎng)絡(luò)結(jié)構(gòu)),在上面所說(shuō)的經(jīng)驗(yàn)法則下內(nèi)存消耗增長(zhǎng)得非常快。例如,使用三個(gè) 3x3 的卷積層,每個(gè)具有 64 個(gè)過(guò)濾器,對(duì) 224x224x3 的圖像先進(jìn)行 1 個(gè)像素的填充,然后再進(jìn)行卷積過(guò)濾,得到三個(gè)大小為 [224x224x64] 的激活方體。所有這些加在一起將近 1000 萬(wàn)個(gè)激活項(xiàng),或者 72MB 的內(nèi)存(每張圖像,對(duì)激活和梯度都是)。因?yàn)?GPU 通常都有內(nèi)存瓶頸,所以必須做出讓步。在實(shí)際中,人們傾向于只對(duì)網(wǎng)絡(luò)的第一個(gè)卷積層讓步。比如,一個(gè)讓步是在第一個(gè)卷積層使用步幅為 2 的 7x7 的過(guò)濾器(如將要看到的 ZFNet)。另一個(gè)例子是 AlexNet 使用步幅為 4 的 11x11 的過(guò)濾器。
案例研究
???????在卷積網(wǎng)絡(luò)領(lǐng)域,有很多的結(jié)構(gòu)都有命名。最常見(jiàn)的是:
- LeNet。在上世紀(jì)九十年代,Yann LeCun 首次使得卷積網(wǎng)絡(luò)獲得成功應(yīng)用。其中,最有名的結(jié)構(gòu)是?LeNet,它用于讀取郵政編碼、數(shù)字等。
- AlexNet。在計(jì)算機(jī)視覺(jué)領(lǐng)域,第一個(gè)最受歡迎的卷積網(wǎng)絡(luò)是?AlexNet,它由 Alex Krizhevsky,IIya Sutskever 和 Geoff Hinton 建立。AlexNet 在 2012 年的?ImageNet ILSVRC challenge?上提交結(jié)果,表現(xiàn)遠(yuǎn)超第二名(相比第二名的 top 5 錯(cuò)誤率 26%,它只有 16%)。這個(gè)網(wǎng)絡(luò)的結(jié)構(gòu)非常類(lèi)似 LeNet,只是它更深、更大,而且有多個(gè)卷積層堆疊在一起(此前,通常一個(gè)卷積層之后緊跟著池化層)。
- ZFNet。2013 年的 ILSVRC 由 Matthew Zeiler 和 Rob Fergus 提出的卷積網(wǎng)絡(luò)獲得冠軍,即現(xiàn)在有名的?ZFNet(Zeiler & Fergus Net 的縮寫(xiě))。它是由調(diào)整 AlexNet 的超參數(shù)改善而來(lái),特別是擴(kuò)大了 AlexNet 的中間卷積層大小,以及減小了第一個(gè)卷積層的步幅和過(guò)濾器大小。
- GoogLeNet。2014 年的 ILSVRC 的冠軍是由來(lái)源于谷歌的?Szegedy et al.?提出的卷積網(wǎng)絡(luò)。它的主要貢獻(xiàn)是發(fā)展了?Inception Module,可以極大的減少網(wǎng)絡(luò)的參數(shù)個(gè)數(shù)(4M 相比于 AlexNet 的 60 M)。而且,在卷積網(wǎng)絡(luò)頂層用平均池化層(Average Polling)替換了全連接層,消減了大量的無(wú)關(guān)緊要的參數(shù)。GoogLeNet 有很多的后續(xù)版本,最近的版本是?Inception-v4。
- VGGNet。2014 年的 ILSVRC 的亞軍是?VGGNet,由 Karen Simonyan 和 Andrew Zisserman 提出。它的主要貢獻(xiàn)是證明網(wǎng)絡(luò)深度是好的性能的關(guān)鍵因素。他們最后最好的網(wǎng)絡(luò)包含 16 個(gè) CONV / FC 層,一個(gè)從始至終只進(jìn)行 3x3 的卷積和 2x2 的池化的異常齊次的結(jié)構(gòu)。他們的?pretrained model?可以公開(kāi)下載(使用 Caffe 編寫(xiě))。VGGNet 的一個(gè)缺點(diǎn)是:它的計(jì)算代價(jià)很高昂,使用大量?jī)?nèi)存和參數(shù)(140M)。大量的參數(shù)來(lái)源于第一個(gè)全連接層,而且現(xiàn)在已經(jīng)知道這些全連接層就算被移除也不會(huì)讓性能下降,但卻可以顯著的減少參數(shù)個(gè)數(shù)。
- ResNet。殘差網(wǎng)絡(luò)(Residual Network,ResNet)由何愷明(Kaiming He)等人建立,它是 ILSVRC 2015 年的冠軍。它使用了特殊的?skip connections?和大量的應(yīng)用了?batch normalization。網(wǎng)絡(luò)結(jié)構(gòu)的最后也沒(méi)有使用全連接層。讀者可以參考愷明的報(bào)告(視頻,幻燈片),最近一些實(shí)驗(yàn)用 Torch 復(fù)現(xiàn)了他們的結(jié)果。到目前為止,ResNet 是最好的(the state of the art)卷積神經(jīng)網(wǎng)絡(luò),也是實(shí)際使用卷積網(wǎng)絡(luò)的默認(rèn)選擇(截止到 2016 年 5 月 10 日)。特別的,最近的發(fā)展?Kaiming He et al. Identity Mappings in Deep Residual Networks(發(fā)表于 2016 年 4 月) 調(diào)整了原來(lái)的網(wǎng)絡(luò)結(jié)構(gòu)。
???????VGGNet細(xì)節(jié)。作為一個(gè)案例研究,讓我們更詳細(xì)的來(lái)分解一下?VGGNet。整個(gè) VGGNet 由進(jìn)行步幅為 1,1 個(gè)單位填充的 3x3 卷積的卷積層,和進(jìn)行步幅為 2(沒(méi)有填充)的 2x2 最大池化的池化層組成。我們可以把處理過(guò)程的每一步的表示的大小寫(xiě)出來(lái),也可以追蹤表示大小和參數(shù)個(gè)數(shù):
INPUT: [224x224x3] memory: 224*224*3=150K weights: 0 CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*3)*64 = 1,728 CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*64)*64 = 36,864 POOL2: [112x112x64] memory: 112*112*64=800K weights: 0 CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*64)*128 = 73,728 CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*128)*128 = 147,456 POOL2: [56x56x128] memory: 56*56*128=400K weights: 0 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*128)*256 = 294,912 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824 POOL2: [28x28x256] memory: 28*28*256=200K weights: 0 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*256)*512 = 1,179,648 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296 POOL2: [14x14x512] memory: 14*14*512=100K weights: 0 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 POOL2: [7x7x512] memory: 7*7*512=25K weights: 0 FC: [1x1x4096] memory: 4096 weights: 7*7*512*4096 = 102,760,448 FC: [1x1x4096] memory: 4096 weights: 4096*4096 = 16,777,216 FC: [1x1x1000] memory: 1000 weights: 4096*1000 = 4,096,000TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd) TOTAL params: 138M parameters- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
???????注意到,與通常的卷積網(wǎng)絡(luò)一樣,大量的內(nèi)存(和計(jì)算時(shí)間)都使用在早期的卷積層,而大部分的參數(shù)都來(lái)源于最后的全連接層。在這個(gè)特殊案例下,第一個(gè)全連接層包含整個(gè)網(wǎng)絡(luò)的 140M 個(gè)參數(shù)中的 100M 個(gè)。
計(jì)算考量
???????在構(gòu)造卷積網(wǎng)絡(luò)結(jié)構(gòu)的時(shí)候,最大的瓶頸是內(nèi)存瓶頸。很多現(xiàn)代的 GPU 都有 3 / 4 / 6 GB 的內(nèi)存限制,就算是最好的 GPU 也只有大約 12 GB 的內(nèi)存。有三個(gè)主要的內(nèi)存占用項(xiàng):
- 來(lái)源于中間方體大小:它們是卷積網(wǎng)絡(luò)的每一層的激活(activations)的原始數(shù)值,以及它們的梯度(大小相等)。通常大量的激活都集中在卷積網(wǎng)絡(luò)的淺層(也就是前面的卷積層)。它們需要保留,因?yàn)樵诜聪騻鞑サ臅r(shí)候要用到,當(dāng)然在測(cè)試階段,卷積網(wǎng)絡(luò)聰明的實(shí)現(xiàn)是只保存任一層當(dāng)前的激活而忽略前面層的激活,這在原則上可以大量的減少內(nèi)存。
- 來(lái)源于參數(shù)大小:它們是網(wǎng)絡(luò)參數(shù)(parameters)的數(shù)值,反向傳播時(shí)的梯度,和通常還包括使用 momentum,Adagrad,或者 RMSProp 優(yōu)化時(shí)的緩存。因此,保存參數(shù)向量的內(nèi)存必須要乘以至少是 3 或者更大的因子。
- 每一個(gè)卷積網(wǎng)絡(luò)的實(shí)現(xiàn)都要維護(hù)各種各樣(miscellaneous)的內(nèi)存,比如圖像數(shù)據(jù)批量,可能是它們的增強(qiáng)版本等等。
???????一旦你對(duì)值(activations,gradients,misc)的總個(gè)數(shù)有一個(gè)大概的估計(jì),這個(gè)數(shù)應(yīng)當(dāng)轉(zhuǎn)化為多少 GB。取值的個(gè)數(shù),乘以 4 就得到原始 bytes 數(shù)(因?yàn)槊恳粋€(gè)浮點(diǎn)數(shù)是 4 bytes,如果是雙精度浮點(diǎn)數(shù)則是 8 bytes),然后除以 1024 多次來(lái)得到多少 KB,MB,GB 的內(nèi)存。如果你的網(wǎng)絡(luò)與內(nèi)存不匹配,一個(gè)讓它匹配的常用啟發(fā)式方法是減小批量大小,因?yàn)榇罅康膬?nèi)存通常由激活消耗。
其它資源
???????與實(shí)現(xiàn)有關(guān)的其它資源:
- 卷積網(wǎng)絡(luò)性能的 Soumith 基準(zhǔn)
- ConvNetJS CIFAR-10 demo?允許你在網(wǎng)頁(yè)上設(shè)置卷積網(wǎng)絡(luò)結(jié)構(gòu),查看實(shí)時(shí)計(jì)算的結(jié)果
- Caffe,一個(gè)流行的卷積網(wǎng)絡(luò)庫(kù)
- State of the art ResNets in Torch7
總結(jié)
以上是生活随笔為你收集整理的卷积神经网络(Convolutional Neural Networks,CNNS/ConvNets)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 神经网络中常用的激活函数
- 下一篇: 深度学习:卷积神经网络(convolut