第五章 卷積神經網絡(CNN)

文章目錄


# 第五章 卷積神經網絡(CNN)

標籤(空格分隔): 原創性 深度學習 協作
卷積神經網絡負責人:

重慶大學研究生-劉暢 [email protected]

鉿星創新科技聯合創始人-楊文英;

Markdown Revision 1;
Date: 2018/11/08
Editor: 李驍丹-杜克大學
Contact: [email protected]

5.1 卷積神經網絡的組成層

在卷積神經網絡中,一般包含5種類型的層:

  • 輸入層
  • 卷積運算層
  • 激活函數層
  • 池化層
  • 全連接層

輸入層主要包含對原始圖像進行預處理,包括白化、歸一化、去均值等等。

卷積運算層主要使用濾波器,通過設定步長、深度等參數,對輸入進行不同層次的特徵提取。濾波器中的參數可以通過反向傳播算法進行學習。

激活函數層主要是將卷積層的輸出做一個非線性映射。常見的激活函數包括sigmoid,tanh,Relu等。

池化層主要是用於參數量壓縮。可以減輕過擬合情況。常見的有平均池化和最大值池化,不包含需要學習的參數。

全連接層主要是指兩層網絡,所有神經元之間都有權重連接。常見用於網絡的最後一層,用於計算類別得分。

5.2 卷積如何檢測邊緣信息?

卷積運算是卷積神經網絡最基本的組成部分。在神經網絡中,以物體識別爲例,特徵的檢測情況可大致做一下劃分。前幾層檢測到的是一些邊緣特徵,中間幾層檢測到的是物體的局部區域,靠後的幾層檢測到的是完整物體。每個階段特徵的形成都是由多組濾波器來完成的。而其中的邊緣檢測部分是由濾波器來完成的。在傳統的圖像處理方法裏面,有許多邊緣檢測算子,如canny算子。使用固定的模板來進行邊緣檢測。

先介紹一個概念,過濾器:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-5L2WbXxr-1575791353257)(./img/ch5/img2.png)]

這是一個3*3的過濾器,是一個矩陣,數值如上所示。

假設我們有一個6*6的灰度圖像:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-VhIgyP6o-1575791353258)(./img/ch5/img3.png)]

把這個圖像與過濾器進行卷積運算,卷積運算在此處用“*”表示。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-I08h0IVQ-1575791353259)(./img/ch5/img4.png)]

如圖深藍色區域所示,過濾器在圖像左上方3*3的範圍內,逐一加權相加,得到-5。

同理,將過濾器右移進行相同操作,再下移,直到過濾器對準圖像右下角最後一格。依次運算得到一個4*4的矩陣。

在瞭解了過濾器以及卷積運算後,讓我們看看爲何過濾器能檢測物體邊緣:

舉一個最簡單的例子:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Fvf94pAd-1575791353261)(./img/ch5/img5.png)]

這張圖片如上所示,左半邊全是白的,右半邊全是灰的,我們仍然使用之前的過濾器,對該圖片進行卷積處理:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7pbFJE9f-1575791353262)(./img/ch5/img6.png)]

可以看到,最終得到的結果中間是一段白色,兩邊爲灰色,於是垂直邊緣被找到了。爲什麼呢?因爲在6*6圖像中紅框標出來的部分,也就是圖像中的分界線所在部分,與過濾器進行卷積,結果是30。而在不是分界線的所有部分進行卷積,結果都爲0.

在這個圖中,白色的分界線很粗,那是因爲6*6的圖像尺寸過小,對於1000*1000的圖像,我們會發現在最終結果中,分界線較細但很明顯。

這就是檢測物體垂直邊緣的例子,水平邊緣的話只需將過濾器旋轉90度。

5.3 卷積層中的幾個基本參數?

在卷積層中,有一些我們常用的參數,定義如下

5.3.1 卷積核大小

英文名是Kernel Size:卷積核的大小定義了卷積的感受野。二維卷積的核大小選擇通常是3,即3×3。

5.3.2 卷積核的步長

英文名是Stride: Stride定義了卷積核在卷積過程中的步長。雖然它的默認值通常爲1,但我們可以將步長設置爲2,可以實現類似於pooling的下采樣功能。

5.3.3 邊緣填充

英文名是Padding: Padding用於填充輸入圖像的邊界。一個(半)填充的卷積將使空間輸出維度與輸入相等,而如果卷積核大於1,則對於未被填充的圖像,卷積後將會使圖像一些邊界消失。

5.3.4 輸入和輸出通道

英文名是 Input/Output Channels 一個卷積層接受一定數量的輸入通道I,並計算一個特定數量的輸出通道O,這一層所需的參數可以由IOK計算,K等於卷積核中參數的數量。

5.4 卷積的網絡類型分類?

5.4.1 普通卷積

普通卷積即如下圖所示,使用一個固定大小的濾波器,對圖像進行加權提特徵。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dABymeyJ-1575791353264)(./img/ch5/img7.png)]

5.4.2 擴張卷積

擴張卷積,又稱爲帶孔(atrous)卷積或者空洞(dilated)卷積。在使用擴張卷積時,會引入一個稱作擴張率(dilation rate)的參數。該參數定義了卷積核內參數間的行(列)間隔數。例如下圖所示,一個3×3的卷積核,擴張率爲2,它的感受野與5×5卷積核相同,而僅使用9個參數。這樣做的好處是,在參數量不變的情況下,可以獲得更大的感受野。擴張卷積在實時分割領域應用非常廣泛。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DTsMxIN6-1575791353265)(./img/ch5/img8.png)]

5.4.3 轉置卷積

轉置卷積也就是反捲積(deconvolution)。雖然有些人經常直接叫它反捲積,但嚴格意義上講是不合適的,因爲它不符合一個反捲積的概念。反捲積確實存在,但它們在深度學習領域並不常見。一個實際的反捲積會恢復卷積的過程。想象一下,將一個圖像放入一個卷積層中。現在把輸出傳遞到一個黑盒子裏,然後你的原始圖像會再次出來。這個黑盒子就完成了一個反捲積。這是一個卷積層的數學逆過程。

一個轉置的卷積在某種程度上是相似的,因爲它產生的空間分辨率是跟反捲積後產生的分辨率相同。不同之處是在卷積核值上執行的實際數學操作。轉置卷積層使用的是常規的卷積,但是它能夠恢復其空間變換。

在這一點上,讓我們來看一個具體的例子:
將5×5的圖像送到一個卷積層。步長設置爲2,無邊界填充,而卷積核是3×3。結果得到了2×2的圖像。如果我們想要逆向該過程,則需要數學上的逆運算,以便從輸入的每個像素值中生成9個值。然後,我們將步長設置爲2來遍歷輸出圖像。這就是一個反捲積過程。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-M8t7OL12-1575791353266)(./img/ch5/img9.png)]
轉置卷積的實現過程則不同。爲了保證輸出將是一個5×5的圖像,在使用卷積運算時,我們需要在輸入上執行一些特別的填充。而這一過程並不是逆轉了卷積運算,它僅僅是重新構造了之前的空間分辨率並進行了卷積運算。這樣的做法並不是數學上的逆過程,但是很適用於編碼-解碼器(Encoder-Decoder)架構。我們就可以把圖像的上採樣(upscaling)和卷積操作結合起來,而不是做兩個分離的過程。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-medhCRHH-1575791353266)(./img/ch5/img10.png)]

