卷積神經網路基礎之百度飛漿課程筆記
卷積神經網路基礎之百度飛漿課程筆記
卷積神經網路的基礎知識主要有卷積、池化、啟用函式、批歸一化和Dropout等理論和技巧共五部分,下面將逐一展開進行介紹。
卷積(Convolution)
卷積計算
卷積在數學中是一種積分變換的方法,可能大家對這個也不太關心,在卷積神經網路中,卷積層的實現方式實際上是數學中定義的互相關運算,通常是用滑動視窗的點積運算來完成,如下圖 卷積計算過程(來自百度飛漿深度學習課程):
上圖中的0、1、2、3組成的矩陣就叫做卷積核,一個卷積運算元除了進行上述的卷積計算之外,還包括加上偏置項的操作,即在卷積計算的結果基礎上加上一個常數項。
卷積輸出特徵圖的尺寸計算公式如下:
\[\begin{aligned} H_{\text {out}} &=H-k_{h}+1 \\ W_{\text {out}} &=W-k_{w}+1 \end{aligned} \]
\(H\) 表示輸入圖片的高度,\(W\)表示輸入圖片的寬度,\(k_{h}\) 表示卷積核的高度,\(k_{w}\)表示卷積核的寬度,\(1\) 表示偏置項,\(H_{out}\)表示輸出尺寸的高,\(W_{out}\)表示輸出尺寸的寬。(尺寸計算一定要會,很基礎也很重要)
填充(padding)
在卷積計算中,我們知道經過卷積之後,輸出尺寸是在變小的,為了避免卷積之後圖片尺寸不斷變小,通常會在圖片的外圍進行填充操作,從而保證尺寸的固定,如下圖所示(來源於百度飛漿):
如上圖(a)所示,填充的大小為1,使得輸入圖片尺寸由4 x 4變為6 x 6,根據上述卷積尺寸計算公式,經過卷積之後輸出尺寸變為4 x 4。
加入padding後卷積輸出特徵圖的尺寸計算公式如下:
如果在圖片高度方向,在第一行之前填充\(p_{h1}\)行,在最後一行之後填充\(p_{h2}\)行;在圖片的寬度方向,在第1列之前填充\(p_{w1}\)列,在最後1列之後填充\(p_{w2}\)列;則填充之後的圖片尺寸為\((H+p_{h1}+p_{h2})×(W+p_{w1}+p_{w2})\)。經過大小為\(k_h\times k_w\)的卷積核操作之後,輸出圖片的尺寸為:
\[\begin{array}{l} H_{\text {out}}=H+p_{h 1}+p_{h 2}-k_{h}+1 \\ W_{\text {out}}=W+p_{w 1}+p_{\text {w} 2}-k_{w}+1 \end{array} \]
在卷積計算過程中,通常會在高度或者寬度的兩側採取等量填充,即\(p_{h1} = p_{h2} = p_h\),\(p_{w1} = p_{w2} = p_w\),,上面計算公式也就變為:
\[\begin{aligned} H_{\text {out}} &=H+2 p_{h}-k_{h}+1 \\ W_{\text {out}} &=W+2 p_{w}-k_{w}+1 \end{aligned} \]
這應該是經常會看到的公式的樣子,實際中,卷積核通常使用1,3,5,7這樣的奇數,通過上述等式,如果我們想要卷積後的影象尺寸不變,則可以得到填充大小為\(p_h=(k_h-1)/2\),\(p_w=(k_w-1)/2\),這也是我們經常會在設計卷積網路模型時需要進行的尺寸計算。
步幅(stride)
卷積層的引數步幅簡單來說就是在卷積計算中,滑動視窗每次滑動的距離,很好理解,直觀來看如下圖:
步幅分為兩個方向,分別是高\(s_h\)和寬\(s_w\),通常都設定為一樣的大小。
加入stride後卷積輸出特徵圖的尺寸計算公式如下:
\[\begin{aligned} H_{\text {out}} &=\frac{H+2 p_{h}-k_{h}}{s_{h}}+1 \\ W_{\text {out}} &=\frac{W+2 p_{w}-k_{w}}{s_{w}}+1 \end{aligned} \]
感受野(Receptive Field)
輸出特徵圖上每個點的數值,是由輸入圖片上大小為\(k_h\times k_w\)的區域的元素與卷積核每個元素相乘再相加得到的,所以輸入影象上\(k_h\times k_w\)區域內每個元素數值的改變,都會影響輸出點的畫素值。我們將這個區域叫做輸出特徵圖上對應點的感受野。感受野內每個元素數值的變動,都會影響輸出點的數值變化。比如\(3×33\)卷積對應的感受野大小就是\(3×3\)。
多通道操作
實際應用中通常都是多通道進行卷積,如影象的RGB三個通道,這樣的資料輸入和輸出都是多通道的,所以需要能夠處理多通道的場景,除此之外,神經網路中多采用批訓練的方式,所以卷積運算元需要具有批量處理多通道的能力。
-
多輸入通道場景
假設圖片的通道數為\(C_{in}\) ,輸入資料的形狀為\(C_{in}\times H_{in}\times W_{in}\) ,則計算過程如下圖所示:
- 對每一個通道分別設計一個2維陣列卷積核,所以卷積核數組的形狀為\(C_{in}\times k_{h}\times k_w\) 。
- 對任意一個通道,分別用對應通道的卷積核進行卷積運算。
- 將這\(C_{in}\) 個通道各自的卷積計算結果相加,得到一個形狀為\(H_{out}\times W_{out}\) 的二維陣列。
- 其中\(H_{out}\times W_{out}\) 的大小依據單通道的公式計算即可。
-
多輸出通道場景
一般來說,卷積操作的輸出特徵圖也具有多通道\(C_{out}\) ,這時我們需要設計\(C_{out}\) 個維度為\(C_{in}\times k_h\times k_w\) 的卷積核,這裡可能不太好理解,不過只要多一點點思考就可以想明白了,其實只是在維度上增加了而已,不過實際中通常我們將多通道輸出個數叫做卷積核個數,因為四維空間較為抽象,卷積核數組的最終維度為\(C_{out}\times C_{in}\times k_h\times k_w\) ,如下圖:
- 對任一輸出通道\(c_{o u t} \in\left[0, C_{o u t}\right)\) ,都是使用上面描述的\(C_{in}\times k_h\times k_w\) 卷積核對影象做卷積得到的。
- 將\(C_{out}\)個形狀為\(H_{out} \times W_{out}\) 二維陣列拼在一起,就得到\(C_{out}\times H_{out}\times W_{out}\) 形狀的多通道輸出。
- 對這個的理解,需要一步步的,首先掌握單通道的卷積尺寸計算,然後掌握多輸入通道場景的計算,再然後就可以很好理解多輸出通道場景的計算了。
-
批量操作
卷積神經網路中,通常進行多樣本一起訓練,即輸入資料的維度為\(N\times C_{in}\times H_{in}\times W_{in}\) 。由於會對每張圖片使用同樣的卷積核進行卷積操作,所以卷積核的計算和上述多輸出通道一樣,卷積核的維度仍然是\(C_{out}\times C_{in}\times k_h\times k_w\) ,輸出維度為\(N\times C_{out}\times H_{out}\times W_{out}\) ,如下圖所示:
池化(Pooling)
簡介:池化是使用某一位置的相鄰輸出的總體特徵代替網路在該位置的輸出,經過池化操作後,特徵圖的尺寸會變得很小,一定程度上可以減少神經元的個數,節省空間提高效率。
方法:平均池化和最大池化。平均池化即取池化視窗區域數值的平均值作為池化結果,最大池化即取池化視窗區域的最大值作為池化結果。圖例如下:
輸出尺寸計算:池化層與卷積層類似,也可以進行Padding,也有步長,也有池化視窗,這裡設步長為\(s_h\) 和\(s_w\) ,高度上填充為\(p_{h1}\) 和\(p_{h2}\) ,寬度上填充為\(p_{w1}\) 和\(p_{w2}\) ,則池化層輸出尺寸為:
\[\begin{aligned} H_{\text {out}} &=\frac{H+p_{h 1}+p_{h 2}-k_{h}}{s_{h}}+1 \\ W_{\text {out}} &=\frac{W+p_{w 1}+p_{w 2}-k_{w}}{s_{w}}+1 \end{aligned} \]
啟用函式
啟用函式為神經網路提供了非線性的性質,提高了神經網路的表現能力,所以在神經網路中選擇合適的啟用函式是十分重要的。常用的啟用函式有sigmoid、tanh、Relu、Leaky Relu、MaxOut等,目前在深度學習中Relu的效果還是較為不錯的。關於啟用函式更詳細的介紹可以參考該部落格《常用啟用函式總結》 ,這裡就不過多贅述(其實我就是懶了,不想造輪子總結,拿來主義也挺好,並且個人覺得這個部落格講的挺清晰明白的,希望讀者諒解呀^0^)。
批歸一化
模型的收斂需要穩定的資料分佈,歸一化(標準化)可以將資料對映到一個穩定分佈的空間。對於淺層的神經網路,可能只需要對輸入資料做歸一化就可以得到較好的結果,但對於深度神經網路來說,僅僅對輸入資料做歸一化是不足夠的,我們還需要對中間過程的輸出資料也做歸一化,從而讓深度網路模型也能很好的收斂,提高模型的穩定性。詳細內容
批歸一化公式計算過程
-
計算mini-batch內樣本的均值
-
計算mini-batch內樣本的方差
-
計算標準化之後的輸出
-
對標準化的輸出進行平移和縮放
如果強行限制輸出層的分佈是標準化的,可能會導致模型某些特徵模式的丟失,所以會緊接著需要進行平移和縮放
注:如果一個樣本具有多個特徵,則對每個特徵分別計算均值和方差
批歸一化實踐技巧
上面講到的批歸一化計算過程,我們是以一個batch為例的,只是為了講清楚具體的計算公式,但我們在實際預測時候,如果是以一個batch的資料的均值和方差來歸一化,則會導致同一個樣本在不同的batch中歸一化結果不同,導致預測結果不一致,存在偏差,這並不是我們想要的結果,所以我們需要在整個資料集上進行歸一化的操作,具體如下:
-
解決方案:訓練時計算在整個資料集上的均值和方差,並將結果儲存,預測時不計算樣本內均值和方差,而是使用訓練時儲存的值
-
計算方法:在訓練過程中通過滾動平均的方式,計算在整個資料集上的均值和方差並儲存,公式如下:
\[\begin{array}{l} \text { saved } _{-}\mu_{B} \leftarrow \text { saved }_{-} \mu_{B} \times 0.9+\mu_{B} \times(1-0.9) \\ \text { saved }_{-} \sigma_{B}^{2} \leftarrow \text { saved_ } \sigma_{B}^{2} \times 0.9+\sigma_{B}^{2} \times(1-0.9) \end{array} \]
\({ saved } _{-}\mu_{B}\) 表示訓練過程中前面所有輪次的滾動的均值;
\({ saved }_{-} \sigma_{B}^{2}\) 表示訓練過程中前面所有輪次的滾動的方差;
0.9
表示滾動平均的動量係數(momentum);\(\mu_{B}\) 表示本輪batch資料的均值;
\(\sigma_{B}^{2}\) 表示本輪batch資料的方差;
按照上述公式不斷迭代,直到訓練過程結束,最後得到的均值和方差儲存下來,作為預測資料歸一化的均值和方差。
注:也許你會覺得可以直接針對整個資料集計算出均值和方差並儲存下來,這樣確實是很直觀的一個方法,我個人剛開始也是這樣想的,但課程中老師並未詳細解釋,後續我會繼續跟蹤這個問題,如果您偶有所瞭解,非常歡迎在評論區留下您的見解!!!
丟棄(Dropout)
簡介
Dropout是一種抑制過擬合的方法
方法
- 訓練階段:每次隨機的刪除一部分神經元,不向前傳播所攜帶的資訊,相當於每次都是讓不同的模型在學習
- 測試階段:向前傳播所有神經元的資訊,相當於讓不同的模型一起工作
直觀來看,如下圖所示:
如果需要進一步瞭解Dropout的原理和實踐操作,請參考該部落格《Dropout原理解析》
總結
卷積神經網路基礎的小結就到此結束了,非常感謝您能讀到這裡,也更加希望您能在看完本篇長文後有所收穫,你的進步和鼓勵就是我作為知識搬運工的最大動力!!!
有任何疑問都歡迎在評論區提出討論,分享交流,共同進步!!!