卷積網絡是近年來非常流行的網絡結構,常用于處理圖像(2維卷積)和自然語言(1維卷積)。在不明覺厲的情況下使用卷積層,往往使用别人設計的結構,湊參數往模型裡塞,同複雜的原理書中的内容又有點對不上号。本篇從應用場景,具體用法入手,深入到每一個重要參數:具體用途、用法及計算方法。
為什麼使用卷積網絡
先來看看全連接配接網絡的參數:
網絡有三個輸入x1,x2,x3和兩個輸出y1,y2,具體計算方法是:
如果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)周遊左圖中所有區域,計算出右圖中所有點作為輸出。
圖檔來自吳恩達深度學習
kernel卷積核
卷積核kernel,有時也叫作filter,具體的計算方法下:
可以看到乘加的方法與全連接配接非常相似,不同的是使用卷積核之後,輸出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時,第一步和第二步的卷積操作。
簡單地講就是每次移動幾個像素,stride一般設定為1或2,如何設定stride與卷積核大小相關,如果卷積核為3,步長為1,則各個卷積之間有一定的重疊;如果設定為4,則會漏掉一些像素。另外,如果stride設定較大會使輸出圖檔變小,這也起到了一定的池化作用。
輸出圖檔的大小可按以下公式計算:
其中n是圖檔大小,f是卷積核大小,pad為擴邊大小,stride為步長,注意當除法結果非整數時向下取整。
channel通道
通道變換是相對較難以了解的問題,從使用角度看,輸入卷積層的是一張256x256x3,即長寬各為256像素,包含RGB三個顔色通道的圖檔,輸出為32x32x16,即大小為32x32,提取了16組特征。下面來看看如何從3通道變成16通道。
如圖所示,對三維資料進行三維卷積後,輸出為二維(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,如下圖所示:
maxpool可看作是提取了最顯著的特征,另外,需要注意:
- 池化可能有兩個區域或者多個區域有重疊部分。
- 池化層沒有需要訓練的weight參數,也因為這個原因,在描述一個模型的層數時,一般不将池化層計算在内,隻作為卷積層的附屬。
- 對于三維資料,池化隻對其中的wxh操作,輸出的channel大小不變。
瓶頸層
卷積網絡正常用法
- 盡量使用論文中的超參數,不要自己從頭設定。
- 網絡結構中,一般wxh越來越小,channel越來越大,且常常是成倍減少或增加。
- 前邊是若幹卷積層,後面是一個或幾個全連接配接層,最後是softmax。
- 層間資料越來越少,但不要下降太快。