5.4.4 可分離卷積

在一個可分離卷積中,我們可以將內核操作拆分成多個步驟。我們用y = conv(x,k)表示卷積,其中y是輸出圖像,x是輸入圖像,k是核大小。這一步很簡單。接下來,我們假設k可以由下面這個等式計算得出:k = k1.dot(k2)。這將使它成爲一個可分離的卷積,因爲我們可以通過對k1和k2做2個一維卷積來取得相同的結果,而不是用k做二維卷積。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-t22c3qGd-1575791353267)(./img/ch5/img11.png)]

以圖像處理中的Sobel算子爲例。你可以通過乘以向量[1,0,-1]和[1,2,1] .T獲得相同的核大小。在執行相同的操作時,你只需要6個參數,而不是9個。上面的示例顯示了所謂的空間可分離卷積。即將一個二維的卷積分離成兩個一維卷積的操作。在神經網絡中,爲了減少網絡參數,加速網絡運算速度。我們通常使用的是一種叫深度可分離卷積的神經網絡。

5.5 圖解12種不同類型的2D卷積?

http://www.sohu.com/a/159591827_390227

5.6 2D卷積與3D卷積有什麼區別?

5.6.1 2D卷積

二維卷積操作如圖所示,爲了更直觀的說明,分別展示了單通道和多通道的操作。假定只使用了1個濾波器,即輸出圖像只有一個channel。其中,針對單通道,輸入圖像的channel爲1,卷積核尺寸爲 (k_h, k_w, 1),卷積核在輸入圖像的空間維度上進行滑窗操作,每次滑窗和 (k_h, k_w)窗口內的值進行卷積操作,得到輸出圖像中的一個值。針對多通道,假定輸入圖像的channel爲3,卷積核尺寸則爲 (k_h, k_w, 3),則每次滑窗與3個channels上的 (k_h, k_w)窗口內的所有值進行卷積操作,得到輸出圖像中的一個值。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-SI3quMEM-1575791353268)(./img/ch5/img12.png)]

5.6.2 3D卷積

3D卷積操作如圖所示,同樣分爲單通道和多通道,且假定只使用1個濾波器,即輸出圖像僅有一個channel。其中,針對單通道,與2D卷積不同之處在於,輸入圖像多了一個length維度,卷積核也多了一個k_l維度,因此3D卷積核的尺寸爲(k_h, k_w, k_l),每次滑窗與 (k_h, k_w, k_l)窗口內的值進行相關操作,得到輸出3D圖像中的一個值.針對多通道,則與2D卷積的操作一樣,每次滑窗與3個channels上的 (k_h, k_w, k_l) 窗口內的所有值進行相關操作,得到輸出3D圖像中的一個值。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-AxxqwJDu-1575791353268)(./img/ch5/img13.png)]

5.7 有哪些池化方法?

在構建卷積神經網絡時,經常會使用池化操作,而池化層往往在卷積層後面,通過池化操作來降低卷積層輸出的特徵維度,同時可以防止過擬合現象。池化操作可以降低圖像維度的原因,本質上是因爲圖像具有一種“靜態性”的屬性,這個意思是說在一個圖像區域有用的特徵極有可能在另一個區域同樣有用。因此,爲了描述一個大的圖像,很直觀的想法就是對不同位置的特徵進行聚合統計。例如,可以計算圖像在固定區域上特徵的平均值 (或最大值)來代表這個區域的特徵。[1]

5.7.1 一般池化(General Pooling)

池化操作與卷積操作不同,過程如下圖。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-KxGCDeB9-1575791353269)(./img/ch5/img14.png)]
池化操作過程如圖所示,對固定區域的特徵,使用某一個值來表示。最常見的池化操作有兩種,分爲平均池化mean pooling和最大池化max pooling

1、平均池化:計算圖像區域的平均值作爲該區域池化後的值。

2、最大池化:選圖像區域的最大值作爲該區域池化後的值。

上述的池化過程,相鄰的池化窗口間沒有重疊部分。

5.7.2 重疊池化(General Pooling)

重疊池化即是一種相鄰池化窗口之間會有重疊區域的池化技術。論文中[2]中,作者使用了重疊池化,其他的設置都不變的情況下,top-1和top-5 的錯誤率分別減少了0.4% 和0.3%。

5.7.3 空金字塔池化(Spatial Pyramid Pooling)

空間金字塔池化可以將任意尺度的圖像卷積特徵轉化爲相同維度,這不僅可以讓CNN處理任意尺度的圖像,還能避免cropping和warping操作,導致一些信息的丟失。一般的卷積神經網絡都需要固定輸入圖像大小,這是因爲全連接層的輸入需要固定輸入維度,但在卷積操作時並沒有對圖像大小有限制,所以作者提出了空間金字塔池化方法,先讓圖像進行卷積操作,然後使用SPP方法轉化成維度相同的特徵,最後輸入到全連接層。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-U0WrtRK4-1575791353270)(./img/ch5/img17.png)]

根據論文作者所述,空間金字塔池化的思想來自於Spatial Pyramid Model,它是將一個pooling過程變成了多個尺度的pooling。用不同大小的池化窗口作用於卷積特徵,這樣就可以得到1X1,2X2,4X4的池化結果,由於conv5中共有256個濾波器,所以得到1個256維的特徵,4個256個特徵,以及16個256維的特徵,然後把這21個256維特徵鏈接起來輸入全連接層,通過這種方式把不同大小的圖像轉化成相同維度的特徵。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Kn3CEUvR-1575791353271)(./img/ch5/img18.png)]

對於不同的圖像,如果想要得到相同大小的pooling結果,就需要根據圖像大小動態的計算池化窗口大小和步長。假設conv5輸出的大小爲aa,需要得到nn大小的池化結果,可以讓窗口大小sizeX爲[a/n],步長爲[a/n]。下圖展示了以conv5輸出大小是13*13爲例,spp算法的各層參數。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PMjl2Nm0-1575791353271)(./img/ch5/img19.png)]

總結來說,SPP方法其實就是一種使用多個尺度的池化方法,可以獲取圖像中的多尺度信息。在卷積神經網絡中加入SPP後,可以讓CNN處理任意大小的輸入,這讓模型變得更加的靈活。

5.8 1x1卷積作用?

1×1的卷積主要有以下兩個方面的作用:

  1. 實現信息的跨通道交互和整合。

  2. 對卷積核通道數進行降維和升維,減小參數量。

