深度学习入门笔记(十八):卷积神经网络(一)
歡迎關注WX公眾號:【程序員管小亮】
專欄——深度學習入門筆記
聲明
1)該文章整理自網上的大牛和機器學習專家無私奉獻的資料,具體引用的資料請看參考文獻。
2)本文僅供學術交流,非商用。所以每一部分具體的參考資料并沒有詳細對應。如果某部分不小心侵犯了大家的利益,還望海涵,并聯系博主刪除。
3)博主才疏學淺,文中如有不當之處,請各位指出,共同進步,謝謝。
4)此屬于第一版本,若有錯誤,還需繼續修正與增刪。還望大家多多指點。大家都共享一點點,一起為祖國科研的推進添磚加瓦。
文章目錄
- 歡迎關注WX公眾號:【程序員管小亮】
- 專欄——深度學習入門筆記
- 聲明
- 深度學習入門筆記(十八):卷積神經網絡(一)
- 1、Padding填充
- 2、卷積步長
- 3、三維卷積
- 4、單層卷積網絡
- 5、總結
- 推薦閱讀
- 參考文章
深度學習入門筆記(十八):卷積神經網絡(一)
推薦博客:大話卷積神經網絡CNN(干貨滿滿)
1、Padding填充
為了構建深度神經網絡,需要學習很多東西,除了前面講過的最基本的卷積,還需要學會使用的一個基本的卷積操作就是 padding,一起來看看它是如何工作的。
我們在 深度學習入門筆記(十六):計算機視覺之邊緣檢測 中講過卷積這個例子,如果用一個3×3的過濾器卷積一個6×6的圖像,那么最后會得到一個4×4的輸出(也就是一個4×4矩陣)。這背后的數學解釋是,如果有一個 n×nn×nn×n 的圖像,用 f×ff×ff×f 的過濾器做卷積,步長是1,那么輸出的維度就是 (n?f+1)×(n?f+1)(n-f+1)×(n-f+1)(n?f+1)×(n?f+1),即 6?3+1=46-3+1=46?3+1=4。
這樣的話會有兩個缺點:
- 第一個缺點是,每次卷積,圖像就會縮小,從6×6縮小到4×4,再多做幾次之后,比如當一個100層的深層網絡,每經過一層圖像都縮小,經過100層網絡后,就會得到一個很小很小的圖像,可能是1×1,可能是別的,但我們不想讓圖像在每次識別邊緣或其他特征時都縮小。
- 第二個缺點是,如果是在角落邊緣的像素,這個綠色陰影標記只被一個輸出所觸碰或者使用,因為它位于這個3×3的區域的一角;但如果是在中間的像素點,比如紅色方框標記,就會有許多個3×3的區域與之重疊,所以那些在角落或者邊緣區域的像素點在輸出中采用較少,意味著丟失了圖像邊緣位置的許多信息。
為了解決問題,在卷積操作之前可以填充這幅圖像。
比如在這個案例中,可以沿著圖像邊緣再填充一層像素,這樣6×6的圖像就被填充成了8×8。如果用3×3的圖像對這個8×8的圖像卷積,得到的輸出就不是4×4而是6×6,這樣就得到了一個尺寸和原始圖像相同的圖像。
習慣上是用0去填充!如果 ppp 是填充的數量,在這個案例中 p=1p=1p=1,因為在原始圖像周圍填充了一個像素點,輸出也就變成了 (n+2p?f+1)×(n+2p?f+1)(n+2p-f+1)×(n+2p-f+1)(n+2p?f+1)×(n+2p?f+1),所以就變成了 (6+2×1?3+1)×(6+2×1?3+1)(6+2×1-3+1)×(6+2×1-3+1)(6+2×1?3+1)×(6+2×1?3+1),即 6×66×66×6,和輸入的圖像一樣大。這樣的話,涂綠的像素點(左邊矩陣)影響了輸出中的這些格子(右邊矩陣)。這樣一來,丟失信息或者更準確來說角落或圖像邊緣的信息發揮的作用較小的這一缺點就被削弱了。
填充像素通常有兩個選擇,分別叫做 Valid 卷積和 Same 卷積:
- Valid 卷積意味著不填充,這樣的話,p=0p=0p=0。
- Same 卷積意味著填充,且輸出大小和輸入大小是一樣的。
習慣上,計算機視覺中濾波器大小 fff 是奇數,甚至可能都是這樣,比如1,3,5,為什么很少能看到偶數的過濾器,大概有兩個原因:
- 第二個原因是,如果 fff 是一個偶數,那么只能使用一些不對稱填充,而只有 fff 是奇數的情況下,Same 卷積才會有自然的填充,而不是左邊填充多一點,右邊填充少一點,這樣不對稱的填充。
- 第二個原因是,當有一個奇數維過濾器,比如3×3或者5×5的,它就有一個中心點。有時在計算機視覺里,如果有一個中心像素點會更方便,便于指出過濾器的位置。
看起來,也許這些都不是為什么 fff 通常是奇數的充分原因,但如果看了卷積的文獻,你就會經常會看到3×3的過濾器,也可能會看到一些5×5,7×7的過濾器,甚至有些時候會是1×1的,后面會談到它以及什么時候它是有意義的。
2、卷積步長
卷積中的步幅是另一個構建卷積神經網絡的基本操作,來看一個例子。
如果也想用3×3的過濾器卷積這個7×7的圖像,和之前不同的是,現在步幅設置成了2。第一個位置還是和之前一樣取左上方的3×3區域的元素的乘積,再加起來,最后結果為91,然后向右移動兩個空格,以此類推。
所以這個例子中是用3×3的矩陣卷積一個7×7的矩陣,得到一個3×3的輸出,計算公式還是和之前一樣,過程如下:
如果用一個 f×ff×ff×f 的過濾器卷積一個 n×nn×nn×n 的圖像,padding 為ppp,步幅為 sss,在這個例子中 s=2s=2s=2,那么輸出變為 (n+2p?fs+1)×(n+2p?fs+1)(\frac{n+2p - f}{s} + 1) \times (\frac{n+2p - f}{s} + 1)(sn+2p?f?+1)×(sn+2p?f?+1),其實之前的例子也是一樣,只不過 s=1s=1s=1,而在現在這個例子里 n=7n=7n=7,p=0p=0p=0,f=3f=3f=3,s=2s=2s=2,7+0?32+1=3\ \frac{7 + 0 - 3}{2} + 1 =3?27+0?3?+1=3,即3×3的輸出。
現在只剩下最后的一個細節了,如果商不是一個整數怎么辦?在這種情況下是會向下取整的,??? ??? 就是向下取整的符號,也叫做對 zzz 進行地板除(floor),這意味著 zzz 向下取整到最近的整數。這個原則具體實現的方式是,只在藍框完全包括在圖像或填充完的圖像內部時,才對它進行運算;如果有任意一個藍框移動到了外面,那就不要進行相乘操作,這是一個慣例。
3、三維卷積
卷積不僅僅可以發生在二維圖像上,也可以發生在三維立體上。
來看一個例子,假如說不僅想檢測灰度圖像的特征,也想檢測 RGB 彩色圖像的特征。如果彩色圖像是6×6×3,這里的3指的是三個顏色通道,可以想象成3個6×6圖像的堆疊,為了檢測圖像的邊緣或者其他的特征,不是把它跟原來的3×3的過濾器做卷積,而是跟一個三維的3×3×3的過濾器卷積,這樣這個過濾器也有三層,對應紅綠、藍三個通道。
給這些起個名字(原圖像),這里的第一個6代表圖像高度,第二個6代表寬度,這個3代表通道的數目。同樣地,過濾器也有一個高,寬和通道數,并且圖像的通道數必須和過濾器的通道數匹配,所以這兩個數(紫色方框標記的兩個數,3)必須相等。
還是卷積的過程,最后一個數字通道數必須和過濾器中的通道數相匹配。
把過濾器先放到最左上角的位置,這個3×3×3的過濾器有27個數,27個參數就是3的立方,依次取這27個數,然后乘以相應的紅綠藍通道中的數字:
- 先取紅色通道的前9個數字,
- 然后是綠色通道,
- 然后再是藍色通道,
- 乘以左邊黃色立方體覆蓋的對應的27個數,
- 然后把這些數都加起來,就得到了輸出的第一個數字。
如果要計算下一個輸出,就把這個立方體滑動一個單位,執行上面的操作,以此類推。
那么,這個能干什么呢?
舉個例子,這個過濾器是3×3×3的,如果想檢測圖像紅色通道的邊緣,那么可以將第一個過濾器設為 [10?110?110?1]\begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\\end{bmatrix}???111?000??1?1?1????,和之前一樣,而綠色通道全為0([000000000]\begin{bmatrix} 0& 0 & 0 \\ 0 &0 & 0 \\ 0 & 0 & 0 \\\end{bmatrix}???000?000?000????),藍色也全為0。這樣的三個矩陣堆疊在一起形成一個3×3×3的過濾器就是一個檢測垂直邊界的過濾器,且只對紅色通道有用。
或者如果你不關心垂直邊界在哪個顏色通道里,那么可以用一個這樣的過濾器,[10?110?110?1]\begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\ \end{bmatrix}???111?000??1?1?1????,[10?110?110?1]\begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\ \end{bmatrix}???111?000??1?1?1????,[10?110?110?1]\begin{bmatrix}1 & 0 & - 1 \\ 1 & 0 & - 1 \\ 1 & 0 & - 1 \\\end{bmatrix}???111?000??1?1?1????,三個通道都是這樣的。按照計算機視覺的慣例,過濾器可以有不同的高,不同的寬,但是必須一樣的通道數。
現在我們已經了解了如何對立方體卷積,還有最后一個概念就是,如果不僅僅想要檢測垂直邊緣怎么辦?如果同時檢測垂直邊緣和水平邊緣,還有45°傾斜的邊緣,還有70°傾斜的邊緣怎么做?換句話說,如果想同時用多個過濾器怎么辦?
一個6×6×3的圖像和這個3×3×3的過濾器卷積,得到4×4的輸出:
- 第一個過濾器可能是一個垂直邊界檢測器或者是學習檢測其他的特征;
- 第二個過濾器可以是一個水平邊緣檢測器。
所以和第一個過濾器卷積,可以得到第一個4×4的輸出,然后卷積第二個過濾器,得到另一個不同的4×4的輸出,待做完卷積之后把這兩個4×4的輸出,把兩個輸出堆疊在一起得到了一個4×4×2的輸出立方體。
小結一下 維度問題,如果有一個 n×n×ncn \times n \times n_{c}n×n×nc? 的輸入圖像,在上面是6×6×3,ncn_{c}nc? 是通道(或者深度)數目,然后卷積上一個 f×f×ncf×f×n_{c}f×f×nc?,在上面是3×3×3,按照慣例,這個(前一個 ncn_{c}nc?)和這個(后一個 ncn_{c}nc?)必須數值相同,然后就得到了 (n?f+1)×(n?f+1)×nc′(n-f+1)×(n-f+1)×n_{c^{'}}(n?f+1)×(n?f+1)×nc′?,這里 nc′n_{c^{'}}nc′? 其實就是下一層的通道數,就是用的過濾器的個數,在上面就是4×4×2。這對立方體卷積的概念真的很有用!用它的一小部分直接在三個通道的 RGB 圖像上進行操作,更重要的是,可以檢測兩個特征,比如垂直和水平邊緣或者10個或者128個或者幾百個不同的特征,并且輸出的通道數會等于準備要檢測的特征數。
4、單層卷積網絡
做了這么多準備之后,終于可以開始構建卷積神經網絡的卷積層,下面來看個例子。
通過兩個過濾器卷積處理一個三維圖像,并輸出兩個不同的矩陣:
最終各自形成一個卷積神經網絡層,然后增加偏差(實數),通過 Python 的廣播機制給這16個元素都加上同一偏差,然后應用非線性激活函數 ReLU,輸出結果是一個4×4矩陣。對于第二個4×4矩陣,是加上了不同的偏差(實數),然后應用非線性函數,最終得到另一個4×4矩陣。然后重復之前的步驟,把這兩個矩陣堆疊起來,得到一個4×4×2的矩陣。
廣播機制看這里:深度學習入門筆記(五):神經網絡的編程基礎
通過計算,從6×6×3的輸入推導出一個4×4×2矩陣,它是卷積神經網絡的一層,把它映射到標準神經網絡中四個卷積層中的某一層或者一個非卷積神經網絡中。
注意,前向傳播中一個操作就是 z[1]=W[1]a[0]+b[1]z^{[1]} = W^{[1]}a^{[0]} + b^{[1]}z[1]=W[1]a[0]+b[1],其中 a[0]=xa^{[0]} =xa[0]=x,執行非線性函數得到 a[1]a^{[1]}a[1],即 a[1]=g(z[1])a^{[1]} = g(z^{[1]})a[1]=g(z[1]),輸入是a[0]a^{\left\lbrack 0\right\rbrack}a[0],也就是 xxx,過濾器用變量 W[1]W^{[1]}W[1] 表示。在整個卷積過程中,對這3×3×3=27個數進行操作,其實是27×2(因為用了兩個過濾器),取這些數做乘法,實際執行了一個線性函數,得到一個4×4的矩陣,卷積操作的輸出結果是一個4×4的矩陣,它的作用類似于 W[1]a[0]W^{[1]}a^{[0]}W[1]a[0],也就是這兩個4×4矩陣的輸出結果,然后加上偏差。
這一部分(圖中藍色邊框標記的部分)就是應用激活函數 ReLU 之前的值,它的作用類似于 z[1]z^{[1]}z[1],最后應用非線性函數,得到的這個4×4×2矩陣,成為神經網絡的下一層,也就是激活層,這就是 a[0]a^{[0]}a[0] 到 a[1]a^{[1]}a[1] 的演變過程。
示例中有兩個過濾器,也就是有兩個特征,因此最終才得到一個4×4×2的輸出,但如果用了10個過濾器,而不是2個,最后會得到一個4×4×10維度的輸出圖像,因為我們選取了其中10個特征映射(而不僅僅是2個)將它們堆疊在一起,形成一個4×4×10的輸出圖像,也就是 a[1]a^{\left\lbrack1 \right\rbrack}a[1]。
為了加深理解,來做一個練習。
假設現在有10個過濾器,而不是2個,神經網絡的一層是3×3×3,那么,這一層有多少個參數呢???
來一起計算一下,每一層都是一個3×3×3的矩陣,因此每個過濾器有27個參數,也就是27個數,然后加上一個偏差,用參數 bbb 表示,現在參數增加到28個,有10個過濾器,即28×10,也就是280個參數。不過,請注意一點,不論輸入圖片有多大,1000×1000也好,5000×5000也好,參數始終都是280個,即使這些圖片很大,參數卻很少,這就是卷積神經網絡的一個特征,叫作 避免過擬合。
避免過擬合的方式看這里:深度學習入門筆記(十):正則化。
5、總結
最后總結一下用于描述卷積神經網絡中的一層(以 lll 層為例),也就是卷積層的各種標記:
這一層是卷積層,用 f[l]f^{[l]}f[l] 表示過濾器大小,上標 [l]\lbrack l\rbrack[l] 用來標記 lll 層,上標 [l]\lbrack l\rbrack[l] 表示 lll 層中過濾器大小為 f×ff×ff×f;用 p[l]p^{[l]}p[l] 來標記 padding 的數量,valid 卷積,即無 padding,same 卷積,即選定 padding;用 s[l]s^{[l]}s[l] 標記步幅。
這一層的輸入會是某個維度的數據,表示為 n×n×ncn \times n \times n_{c}n×n×nc?,ncn_{c}nc? 表示某層上的顏色通道數。只要稍作修改,增加上標 [l?1]\lbrack l -1\rbrack[l?1],即 n[l?1]×n[l?1]×nc[l?1]n^{\left\lbrack l - 1 \right\rbrack} \times n^{\left\lbrack l -1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack}n[l?1]×n[l?1]×nc[l?1]?,就變成了上一層的激活值。
使用圖片的高度和寬度可以都一樣,但也有可能不同,所以分別用上下標 HHH 和 WWW 來標記,即 nH[l?1]×nW[l?1]×nc[l?1]n_{H}^{\left\lbrack l - 1 \right\rbrack} \times n_{W}^{\left\lbrack l - 1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack}nH[l?1]?×nW[l?1]?×nc[l?1]?,lll 層的輸入就是上一層的輸出,因此上標是 [l?1]\lbrack l - 1\rbrack[l?1],這一層中會有輸出(圖像),其大小為 nH[l]×nW[l]×nc[l]n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}nH[l]?×nW[l]?×nc[l]?。計算方式前面提到過,至少給出了高度和寬度,?n+2p?fs+1?\lfloor\frac{n+2p - f}{s} + 1\rfloor?sn+2p?f?+1?(注意:n+2p?fs+1\frac{n + 2p - f}{s} +1sn+2p?f?+1 直接用這個運算結果,也可以向下取整)。
那么通道數量又是什么?這些數字從哪兒來的?
輸出圖像也具有深度,等于該層中過濾器的數量,就是輸入通道數量,所以過濾器維度等于 f[l]×f[l]×nc[l?1]f^{[l]} \times f^{[l]} \times n_{c}^{\left\lbrack l - 1 \right\rbrack}f[l]×f[l]×nc[l?1]?。應用偏差和非線性函數之后,這一層的輸出等于它的激活值 a[l]a^{[l]}a[l](三維體),即 nH[l]×nW[l]×nc[l]n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}nH[l]?×nW[l]?×nc[l]?。當執行批量梯度下降或小批量梯度下降時,如果有 mmm 個例子,就是有 mmm 個激活值的集合,那么輸出 A[l]=m×nH[l]×nW[l]×nc[l]A^{[l]} = m \times n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}A[l]=m×nH[l]?×nW[l]?×nc[l]?。
該如何確定權重參數,即參數W呢?
過濾器的維度已知,為 f[l]×f[l]×nc[l?1]f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]}f[l]×f[l]×nc[l?1]?,這只是一個過濾器的維度,如果是多個,nc[l]n_{c}^{[l]}nc[l]? 是過濾器的數量,權重也就是所有過濾器的集合再乘以過濾器的總數量,即 f[l]×f[l]×nc[l?1]×nc[l]f^{[l]} \times f^{[l]} \times n_{c}^{[l - 1]} \times n_{c}^{[l]}f[l]×f[l]×nc[l?1]?×nc[l]?。
最后看看偏差參數,每個過濾器都有一個偏差參數(實數),它是某維度上的一個向量,為了方便,在代碼中常常表示為一個1×1×1×nc[l]n_{c}^{[l]}nc[l]? 的四維向量或四維張量。
推薦閱讀
- 深度學習入門筆記(一):深度學習引言
- 深度學習入門筆記(二):神經網絡基礎
- 深度學習入門筆記(三):求導和計算圖
- 深度學習入門筆記(四):向量化
- 深度學習入門筆記(五):神經網絡的編程基礎
- 深度學習入門筆記(六):淺層神經網絡
- 深度學習入門筆記(七):深層神經網絡
- 深度學習入門筆記(八):深層網絡的原理
- 深度學習入門筆記(九):深度學習數據處理
- 深度學習入門筆記(十):正則化
- 深度學習入門筆記(十一):權重初始化
- 深度學習入門筆記(十二):深度學習數據讀取
- 深度學習入門筆記(十三):批歸一化(Batch Normalization)
- 深度學習入門筆記(十四):Softmax
- 深度學習入門筆記(十五):深度學習框架(TensorFlow和Pytorch之爭)
- 深度學習入門筆記(十六):計算機視覺之邊緣檢測
- 深度學習入門筆記(十七):深度學習的極限在哪?
- 深度學習入門筆記(十八):卷積神經網絡(一)
- 深度學習入門筆記(十九):卷積神經網絡(二)
- 深度學習入門筆記(二十):經典神經網絡(LeNet-5、AlexNet和VGGNet)
參考文章
- 吳恩達——《神經網絡和深度學習》視頻課程
總結
以上是生活随笔為你收集整理的深度学习入门笔记(十八):卷积神经网络(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 广告秘籍
- 下一篇: 如何更高效、系统地学习3D视觉?