天天看點

卷積網絡CNN

卷積網絡是近年來非常流行的網絡結構,常用于處理圖像(2維卷積)和自然語言(1維卷積)。在不明覺厲的情況下使用卷積層,往往使用别人設計的結構,湊參數往模型裡塞,同複雜的原理書中的内容又有點對不上号。本篇從應用場景,具體用法入手,深入到每一個重要參數:具體用途、用法及計算方法。

為什麼使用卷積網絡

先來看看全連接配接網絡的參數:

卷積網絡CNN

網絡有三個輸入x1,x2,x3和兩個輸出y1,y2,具體計算方法是:

卷積網絡CNN

如果y1與x3沒有什麼關系,通過訓練兩者之間的參數w31可能趨近于0,但該連接配接仍然存在。對于輸入為3輸出為2的網絡需要訓練32=6個參數。圖檔資料非常龐大,如果訓練一張10001000像素,RGB三通道的圖檔,則輸入元素有3M個,如果第一個隐藏層有1000個元素,則需要訓練100010003*1000個參數,使得網絡非常龐大,同時需要非常大量的資料才能避免過拟合。

卷積網絡的優勢在于共享參數,比如一個3x3的檢測物體邊緣卷積核訓練好後,即可用于整個圖檔,此時需要學習的參數隻有3x3=9個,如果在一層中訓練20個3x3的卷積核用于檢測不同特征,也隻需要訓練3x3x20=60個參數。

需要注意的問題是使用同樣一組參數(卷積核)處理層的多個輸入特征時,每組輸入特征需要具有共同的性質,才能被處理,比如圖檔中的每個小區域邊緣都具有相同的性質,可使用同種方法檢測;但是預測汽車價格時,各個特征都代表完全不同的含義,就無法将不同意義的特征分組後使用同樣的方法處理。

具體用法

卷積網絡常用于圖像處理,它常與池化層同時使用。以Pytorch為例,在模型的init初始化中建立層:

self.conv=torch.nn.Conv2d(3,16,2,stride=1,padding=1)  
self.pool=torch.nn.MaxPool2d(4,4)        

在forward前向傳播時使用層:

out = self.conv(X)  
out = self.pool(out)        

傳入卷積層的一般是4維資料[m,w,h,c]。此處建立的卷積層可以處理任意大小的圖檔。構造該層的參數如下:

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)        

其中前五個參數最為重要:

  • in_channel:輸入通道數
  • out_channel:輸出通道數
  • kernel_size:卷積核大小
  • stride:步長
  • padding:擴邊

下面從原理角度介紹各個參數的功能。

重要概念

卷積網絡的原理如下圖所示,一個3x3的卷積核作用于6x6的圖檔之上,通過每個相鄰的3x3區域計算一個值,具體方法是對應點做元素乘法之後相加,映射成右圖中的一個點,然後逐漸移動(Stride)周遊左圖中所有區域,計算出右圖中所有點作為輸出。

卷積網絡CNN

圖檔來自吳恩達深度學習

kernel卷積核

卷積核kernel,有時也叫作filter,具體的計算方法下:

卷積網絡CNN

可以看到乘加的方法與全連接配接非常相似,不同的是使用卷積核之後,輸出y中的每個元素隻與部分x元素連接配接,計算量更小,即稀疏連接配接;使用同一組f與各個位置的x計算,參數更少,即共享參數。

padding擴邊

上圖中使用3x3的卷積核對6x6的圖檔做卷積操作,輸出是3x3的圖檔,輸出明顯變小了,如果經過多次卷積圖檔會越變越小,另外,在卷積過程中邊緣像素也被弱化了(邊緣像素隻對少數輸出點起作用,使各像素點貢獻不均衡)。為解決這一問題,一般工具都提供padding擴邊功能,在卷積處理之前,延着邊擴一圈(或者幾圈),元素填充為0,如圖檔大小為6x6,padding為1時,圖檔大小變成8x8。目标是使得輸出與處理之前的輸入大小一緻。

卷積可分為Valid Convolutions(帶padding)和Same Convolutions(不帶padding)兩種。padding的大小一般設定為p=(f+1)/2。其中f是卷積核大小,由于上/下,左/右都需要加邊,是以除2,可以看到如果卷積核為偶數,則p有小數部分,是以,一般卷積核心都為奇數,以免造成不對稱;另外,奇數填充有一個中心點,這樣也能更好地描述卷積操作的位置。

stride步長

步長是卷積核在原圖上每一步移動的距離。下圖是步長為2時,第一步和第二步的卷積操作。

卷積網絡CNN

簡單地講就是每次移動幾個像素,stride一般設定為1或2,如何設定stride與卷積核大小相關,如果卷積核為3,步長為1,則各個卷積之間有一定的重疊;如果設定為4,則會漏掉一些像素。另外,如果stride設定較大會使輸出圖檔變小,這也起到了一定的池化作用。

輸出圖檔的大小可按以下公式計算:

卷積網絡CNN

其中n是圖檔大小,f是卷積核大小,pad為擴邊大小,stride為步長,注意當除法結果非整數時向下取整。

channel通道

通道變換是相對較難以了解的問題,從使用角度看,輸入卷積層的是一張256x256x3,即長寬各為256像素,包含RGB三個顔色通道的圖檔,輸出為32x32x16,即大小為32x32,提取了16組特征。下面來看看如何從3通道變成16通道。

卷積網絡CNN

如圖所示,對三維資料進行三維卷積後,輸出為二維(27次元素乘法之後做加法),如果使用16個三維卷積核做卷積,輸出則是4x4x16個特征。可以說訓練了16個卷積核,用于提取不同的16種特征。對照初始化時的操作,無需指定圖檔大小,隻需指定輸入通道數i,輸出通道數o,即可提取o種特征。

資料格式

傳入conv2d的資料格式一般是4維數組[m,w,h,c],後三維分别是圖檔的寬高和輸入通道數,第一維用于處理多張圖檔。需要注意的是forward時的輸入通道數需要與初始化conv2d時設定的輸入通道數一緻。

池化層

池化層的主要作用是縮小圖檔,以及提高魯棒性。上面提到,通過卷積的步長也能達到使輸出變小的效果,池化層的另一個重要功能提高魯棒性。

池化層一般放置在卷積層之後,用于将某一種特征中的多個值用單個值表示,這裡隻讨論最簡單普通的用法:與卷積層配合使用的池化層。最常見的兩種池化分别是最大池化和平均池化,又以最大池化為主。

池化的主要參數也是:大小f,步長s,以及具體的池化方法max/mean。最常見的數池化是f=2,s=2,type=maxpool,如下圖所示:

卷積網絡CNN

maxpool可看作是提取了最顯著的特征,另外,需要注意:

  • 池化可能有兩個區域或者多個區域有重疊部分。
  • 池化層沒有需要訓練的weight參數,也因為這個原因,在描述一個模型的層數時,一般不将池化層計算在内,隻作為卷積層的附屬。
  • 對于三維資料,池化隻對其中的wxh操作,輸出的channel大小不變。

瓶頸層

卷積網絡正常用法

  • 盡量使用論文中的超參數,不要自己從頭設定。
  • 網絡結構中,一般wxh越來越小,channel越來越大,且常常是成倍減少或增加。
  • 前邊是若幹卷積層,後面是一個或幾個全連接配接層,最後是softmax。
  • 層間資料越來越少,但不要下降太快。

繼續閱讀