下面詳細解釋一下:
第一點 實現信息的跨通道交互和整合
對1×1卷積層的探討最初是出現在NIN的結構,論文作者的動機是利用MLP代替傳統的線性卷積核,從而提高網絡的表達能力。文中從跨通道池化的角度進行解釋,認爲文中提出的MLP其實等價於在傳統卷積核後面接cccp層,從而實現多個feature map的線性組合,實現跨通道的信息整合。而查看代碼實現,cccp層即等價於1×1卷積層。
第二點 對卷積核通道數進行降維和升維,減小參數量
1x1卷積層能帶來降維和升維的效果,在一系列的GoogLeNet中體現的最明顯。對於每一個Inception模塊(如下圖),左圖是原始模塊,右圖是加入1×1卷積進行降維的模塊。雖然左圖的卷積核都比較小,但是當輸入和輸出的通道數很大時,卷積核的參數量也會變的很大,而右圖加入1×1卷積後可以降低輸入的通道數,因此卷積核參數、運算複雜度也就大幅度下降。以GoogLeNet的3a模塊爲例,輸入的feature map是28×28×192,3a模塊中1×1卷積通道爲64,3×3卷積通道爲128,5×5卷積通道爲32,如果是左圖結構,那麼卷積核參數爲1×1×192×64+3×3×192×128+5×5×192×32,而右圖對3×3和5×5卷積層前分別加入了通道數爲96和16的1×1卷積層,這樣卷積核參數就變成了1×1×192×64+(1×1×192×96+3×3×96×128)+(1×1×192×16+5×5×16×32),參數大約減少到原來的三分之一。同時在並行pooling層後面加入1×1卷積層後也可以降低輸出的feature map數量,左圖pooling後feature map是不變的,再加捲積層得到的feature map,會使輸出的feature map擴大到416,如果每個模塊都這樣,網絡的輸出會越來越大。而右圖在pooling後面加了通道數爲32的1×1卷積,使得輸出的feature map數降到了256。GoogLeNet利用1×1的卷積降維後,得到了更爲緊湊的網絡結構,雖然總共有22層,但是參數數量卻只是8層AlexNet的十二分之一,當然其中也有丟掉全連接層的原因。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tZ8aXfUS-1575791353272)(./img/ch5/img20.png)]
而非常經典的ResNet結構,同樣也使用了1×1卷積,並且是在3×3卷積層的前後都使用了,不僅進行了降維,還進行了升維,使得卷積層的輸入和輸出的通道數都減小,參數數量進一步減少,如下圖結構所示。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Hvm8I4jT-1575791353273)(./img/ch5/img21.png)]

5.9 卷積層和池化層有什麼區別?

首先可以從結構上可以看出,卷積之後輸出層的維度減小,深度變深。但池化層深度不變。同時池化可以把很多數據用最大值或者平均值代替。目的是降低數據量。降低訓練的參數。對於輸入層,當其中像素在鄰域發生微小位移時,池化層的輸出是不變的,從而能提升魯棒性。而卷積則是把數據通過一個卷積核變化成特徵,便於後面的分離。

1:卷積

當從一個大尺寸圖像中隨機選取一小塊,比如說 8x8 作爲樣本,並且從這個小塊樣本中學習到了一些特徵,這時我們可以把從這個 8x8 樣本中學習到的特徵作爲探測器,應用到這個圖像的任意地方中去。特別是,我們可以用從 8x8 樣本中所學習到的特徵跟原本的大尺寸圖像作卷積,從而對這個大尺寸圖像上的任一位置獲得一個不同特徵的激活值。

下面給出一個具體的例子:假設你已經從一個 96x96 的圖像中學習到了它的一個 8x8 的樣本所具有的特徵,假設這是由有 100 個隱含單元的自編碼完成的。爲了得到卷積特徵,需要對 96x96 的圖像的每個 8x8 的小塊圖像區域都進行卷積運算。也就是說,抽取 8x8 的小塊區域,並且從起始座標開始依次標記爲(1,1),(1,2),…,一直到(89,89),然後對抽取的區域逐個運行訓練過的稀疏自編碼來得到特徵的激活值。在這個例子裏,顯然可以得到 100 個集合,每個集合含有 89x89 個卷積特徵。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JxyW8SFA-1575791353274)(./img/ch5/img22.png)]

2:說下池化,其實池化很容易理解,先看圖:

轉自: http://blog.csdn.net/silence1214/article/details/11809947

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-bUS6W2Mp-1575791353274)(./img/ch5/img23.png)]

比如上方左側矩陣A是2020的矩陣要進行大小爲1010的池化,那麼左側圖中的紅色就是10*10的大小,對應到右側的矩陣,右側每個元素的值,是左側紅色矩陣每個元素的值得和再處於紅色矩陣的元素個數,也就是平均值形式的池化。

3:上面說了下卷積和池化,再說下計算中需要注意到的。在代碼中使用的是彩色圖,彩色圖有3個通道,那麼對於每一個通道來說要單獨進行卷積和池化,有一個地方尤其是進行卷積的時候要注意到,隱藏層的每一個值是對應到一幅圖的3個通道穿起來的,所以分3個通道進行卷積之後要加起來,正好才能對應到一個隱藏層的神經元上,也就是一個feature上去。

5.10 卷積核是否一定越大越好?

首先,給出答案。不是。
在AlexNet網絡結構中,用到了一些非常大的卷積核,比如11×11、5×5卷積核。之前研究者的想法是,卷積核越大,receptive field(感受野)越大,因此獲得的特徵越好。雖說如此,但是大的卷積核會導致計算量大幅增加,不利於訓練更深層的模型,而相應的計算性能也會降低。於是在VGG、Inception網絡中,實驗發現利用2個3×3卷積核的組合比1個5×5卷積核的效果更佳,同時參數量(3×3×2+1 VS 5×5×1+1)會更少,因此後來3×3卷積核被廣泛應用在各種模型中。

多個小卷積核的疊加使用遠比一個大卷積核單獨使用效果要好的多,在連通性不變的情況下,大大降低了參數量和計算複雜度。當然,卷積核也不是越小越好,對於特別稀疏的數據,當使用比較小的卷積核的時候可能無法表示其特徵,如果採用較大的卷積核則會導致複雜度極大的增加。

總而言之,我們多傾向於選擇多個相對小的卷積核來進行卷積。

5.11 每層卷積是否只能用一種尺寸的卷積核?

經典的神經網絡,都屬於層疊式網絡,並且每層僅用一個尺寸的卷積核,例如VGG結構中使用了大量的3×3卷積層。事實上,同一層feature map可以分別使用多個不同尺寸的卷積核,以獲得不同尺度的特徵,再把這些特徵結合起來,得到的特徵往往比使用單一卷積核的要好,例如GoogLeNet、Inception系列的網絡,均是每層使用了多個卷積核結構。如下圖所示,輸入的feature map在同一層,分別經過1×1、3×3、5×5三種不同尺寸的卷積核,再將分別得到的特徵進行組合。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YOoBCROy-1575791353275)(./img/ch5/img24.png)]

5.12 怎樣才能減少卷積層參數量?

發明GoogleNet的團隊發現,如果僅僅引入多個尺寸的卷積核,會帶來大量的額外的參數,受到Network In Network中1×1卷積核的啓發,爲了解決這個問題,他們往Inception結構中加入了一些1×1的卷積核,如圖所示:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-UNDbEarU-1575791353276)(./img/ch5/img25.png)]

加入1×1卷積核的Inception結構

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-qtU9SggL-1575791353277)(./img/ch5/img26.png)]

根據上圖,我們來做個對比計算,假設輸入feature map的維度爲256維,要求輸出維度也是256維。有以下兩種操作:

  • (1)256維的輸入直接經過一個3×3×256的卷積層,輸出一個256維的feature map,那麼參數量爲:256×3×3×256 = 589,824
  • (2)256維的輸入先經過一個1×1×64的卷積層,再經過一個3×3×64的卷積層,最後經過一個1×1×256的卷積層,輸出256維,參數量爲:256×1×1×64 + 64×3×3×64 + 64×1×1×256 = 69,632。足足把第一種操作的參數量降低到九分之一!

1×1卷積核也被認爲是影響深遠的操作,往後大型的網絡爲了降低參數量都會應用上1×1卷積核。

5.13 在進行卷積操作時,必須同時考慮通道和區域嗎?

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lLraI7rQ-1575791353277)(./img/ch5/img27.png)]
標準的卷積過程可以看上圖,一個2×2的卷積核在卷積時,對應圖像區域中的所有通道均被同時考慮,那麼問題來了,爲什麼一定要同時考慮圖像區域和通道呢?能不能將通道和空間區域分開考慮?
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-V1cFXTDk-1575791353278)(./img/ch5/img28.png)]
Xception網絡由此誕生。我們首先對每一個通道進行各自的卷積操作,有多少個通道就有多少個過濾器。得到新的通道feature maps之後,這時再對這批新的通道feature maps進行標準的1×1跨通道卷積操作。這種操作被稱爲 “DepthWise convolution”,稱爲深度可分離卷積。在imagenet 1000類分類任務中取得了非常魯棒的效果,同時也減少了大量的參數。我們可以通過一個例子來算一算,使用深度可分離卷積,能d假設輸入通道數爲3,要求輸出通道數爲256。

  1. 使用標準的卷積操作,使用3×3×256的卷積核,參數量爲:3×3×3×256 = 6,912
  2. 使用深度可分離的結構,分兩步完成。參數量爲:3×3×3 + 3×1×1×256 = 795。
    參數量僅爲標準卷積的九分之一! 因此,使用depthwise操作比標準的卷積操作,在降低不少參數量的同時,得到了更好的分類效果。

5.14 採用寬卷積的好處有什麼?

5.14.1 窄卷積和寬卷積

對於窄卷積來說,是從第一個點開始做卷積,每次窗口滑動固定步幅。比如下圖左部分爲窄卷積。那麼注意到越在邊緣的位置被卷積的次數越少。於是有了寬卷積的方法,可以看作在卷積之前在邊緣用0補充,常見有兩種情況,一個是全補充,入下圖右部分,這樣輸出大於輸入的維度。另一種常用的方法是補充一部0值,使得輸出和輸入的維度一致。這裏文中給了一個公式 。這裏npadding在全補充裏是filter-1,在輸入輸出相等時,就要主要奇偶性了,注意到卷積核常爲奇數。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-p254xY9S-1575791353279)(./img/ch5/img29.png)]

5.14.2 爲什麼採用寬卷積?

通過將輸入邊角的值納入到滑窗中心進行計算,以便損失更少的信息。

5.15 在卷積操作後,輸出特徵圖(圖像)大小如何計算?

在進行卷積操作時,往往根據需要,我們需設定一些參數。常見的參數有卷積核大小k, 窗口滑動的步長s, 進行填充的像素p, 假設輸入特徵圖大小爲Iw*Iw。則由以下公式可計算出輸出特徵圖的大小Ow。

O_w = \frac{(I_w - k + 2p))}{s} + 1

5.16 如何得到卷積層輸出的深度?

參數共享:在卷積層中使用參數共享是用來控制參數的數量。假設在第一個卷積層就有55x55x96=290,400個神經元,每個有11x11x3=364個參數和1個偏差。將這些合起來就是290400x364=105,705,600個參數。單單第一層就有這麼多參數,顯然這個數目是非常大的。

作一個合理的假設:如果一個特徵在計算某個空間位置(x,y)的時候有用,那麼它在計算另一個不同位置(x2,y2)的時候也有用。基於這個假設,可以顯著地減少參數數量。換言之,就是將深度維度上一個單獨的2維切片看做深度切片(depth slice),比如一個數據體尺寸爲[55x55x96]的就有96個深度切片,每個尺寸爲[55x55]。在每個深度切片上的神經元都使用同樣的權重和偏差。在這樣的參數共享下,例子中的第一個卷積層就只有96個不同的權重集了,一個權重集對應一個深度切片,共有96x11x11x3=34,848個不同的權重,或34,944個參數(+96個偏差)。

w_conv1=weight_variable([5,5,1,32])

可以看出,上面的32表示的是卷積層輸出的深度,因爲大家都明白width和height都可以通過公式計算得到,但是很多文獻都沒有告訴深度是如何得到的,下面是我的認識:

  1. 因爲這個深度是沒有公式可以計算出來的,因爲深度是一個經驗值,如上面代碼的32 ,其實是一個經驗值,是通過調整參數發現32是一個最合適的值,可以得到最好的準確率,但是不同的圖像的深度是不一樣的。
  2. 這個深度表示用了多少個卷積核,下面這個圖可以說明一下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iOwBmI6k-1575791353280)(./img/ch5/img30.png)]

上圖就可以很有效的說明 :卷積層輸出的深度==卷積核的個數。

5.17 激活函數通常放在卷積神經網絡的哪個操作之後?

通常放在卷積層之後。

5.18 如何理解最大池化層有幾分縮小?

池化層:對輸入的特徵圖進行壓縮,一方面使特徵圖變小,簡化網絡計算複雜度;一方面進行特徵壓縮,提取主要特徵。

池化操作一般有兩種,一種是Avy Pooling,一種是max Pooling。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-80qY4qmT-1575791353280)(./img/ch5/img31.png)]

同樣地採用一個2*2的filter,max pooling是在每一個區域中尋找最大值,這裏的stride=2,最終在原特徵圖中提取主要特徵得到右圖。

注1:(Avy pooling現在不怎麼用了,方法是對每一個22的區域元素求和,再除以4,得到主要特徵),而一般的filter取22,最大取3*3,stride取2,壓縮爲原來的1/4.
注2:這裏的pooling操作是特徵圖縮小,有可能影響網絡的準確度,因此可以通過增加特徵圖的深度來彌補。

5.19 理解圖像卷積與反捲積

5.19.1 圖像卷積

首先給出一個輸入輸出結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZfB0AYMM-1575791353281)(./img/ch5/img32.png)]

那他是怎樣計算的呢?

卷積的時候需要對卷積核進行180的旋轉,同時卷積核中心與需計算的圖像像素對齊,輸出結構爲中心對齊像素的一個新的像素值,計算例子如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ap3myoq3-1575791353282)(./img/ch5/img33.png)]

這樣計算出左上角(即第一行第一列)像素的卷積後像素值。

給出一個更直觀的例子,從左到右看,原像素經過卷積由1變成-8。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-138sP9aU-1575791353283)(./img/ch5/img34.png)]

通過滑動卷積核,就可以得到整張圖片的卷積結果

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EeMA2nI2-1575791353283)(./img/ch5/img35.png)]

5.19.2 圖像反捲積

這裏提到的反捲積跟1維信號處理的反捲積計算是很不一樣的,FCN作者稱爲backwards convolution,有人稱Deconvolution layer is a very unfortunate name and should rather be called a transposed convolutional layer. 我們可以知道,在CNN中有con layer與pool layer,con layer進行對圖像卷積提取特徵,pool layer 對圖像縮小一半篩選重要特徵,對於經典的圖像識別CNN網絡,如IMAGENET,最後輸出結果是1X1X1000,1000是類別種類,1x1得到的是。FCN作者,或者後來對end to end研究的人員,就是對最終1x1的結果使用反捲積(事實上FCN作者最後的輸出不是1X1,是圖片大小的32分之一,但不影響反捲積的使用)。

這裏圖像的反捲積與full卷積原理是一樣的,使用了這一種反捲積手段使得圖像可以變大,FCN作者使用的方法是這裏所說反捲積的一種變體,這樣就可以獲得相應的像素值,圖像可以實現end to end。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-j3TdISgh-1575791353284)(./img/ch5/img36.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-XbuPDZEZ-1575791353285)(./img/ch5/img37.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-PcSrrxxB-1575791353286)(./img/ch5/img38.png)]

這裏說另外一種反捲積做法,假設原圖是33,首先使用上採樣讓圖像變成77,可以看到圖像多了很多空白的像素點。使用一個33的卷積覈對圖像進行滑動步長爲1的valid卷積,得到一個55的圖像,我們知道的是使用上採樣擴大圖片,使用反捲積填充圖像內容,使得圖像內容變得豐富,這也是CNN輸出end to end結果的一種方法。韓國作者Hyeonwoo Noh使用VGG16層CNN網絡後面加上對稱的16層反捲積與上採樣網絡實現end to end 輸出,其不同層上採樣與反捲積變化效果如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-x3wNyMRq-1575791353286)(./img/ch5/img39.png)]

經過上面的解釋與推導,對卷積有基本的瞭解,但是在圖像上的deconvolution究竟是怎麼一回事,可能還是不能夠很好的理解,因此這裏再對這個過程解釋一下。 目前使用得最多的deconvolution有2種,上文都已經介紹。

  • 方法1:full卷積, 完整的卷積可以使得原來的定義域變大。
  • 方法2:記錄pooling index,然後擴大空間,再用卷積填充。

圖像的deconvolution過程如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Gd0uZ89e-1575791353287)(./img/ch5/img40.png)]

輸入:2x2, 卷積核:4x4, 滑動步長:3, 輸出:7x7

即輸入爲2x2的圖片經過4x4的卷積核進行步長爲3的反捲積的過程

  1. 輸入圖片每個像素進行一次full卷積,根據full卷積大小計算可以知道每個像素的卷積後大小爲 1+4-1=4, 即4x4大小的特徵圖,輸入有4個像素所以4個4x4的特徵圖
  2. 將4個特徵圖進行步長爲3的fusion(即相加); 例如紅色的特徵圖仍然是在原來輸入位置(左上角),綠色還是在原來的位置(右上角),步長爲3是指每隔3個像素進行fusion,重疊部分進行相加,即輸出的第1行第4列是由紅色特陣圖的第一行第四列與綠色特徵圖的第一行第一列相加得到,其他如此類推。

可以看出翻卷積的大小是由卷積核大小與滑動步長決定, in是輸入大小, k是卷積核大小, s是滑動步長, out是輸出大小 得到 out = (in - 1) * s + k 上圖過程就是, (2 - 1) * 3 + 4 = 7

5.20 不同卷積後圖像大小計算?

5.20.1 類型劃分

2維卷積的計算分爲了3類:1.full 2.same 3. valid

1、full

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-udDszegh-1575791353288)(./img/ch5/img41.png)]

藍色爲原圖像,白色爲對應卷積所增加的padding,通常全部爲0,綠色是卷積後圖片。圖6的卷積的滑動是從卷積核右下角與圖片左上角重疊開始進行卷積,滑動步長爲1,卷積核的中心元素對應卷積後圖像的像素點。可以看到卷積後的圖像是4X4,比原圖2X2大了,我們還記1維卷積大小是n1+n2-1,這裏原圖是2X2,卷積核3X3,卷積後結果是4X4,與一維完全對應起來了。其實這纔是完整的卷積計算,其他比它小的卷積結果都是省去了部分像素的卷積

2、same

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-FNQm9VGy-1575791353288)(./img/ch5/img42.png)]

3、valid

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cwidBKyL-1575791353289)(./img/ch5/img43.png)]

5.20.2 計算公式

這裏,我們可以總結出full,same,valid三種卷積後圖像大小的計算公式:

  1. full: 滑動步長爲1,圖片大小爲N1xN1,卷積核大小爲N2xN2,卷積後圖像大小:N1+N2-1 x N1+N2-1。
  2. same: 滑動步長爲1,圖片大小爲N1xN1,卷積核大小爲N2xN2,卷積後圖像大小:N1xN1。
  3. valid:滑動步長爲S,圖片大小爲N1xN1,卷積核大小爲N2xN2,卷積後圖像大小:(N1-N2)/S+1 x (N1-N2)/S+1。

5.21 步長、填充大小與輸入輸出關係總結?

在設計深度學習網絡的時候,需要計算輸入尺寸和輸出尺寸,那麼就要設計卷積層的的各種參數。這裏有一些設計時候的計算公式,方便得到各層的參數。

這裏簡化下,約定:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LqJt0YDC-1575791353290)(./img/ch5/img44.png)]

5.21.1 沒有0填充,單位步長

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rZbxCJaE-1575791353290)(./img/ch5/img45.png)]

5.21.2 零填充,單位步長

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-o2OxXcCM-1575791353291)(./img/ch5/img46.png)]

<1>半填充
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-woCs6fBl-1575791353292)(./img/ch5/img47.png)]

<2>全填充
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-90il76JY-1575791353293)(./img/ch5/img48.png)]

參考圖如下圖所示

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-3BovhLCi-1575791353294)(./img/ch5/img49.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-7Jnlt98s-1575791353294)(./img/ch5/img50.png)]

5.21.3 不填充,非單位步長

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-morI5TqG-1575791353295)(./img/ch5/img51.png)]

5.21.4 零填充,非單位步長

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NYsU7UKm-1575791353296)(./img/ch5/img52.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZW8P9AGX-1575791353297)(./img/ch5/img53.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wXTv8Nlc-1575791353297)(./img/ch5/img54.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BqDjcHOl-1575791353298)(./img/ch5/img55.png)]

http://blog.csdn.net/u011692048/article/details/77572024
https://arxiv.org/pdf/1603.07285.pdf

5.22 理解反捲積和棋盤效應

5.22.1 爲什麼出現棋盤現象?

圖像生成網絡的上採樣部分通常用反捲積網絡,不合理的卷積核大小和步長會使反捲積操作產生棋盤效應 (checkerboard artifacts)。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wbshpTYN-1575791353299)(./img/ch5/img56.png)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-dJScQNDn-1575791353299)(./img/ch5/img57.png)]

重疊圖案也在二維中形成。兩個軸上的不均勻重疊相乘,產生不同亮度的棋盤狀圖案。

事實上,不均勻重疊往往在二維上更極端!因爲兩個模式相乘,所以它的不均勻性是原來的平方。例如,在一個維度中,一個步長爲2,大小爲3的反捲積的輸出是其輸入的兩倍,但在二維中,輸出是輸入的4倍。

現在,生成圖像時,神經網絡通常使用多層反捲積,從一系列較低分辨率的描述中迭代建立更大的圖像。雖然這些堆棧的反捲積可以消除棋盤效應,但它們經常混合,在更多尺度上產生棋盤效應。

直觀地看,假設生成的圖像中包含1只黑貓。黑貓身體部分的像素顏色應平滑過渡,或極端地說,該部分應全爲黑色。實際生成的圖像中該部分卻有深深淺淺的近黑方塊組成,很像棋盤的網格,即棋盤效應。

https://distill.pub/2016/deconv-checkerboard/
http://blog.csdn.net/shadow_guo/article/details/52862161

5.22.2 有哪些方法可以避免棋盤效應?

(1)第一種方法是用到的反捲積核的大小可被步長整除,從而避免重疊效應。與最近成功用於圖像超分辨率的技術“子像素卷積”(sub-pixel convolution)等價。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-G4gDas3w-1575791353300)(./img/ch5/img58.png)]

(2)另一種方法是從卷積操作中分離出對卷積後更高分辨率的特徵圖上採樣來計算特徵。例如,可以先縮放圖像(最近鄰插值或雙線性插值),再卷積。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-GIUyiL4K-1575791353301)(./img/ch5/img59.png)]

反捲積與不同縮放卷積方法都是線性操作,並可用矩陣去解釋。對於每個輸出窗口,反捲積操作的輸入唯一,縮放卷積會以阻礙高頻棋盤效應的方式來隱式地集中權重(weight-tying)。

縮放卷積

縮放卷積爲線性操作:假設原圖像爲A,經過插值後的圖像爲A+B;用卷積核C對插值縮放後的圖像卷積,得到最終的圖像 ,其中*爲卷積操作。則可將縮放卷積分解爲原圖像卷積和插值增量圖像卷積,或卷積的原圖像和卷積的插值增量圖像。

C爲卷積操作的卷積核。此時爲上採樣,理解爲反捲積操作中的卷積核。

(1)最近鄰縮放卷積

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-daVvNwHQ-1575791353301)(./img/ch5/img60.png)]

發現,插值增量圖像表示的矩陣爲原圖像表示的矩陣下移1行。可將原圖像矩陣看成環形隊列(隊列最後1行的輸出送入隊列的第1行)。

(2)雙線性縮放卷積

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-HDpiOH8Y-1575791353302)(./img/ch5/img61.png)]

發現,插值增量圖像可細分爲原圖像表示的矩陣下移1行後乘以1/2與原圖像表示的矩陣上移1行後乘以1/2。

5.23 CNN主要的計算瓶頸

CNN的訓練主要是在卷積層和子採樣層的交互上,其主要的計算瓶頸是:

  • 1)前向傳播過程:下采樣每個卷積層的maps;
  • 2)反向傳播過程:上採樣高層子採樣層的靈敏度map,以匹配底層的卷積層輸出maps的大小;
  • 3)sigmoid的運用和求導。

舉例:

對於第一和第二個問題,我們考慮的是如何用Matlab內置的圖像處理函數去實現上採樣和下采樣的操作。對於上採樣,imresize函數可以搞定,但需要很大的開銷。一個比較快速的版本是使用Kronecker乘積函數kron。通過一個全一矩陣ones來和我們需要上採樣的矩陣進行Kronecker乘積,就可以實現上採樣的效果。對於前向傳播過程中的下采樣,imresize並沒有提供在縮小圖像的過程中還計算nxn塊內像素的和的功能,所以沒法用。一個比較好和快速的方法是用一個全一的卷積核來卷積圖像,然後簡單的通過標準的索引方法來採樣最後卷積結果。例如,如果下采樣的域是2x2的,那麼我們可以用2x2的元素全是1的卷積核來卷積圖像。然後再卷積後的圖像中,我們每個2個點採集一次數據,y=x(1:2:end,1:2:end),這樣就可以得到了兩倍下采樣,同時執行求和的效果。

對於第三個問題,實際上有些人以爲Matlab中對sigmoid函數進行inline的定義會更快,其實不然,Matlab與C/C++等等語言不一樣,Matlab的inline反而比普通的函數定義更費時間。所以,我們可以直接在代碼中使用計算sigmoid函數及其導數的真實代碼。

5.24 卷積神經網絡的經驗參數設置

對於卷積神經網絡的參數設置,沒有很明確的指導原則,以下僅是一些經驗集合。

1、learning-rate 學習率:學習率越小,模型收斂花費的時間就越長,但是可以逐步穩健的提高模型精確度。一般初始設置爲0.1,然後每次除以0.2或者0.5來改進,得到最終值;

2、batch-size 樣本批次容量:影響模型的優化程度和收斂速度,需要參考你的數據集大小來設置,具體問題具體分析,一般使用32或64,在計算資源允許的情況下,可以使用大batch進行訓練。有論文提出,大batch可以加速訓練速度,並取得更魯棒的結果;

3、weight-decay 權重衰減:用來在反向傳播中更新權重和偏置,一般設置爲0.005或0.001;

4、epoch-number 訓練次數:包括所有訓練樣本的一個正向傳遞和一個反向傳遞,訓練至模型收斂即可;(注:和迭代次數iteration不一樣)
總之,不是訓練的次數越多,測試精度就會越高。會有各種原因導致過擬合,比如一種可能是預訓練的模型太複雜,而使用的數據集樣本數量太少,種類太單一。

5.25 提高泛化能力的方法總結(代碼示例)

本節主要以代碼示例來說明可以提高網絡泛化能力的方法。
代碼實驗是基於mnist數據集,mnist是一個從0到9的手寫數字集合,共有60000張訓練圖片,10000張測試圖片。每張圖片大小是28*28大小。目的就是通過各種手段,來構建一個高精度的分類神經網絡。

5.25.1 手段

一般來說,提高泛化能力的方法主要有以下幾個:

  • 使用正則化技術
  • 增加神經網絡層數
  • 使用恰當的代價函數
  • 使用權重初始化技術
  • 人爲增廣訓練集
  • 使用dropout技術

5.25.2 主要方法

下面我們通過實驗結果來判斷每種手段的效果。

(1)普通的全連接神經網絡
網絡結構使用一個隱藏層,其中包含100個隱藏神經元,輸入層是784,輸出層是one-hot編碼的形式,最後一層是Softmax層。損失函數採用對數似然代價函數,60次迭代,學習速率η=0.1,隨機梯度下降的小批量數據(mini-SGD)大小爲10,沒使用正則化。在測試集上得到的結果是97.8%,代碼如下:

>>> import network3 
>>> from network3 import Network 
>>> from network3 import ConvPoolLayer, FullyConnectedLayer, SoftmaxLayer 
>>> training_data, validation_data, test_data = network3.load_data_shared() 
>>> mini_batch_size = 10 
>>> net = Network([FullyConnectedLayer(n_in=784, n_out=100),
         SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size) 
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data)

(2)使用卷積神經網絡 — 僅一個卷積層
輸入層是卷積層,卷積核大小是55,一共20個特徵映射。最大池化層的大小爲22。後面接一層100個隱藏神經元的全連接層。結構如圖所示
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-otGsuEvE-1575791353303)(./img/ch5/img62.png)]
在這個結構中,我們把卷積層和池化層看做是訓練圖像的特徵提取,而後的全連接層則是一個更抽象層次的特徵提取,整合全局信息。同樣設定是60次迭代,批量數據大小是10,學習率是0.1.代碼如下,

>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2)),
        FullyConnectedLayer(n_in=20*12*12, n_out=100),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, 
            validation_data, test_data)

經過三次運行取平均後,準確率是98.78%,提高得較多。錯誤率降低了1/3。

(3)使用卷積神經網絡 — 兩個卷積層
我們接着插入第二個卷積層,把它插入在之前結構的池化層和全連接層之間,同樣是使用55的局部感受野,22的池化層。

>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2)),
        ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), 
                      filter_shape=(40, 20, 5, 5), 
                      poolsize=(2, 2)),
        FullyConnectedLayer(n_in=40*4*4, n_out=100),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.1, validation_data, test_data) 

這一次,準確率達到了99.06%。

(4)使用卷積神經網絡 — 兩個卷積層+線性修正單元(ReLU)+正則化
上面的網絡結構,我們使用的是Sigmod激活函數,現在我們換成線性修正激活函數ReLU ,同樣設定參數爲60次迭代,學習速率η=0.03,使用L2正則化,正則化參數λ=0.1,代碼如下:

>>> from network3 import ReLU
>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), 
                      filter_shape=(40, 20, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(training_data, 60, mini_batch_size, 0.03, 
            validation_data, test_data, lmbda=0.1)

這一次,準確率達到了99.23%,超過了使用sigmoid激活函數的99.06%. ReLU的優勢是當取最大極限時,梯度不會飽和。

(5)卷積神經網絡 —兩個卷基層+線性修正單元(ReLU)+正則化+拓展數據集
拓展訓練集數據的一個簡單方法是將每個訓練圖像由一個像素來代替,無論是上一個像素,下一個像素,或者左右的像素。其他的方法也有改變亮度,改變分辨率,圖片旋轉,扭曲,位移等。我們把50000幅圖像人爲拓展到250000幅圖像。使用與第四小節一樣的網絡,因爲我們訓練時使用了5倍的數據,所以減少了過擬合的風險。

>>> expanded_training_data, _, _ = network3.load_data_shared(
        "../data/mnist_expanded.pkl.gz")
>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), 
                      filter_shape=(40, 20, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(expanded_training_data, 60, mini_batch_size, 0.03, 
            validation_data, test_data, lmbda=0.1)

這次得到了99.37的訓練正確率。

(6)卷積神經網絡 — 兩個卷基層+線性修正單元(ReLU)+正則化+拓展數據集+繼續插入額外的全連接層
繼續上面的網絡,我們拓展全連接層的規模,使用300個隱藏神經元和1000個神經元的額精度分別是99.46%和99.43%.

>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), 
                      filter_shape=(40, 20, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        FullyConnectedLayer(n_in=40*4*4, n_out=100, activation_fn=ReLU),
        FullyConnectedLayer(n_in=100, n_out=100, activation_fn=ReLU),
        SoftmaxLayer(n_in=100, n_out=10)], mini_batch_size)
>>> net.SGD(expanded_training_data, 60, mini_batch_size, 0.03, 
            validation_data, test_data, lmbda=0.1)

這次取得了99.43%的精度。拓展後的網絡並沒有幫助太多。

(7)卷積神經網絡 — 兩個卷基層+線性修正單元(ReLU)+拓展數據集+繼續插入額外的全連接層+dropout技術
dropout的基本思想就是在訓練網絡時隨機的移除單獨的激活值,使得模型更稀疏,不太依賴於訓練數據的特質。我們嘗試應用dropout到最終的全連接層(而不是在卷積層)。由於訓練時間,將迭代次數設置爲40,全連接層使用1000個隱藏神經元,因爲dropout會丟棄一些神經元。Dropout是一種非常有效且能提高泛化能力,降低過擬合的方法!

>>> net = Network([
        ConvPoolLayer(image_shape=(mini_batch_size, 1, 28, 28), 
                      filter_shape=(20, 1, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        ConvPoolLayer(image_shape=(mini_batch_size, 20, 12, 12), 
                      filter_shape=(40, 20, 5, 5), 
                      poolsize=(2, 2), 
                      activation_fn=ReLU),
        FullyConnectedLayer(
            n_in=40*4*4, n_out=1000, activation_fn=ReLU, p_dropout=0.5),
        FullyConnectedLayer(
            n_in=1000, n_out=1000, activation_fn=ReLU, p_dropout=0.5),
        SoftmaxLayer(n_in=1000, n_out=10, p_dropout=0.5)], 
        mini_batch_size)
>>> net.SGD(expanded_training_data, 40, mini_batch_size, 0.03, 
            validation_data, test_data)

使用dropout,得到了99.60%的準確率。

(8)卷積神經網絡 — 兩個卷基層+線性修正單元(ReLU)+正則化+拓展數據集+繼續插入額外的全連接層+棄權技術+組合網絡
組合網絡類似於隨機森林或者adaboost的集成方法,創建幾個神經網絡,讓他們投票來決定最好的分類。我們訓練了5個不同的神經網絡,每個都大到了99.60%的準去率,用這5個網絡來進行投票表決一個圖像的分類。
採用這種集成方法,精度又得到了微小的提升,達到了99.67%。

5.26 CNN在CV與NLP領域運用的聯繫與區別?

5.26.1 聯繫

自然語言處理是對一維信號(詞序列)做操作。
計算機視覺是對二維(圖像)或三維(視頻流)信號做操作。

5.26.2 區別

自然語言處理的輸入數據通常是離散取值(例如表示一個單詞或字母通常表示爲詞典中的one hot向量),計算機視覺則是連續取值(比如歸一化到0,1之間的灰度值)。CNN有兩個主要特點,區域不變性(location invariance)和組合性(Compositionality)。

  1. 區域不變性:濾波器在每層的輸入向量(圖像)上滑動,檢測的是局部信息,然後通過pooling取最大值或均值。pooling這步綜合了局部特徵,失去了每個特徵的位置信息。這很適合基於圖像的任務,比如要判斷一幅圖裏有沒有貓這種生物,你可能不會去關心這隻貓出現在圖像的哪個區域。但是在NLP裏,詞語在句子或是段落裏出現的位置,順序,都是很重要的信息。
  2. 局部組合性:CNN中,每個濾波器都把較低層的局部特徵組合生成較高層的更全局化的特徵。這在CV裏很好理解,像素組合成邊緣,邊緣生成形狀,最後把各種形狀組合起來得到複雜的物體表達。在語言裏,當然也有類似的組合關係,但是遠不如圖像來的直接。而且在圖像裏,相鄰像素必須是相關的,相鄰的詞語卻未必相關。

5.27 卷積神經網絡凸顯共性的方法?

5.27.1 局部連接

我們首先了解一個概念,感受野,即每個神經元僅與輸入神經元相連接的一塊區域。
在圖像卷積操作中,神經元在空間維度上是局部連接,但在深度上是全連接。局部連接的思想,是受啓發於生物學裏的視覺系統結構,視覺皮層的神經元就是僅用局部接受信息。對於二維圖像,局部像素關聯性較強。這種局部連接保證了訓練後的濾波器能夠對局部特徵有最強的響應,使神經網絡可以提取數據的局部特徵;
下圖是一個很經典的圖示,左邊是全連接,右邊是局部連接。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-4roO2DM3-1575791353304)(./img/ch5/img63.png)]

對於一個1000 × 1000的輸入圖像而言,如果下一個隱藏層的神經元數目爲10^6個,採用全連接則有1000 × 1000 × 10^6 = 10^12個權值參數,如此巨大的參數量幾乎難以訓練;而採用局部連接,隱藏層的每個神經元僅與圖像中10 × 10的局部圖像相連接,那麼此時的權值參數數量爲10 × 10 × 10^6 = 10^8,將直接減少4個數量級。

5.27.2 權值共享

權值共享,即計算同一深度的神經元時採用的卷積核參數是共享的。權值共享在一定程度上講是有意義的,是由於在神經網絡中,提取的底層邊緣特徵與其在圖中的位置無關。但是在另一些場景中是無意的,如在人臉識別任務,我們期望在不同的位置學到不同的特徵。
需要注意的是,權重只是對於同一深度切片的神經元是共享的。在卷積層中,通常採用多組卷積核提取不同的特徵,即對應的是不同深度切片的特徵,而不同深度切片的神經元權重是不共享。相反,偏置這一權值對於同一深度切片的所有神經元都是共享的。
權值共享帶來的好處是大大降低了網絡的訓練難度。如下圖,假設在局部連接中隱藏層的每一個神經元連接的是一個10 × 10的局部圖像,因此有10 × 10個權值參數,將這10 × 10個權值參數共享給剩下的神經元,也就是說隱藏層中10^6個神經元的權值參數相同,那麼此時不管隱藏層神經元的數目是多少,需要訓練的參數就是這 10 × 10個權值參數(也就是卷積核的大小)。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TZwCAVex-1575791353305)(./img/ch5/img64.png)]

這裏就體現了卷積神經網絡的奇妙之處,使用少量的參數,卻依然能有非常出色的性能。上述僅僅是提取圖像一種特徵的過程。如果要多提取出一些特徵,可以增加多個卷積核,不同的卷積核能夠得到圖像不同尺度下的特徵,稱之爲特徵圖(feature map)。

5.27.3 池化操作

池化操作與多層次結構一起,實現了數據的降維,將低層次的局部特徵組合成爲較高層次的特徵,從而對整個圖片進行表示。如下圖:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rtYwwOIh-1575791353306)(./img/ch5/img65.png)]

5.28 全卷積與Local-Conv的異同點

如果每一個點的處理使用相同的Filter,則爲全卷積,如果使用不同的Filter,則爲Local-Conv。

5.29 舉例理解Local-Conv的作用

並不是所有的卷積都會進行權重共享,在某些特定任務中,會使用不權重共享的卷積。下面通過人臉這一任務來進行講解。在讀人臉方向的一些paper時,會發現很多都會在最後加入一個Local Connected Conv,也就是不進行權重共享的卷積層。總的來說,這一步的作用就是使用3D模型來將人臉對齊,從而使CNN發揮最大的效果。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1oIbY3F1-1575791353306)(./img/ch5/img66.png)]

截取論文中的一部分圖,經過3D對齊以後,形成的圖像均是152×152,輸入到上述的網絡結構中。該結構的參數如下:

Conv:32個11×11×3的卷積核

max-pooling: 3×3,stride=2,

Conv: 16個9×9的卷積核,

Local-Conv: 16個9×9的卷積核,

Local-Conv: 16個7×7的卷積核,

Local-Conv: 16個5×5的卷積核,

Fully-connected: 4096維

Softmax: 4030維。

前三層的目的在於提取低層次的特徵,比如簡單的邊和紋理。其中Max-pooling層使得卷積的輸出對微小的偏移情況更加魯棒。但不能使用更多的Max-pooling層,因爲太多的Max-pooling層會使得網絡損失圖像信息。全連接層將上一層的每個單元和本層的所有單元相連,用來捕捉人臉圖像不同位置特徵之間的相關性。最後使用softmax層用於人臉分類。
中間三層都是使用參數不共享的卷積核,之所以使用參數不共享,有如下原因:

(1)對齊的人臉圖片中,不同的區域會有不同的統計特徵,因此並不存在特徵的局部穩定性,所以使用相同的卷積核會導致信息的丟失。

(2)不共享的卷積核並不增加inference時特徵的計算量,僅會增加訓練時的計算量。
使用不共享的卷積核,由於需要訓練的參數量大大增加,因此往往需要通過其他方法增加數據量。

5.30 簡述卷積神經網絡進化史

主要討論CNN的發展,並且引用劉昕博士的思路,對CNN的發展作一個更加詳細的介紹,將按下圖的CNN發展史進行描述

![image](./img/ch5/img67)

  1. 列表項
    http://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=2650324619&idx=1&sn=ca1aed9e42d8f020d0971e62148e13be&scene=1&srcid=0503De6zpYN01gagUvn0Ht8D#wechat_redirect
    CNN的演化路徑可以總結爲以下幾個方向:
  • 進化之路一:網絡結構加深
  • 進化之路二:加強卷積功能
  • 進化之路三:從分類到檢測
  • 進化之路四:新增功能模塊
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章