cs231n --- 3 : Convolutional Neural Networks (CNNs / ConvNets)

 

CNN介紹

與以前的神經網絡不一樣之處在於,CNN明確指定了輸入就是圖像,這容許咱們將某些特徵編碼到CNN的結構中去,不只易於實現,還能極大減小網絡的參數。git

 一. 結構概述

與通常的神經網絡不一樣,卷積神經網絡尤爲特殊之處。通常的神經網絡每一層與前一層之間採用全鏈接;一層中的神經元之間也是互相獨立的,並不共享權值;最後一層全鏈接層陳偉輸出層,在分類任務中出表示類別得分。CIFAR-10中圖像是32*32*3=3072,因此,與輸入相連的第一個隱層的每一個神經元的參數都有3072個,若是圖像尺寸更大,那麼每一個神經元的參數更多,這將形成巨大的參數冗餘,訓練中也會很快致使過擬合問題。以下圖左所示。github

 

 神經網絡算法

 

 

卷積神經網絡網絡

卷積神經網絡限定了輸入的是圖像,它能夠採用更合理的方式安排神經元。CNN不將圖像調整爲向量以後再輸入,而是直接以原始的3D矩陣形式(高x寬x通道數)給輸入層,而後輸出3D數據矩陣,並依次進行學習、表示。機器學習


二. 卷積神經網絡的層 Layers

卷積神經網絡是由一系列的層Layer組成的,下面介紹主要的層(包括卷積層 Convolutional layer,池化層 Pooling layer,全鏈接層 Fully-connected layer)。ide

以應用於CIFAR-10數據集的卷積神經網絡爲基礎,介紹以下結構的卷積神經網絡,函數

      [ INPUT - CONV - RELU - POOL - FC ]性能

  •  Input:[32x32x3],保存原始圖像的像素值
  • CONV layer:計算與輸入input 局部區域相連的神經元的輸出,每一個輸出都是 局部輸入與這些神經元的權重的點積(.*),若是有12個濾波器(卷積核),則輸出爲 [32x32x12]
  • ReLU:非線性操做max(0,x),不改變輸入尺寸,[32x32x12]
  • Pool:池化,對輸入的 [長x寬] 方向上進行下采樣,改變輸入尺寸,如能夠獲得這樣的結果 [16x16x12]
  • FC:計算類別得分,獲得結果 1x1x10(CIFAR-10 有10類)

 ReLU與Pool都是固定的函數,訓練時 只對 CONV layer與FC進行權重更新學習

1. 卷積層 convolutional layer

卷積層是卷積神經網絡的核心模塊,它承擔了主要的計算工做大數據

 卷積層的參數是一系列能夠學習的濾波器。每一個濾波器都是[ filter_寬xfilter_高x通道數 ],第一個卷積層的典型濾波器尺寸是 5x5xx3。前向傳播時,咱們把每一個濾波器沿着輸入數據的高度與寬度滑動(卷積),計算濾波器係數與濾波器窗口所覆蓋的輸入區域  之間的點積,隨着濾波器沿着輸入數據的高度x寬度所有滑動一遍,就會獲得二維的輸出映射(activation map),activation map 保存的是濾波器在輸入上滑動時,在空間每個點的響應(點積 .*)。這樣一個濾波器就獲得一個 activation map,12個濾波器就會獲得12個activation map,而後沿着深度的方向將這12個二維的 activation map(輸出映射)組合成輸出,做爲下一層的輸入。


 一個濾波器對圖像卷積,convolved feature即爲濾波器的 activation map,即從圖像學到的特徵

 

第一層對原始圖像卷積後,學到多個二維 activation maps,而後按照Z軸(深度)組合起來,傳遞給後面的 pooling layer 進行下采樣

 

直覺上卷積神經網絡學習到的濾波器應該是這樣的,它們在遇到特定的結構時會激活,好比有的濾波器在遇到邊緣時會激活,有的在遇到某個直角會激活,...; 並且不一樣的層的濾波器檢測的形狀也不同,前面的層,它們的濾波器檢測基本的形狀,越靠後面的層,這些基本特徵組合成複雜形狀,後面層的濾波器檢測複雜形狀,最後網絡就能檢測出車輪,或者花朵之類的物體。

1.1 局部鏈接

 局部鏈接就是指小尺寸的濾波器,與高維的輸入之間的鏈接。以卷積神經網絡第一層爲例,採起輸入是原始圖像,因爲不可能像通常的神經網絡那樣實行全鏈接(參數太多!),因此定義小尺寸的濾波器 [filer_寬,filter_高,圖像通道數],必須保證濾波器深度與圖像的深度是一致的,這樣濾波器在圖像上面滑動(卷積)時,只考慮在圖像 寬x高 的空間面上滑動,因此產生的是二維的輸出。濾波器在圖像上滑動時,它所可以覆蓋的輸入圖像的區域,就是局部的小區域(大小是 filter_寬 x filter_高),卷積運算也就是在濾波器與小區域之間進行,獲得一個卷積結果數值,隨後再滑動必定的步長,再次進行卷積。局部鏈接就是每次卷積時,神經元只與覆蓋的小區域鏈接。

  輸出的大小

 卷積層對輸入進行卷積後,獲得activation maps,而後再以某種形式安排這些數據,造成輸出,主要的參數有深度,步長,零填充。

  •  深度是指輸出的深度,即輸出是 寬度 x 高度 x 深度。深度是由濾波器(卷積核)的數量控制的,有多少個濾波器,就有多少個 activation maps,輸出就是將這些 activation maps組合起來,輸出的深度就等於濾波器數量。
  • 步長是指卷積時每次濾波器跳過的像素數,步長=1,則濾波器每次移動一個像素;步長=2,則濾波器每次移動2個像素執行卷積。注意,步長必須能整除 N+2P-m,見下面的例子。
  • 零填充是爲了使濾波器的 activation maps 與輸入有相同的 寬度x高度

 一個例子,輸入是 NxNx3;濾波器是 mxmx3,共有K個;步長是 S;零填充是使用P個0在邊界填充,則輸出activation maps的 高度(=寬度)應該是 (N+2P-m)/ S + 1。

  CIFAR-10 的圖像是 32x32x3, 選擇 濾波器尺寸 5x5x3,步長 S=1,填充 P= 0,則輸出是 28x28;若是步長S=3,則輸出是 10x10。

1.2 權值共享(參數共享)

 一個例子是ImageNet 2012,圖像是 227x227x3,m = 11,S=4,P=3,K=96,則第一層卷積的輸出是 55x55x96。若是按照通常神經網絡的設置,55x55x96的輸出須要 55*55*96 =290400 個神經元,每一個神經元須要的參數是 11*11*3 + 1 =364,所以在第一層就有 290400*364 =105,705,600個參數,這是很是多的。

卷積神經網絡採用了權值共享的思路,對於一個濾波器來講,它的任務是檢測某個特徵,好比說檢測水平線,那麼它檢測到了(x1,y1)位置處的水平線,那麼若是在(x1,y2)位置處有水平線,它應該也能檢測出來。所以,它應該使用相同的參數來檢測不一樣位置處的水平線,因此,就設計一個濾波器在輸入的全部位置(x,y)上滑動時,它的參數都是相同的,也就是說,濾波器在輸入的全部位置上,都是用相同的參數來檢查某一特徵(體現爲卷積操做),而後將卷積的結果就是它的activation map。這樣就使得網絡的參數大大減小,卷積神經網絡第一層的參數就變爲 96*11*11*3 + 96 = 34944

  注意:有的地方不須要權值共享,有時輸入圖像具備特定的中心結構,咱們還但願學到這種結構。那就不須要權值共享了。好比,面部出如今圖像中心,咱們指望學到不一樣的位置的眼睛或者頭髮特徵,那就不須要權值共享,而只須要局部鏈接就好了。

  卷積的實現(Python):經過 im2col 的方法來實現,用矩陣相乘完成卷積操做

假設輸入X [227x227x3],96個濾波器 [ 11x11x3 ],步長S=4,那麼一個濾波器卷積的輸出維度應該是 (227-11)/ 4 = 55,卷積層的輸出應該是 55x55x96。

  1. 濾波器覆蓋是區域是 11x11x3 =363,一個濾波器將對輸入X執行卷積操做 55x55 =3025 次,因此根據X,能夠獲得 X_col [ 363x3025 ],每一列表明 濾波器在X上覆蓋的區域的展開
  2. 根據96個 [11x11x3] 濾波器,獲得 filter_col [ 96x363 ],每一行都是一個濾波器參數的展開
  3. 矩陣相乘 np.dot(filter_col, X_col) 獲得 [96x3025],最後 np.reshape 便可獲得55x55x96的卷積結果

2. 池化層 pooling layer

 在連續的卷積層之間加入池化層很常見,pooling layer 的做用是逐步的減少從圖像中提取的表達representation的尺寸,進而減小網絡的參數與計算量,同時還能控制過擬合。最多見的pooling layer的下采樣尺寸 2x2,步長s=2,它沿着 activation maps的 寬度x高度面下采樣,並不影響深度。

主要有兩種pooling方法,max pooling與mean pooling,主要有 尺寸 2x2,與步長S兩個採樣參數。但並不更新,是固定的,pooling layer只執行固定的下采樣做用。下圖示意圖。

pooling

max pooling

  max pooling ,採樣尺寸 2x2, 步長s=1,在2x2採樣窗口所覆蓋的輸入區域內,取輸入區域最大值max(...),做爲對應的輸出數據點(也就是輸入的2x2數據產生一個輸出數據);而後採樣窗口根據步長規定移動,再對下一個窗口覆蓋的輸入數據採樣,做爲輸出數據值,...,直至採樣完成。max pooling的常見尺寸是 3x3, 步長S=2(重疊採樣),或者 2x2,步長=2

   mean pooling:與max pooling相似,只是取輸入的均值做爲輸出值。如今更經常使用 max pooling,實際效果比 mean pooling 好。

 注意:下采樣時通常不用零填充


 

 3. FC layers to CONV layers

實際中將全鏈接層轉換成具備相同效果的卷積層,加快速度,提高效率。

 


 

三. 卷積神經網絡的結構

卷積神經網絡主要有: CONV, POOL(max), ReLU, FC 組成。

 最多見的卷積網絡結構是: [ 一些 CONV - ReLU 層,接着是一些 POOL 層 ],重複以上結構,直到圖像合併成比較小的圖,而後是 一些FC 層,最後一層 FC 層保存類別得分之類的輸出,

以下所示:

  INPUT -> [ [CONV -> RELU] *N  -> POOL? ]*M -> [FC -> RELU]*K -> FC

 * 表示重複,POOL? 表示可選的 pooling層, 一般 0 <= N <= 3,M >= 0,0 <= K < 3。

3.1 以下是常見的一些 卷積網絡結構

  •  INPUT -> FC,實現線性分類器功能,N = M = K = 0
  • INPUT -> CONV -> ReLU -> FC
  • INPUT -> [ CONV -> ReLU -> POOL ]*2  -> FC -> ReLU -> FC
  • INPUT -> [ CONV -> ReLU -> CONV -> ReLU -> POOL ]*3  -> [ FC -> ReLU ]*2 -> FC, 大型的深度網絡適用,在 pooling 層以前多個 conv 層能夠提取輸入的更復雜的特徵

 3個 3x3 CONV 效果 等同於 1個 7x7 CONV,可是更傾向於 多個小尺寸 CONV ,由於多個小尺寸 CONV層  能夠 1. 更有效的表達特徵,2. 減小參數。

 


3.2 各個層的尺寸問題

1. 輸入層(INPUT)應該可以被 2 整除不少次,一般有 32(CIFAR-10),64,96(STL-10),224,384,512

2. CONV layer使用小的 filter(3x3,最可能是 5x5),步長S=1,須要對輸入進行零填充以保持輸入的大小 ( 寬度x高度 ). 若是非要使用 大的filter(好比7x7),只有在跟輸入的圖像相鄰的第一個卷積層上使用。

3. POOL layer 控制對輸入的下采樣,通常是Max pooling,最經常使用的是 2x2 ,步長S=2,這個設置就捨棄了 75%的下采樣層的輸入(即上一層的activation map);另一個不常常用到的設置是 3x3,步長   S=2。對於 max pooling,採樣窗口大於 3x3 會致使損失太大,性能不佳,不多用。

 


 四. 卷積網絡的幾個例子

  • LeNet:第一個成功應用的卷積神經網絡,用於讀取 zip編碼,識別手寫數字等。
  • AlexNet: 由Alex Krizhevsky, Ilya Sutskever 和 Geoff Hinton提出,2012年的ImageNet ILSVRC challenge冠軍,網絡與LeNet很類似,可是更深更大,並且有CONV層疊加起來,以前都是一個CONV層後面就當即跟一個POOL層。
  • ZF Net:ILSVRC 2013的冠軍,由Matthew Zeiler 和 Rob Fergus 提出,ZF Net是對AlexNet的改進,擴展了中間的卷積層CONV layer,並且使第一層的步長S與濾波器filter的尺寸都更小。
  • GoogleNet:Google的Szegedy et al.提出的,ILSVRC 2014冠軍,主要貢獻是開發的初始模塊極大減小了網絡的參數(GoogleNet的參數4M,AlexNet有60M),文章在網絡的頂部使用平均池化Average pooling 而不是全鏈接層,消除了大量的可有可無的參數。
  • VGGNet:ILSVRC 2014的亞軍,由Karen Simonyan 和 Andrew Zisserman提出,主要貢獻是展現了網絡的深度對於性能的提高很是重要。網絡包含 16個 CONV / FC 層,從頭至尾都是 3x3的CONVOLUTION,2x2的Pooling。參數有 140M。
  • ResNet:殘差網絡是 ILSVRC 2015的冠軍,由 Kaiming He et al. 提出,網絡的特色是 skip connections 和 a heavy use of batch normalization,在網絡的最後也沒有FC層。截至2016.5月此網絡是最好的卷積神經網絡模型,實際中默認選擇的卷積網絡。

 VGGNet 分析

CONV layers執行3x3卷積,步長S=1,零填充P=1; POOL layers執行2x2 max pooling,步長S=2,不進行零填充P=0。

追蹤每一步的 表達size 與 參數size:

INPUT: [224x224x3] memory: 224*224*3=150K weights: 0 CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*3)*64 = 1,728 CONV3-64: [224x224x64] memory: 224*224*64=3.2M weights: (3*3*64)*64 = 36,864 POOL2: [112x112x64] memory: 112*112*64=800K weights: 0 CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*64)*128 = 73,728 CONV3-128: [112x112x128] memory: 112*112*128=1.6M weights: (3*3*128)*128 = 147,456 POOL2: [56x56x128] memory: 56*56*128=400K weights: 0 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*128)*256 = 294,912 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824 CONV3-256: [56x56x256] memory: 56*56*256=800K weights: (3*3*256)*256 = 589,824 POOL2: [28x28x256] memory: 28*28*256=200K weights: 0 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*256)*512 = 1,179,648 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [28x28x512] memory: 28*28*512=400K weights: (3*3*512)*512 = 2,359,296 POOL2: [14x14x512] memory: 14*14*512=100K weights: 0 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 CONV3-512: [14x14x512] memory: 14*14*512=100K weights: (3*3*512)*512 = 2,359,296 POOL2: [7x7x512] memory: 7*7*512=25K weights: 0 FC: [1x1x4096] memory: 4096 weights: 7*7*512*4096 = 102,760,448 FC: [1x1x4096] memory: 4096 weights: 4096*4096 = 16,777,216 FC: [1x1x1000] memory: 1000 weights: 4096*1000 = 4,096,000 TOTAL memory: 24M * 4 bytes ~= 93MB / image (only forward! ~*2 for bwd) TOTAL params: 138M parameters

 


  計算上的考慮

如今構建卷積神經網絡最大的瓶頸就是內存瓶頸,進行網絡構建時提早計算所需內存大小:

1. 每層的activation maps,梯度。

2. 參數數量

3. 其他所需數據,好比 image data等。

 


 


 理解CNN,可視化

總結一些理解與觀察CNN的方法

1. 可視化層的activation

最直白的可視化就是在CNN計算前向傳播時,可視化神經網絡的輸出映射activation maps。若是存在某些 activation maps,對於許多不一樣的輸入這些activation maps的值都是0,那麼就暗示這些濾波器 filters是「死」的濾波器,多是學習率過大的標誌。

2. CONV / FC  Fliters

第二個經常使用方法是可視化權重,通常第一個卷積層的權重可視化後最易於解釋,由於它鏈接的原始圖像,後續的也應該能夠可視化。權重可視化的用途在於,對於訓練很好的網絡,它的濾波器權重可視化後通常都是平滑流暢的無噪聲圖像。有噪聲的可視化圖像暗示着網絡訓練的時間不夠長,或者是正則化強度過低致使了過擬合。

 左側是訓練好的AlexNet的第一個卷積層的濾波器可視化,圖中彩色/灰度在一塊兒是 由於AlexNet網絡有兩個獨立的處理流,結果就是一個開發高頻灰度圖像,另外一個開發低頻彩色圖像

 

右側是訓練好的AlexNet第二個卷積層的濾波器可視化,可視化圖像沒法明確的解釋,可是這些圖像都是光滑的、無噪聲圖像

 3.檢索出可以使神經元有最大激活的圖像

 另外一個可視化方法就是將一個大的圖像集輸入給網絡,追蹤能夠最大激活某些神經元的圖像,而後將圖像顯示出來。以此來觀察這些神經元在它的感覺野以內,它尋找的是什麼樣的圖像。一個這樣的可視化方法就是 Rich feature hierarchies for accurate object detection and semantic segmentation by Ross Girshick et al.: 

AlexNet的第5個POOL 的某些神經元的 最大激活圖像,激活值和感覺野以白色顯示

 ReLU的神經元自己沒有什麼語義含義, http://cs231n.github.io/understanding-cnn/

 4. 根據 t-SNE嵌入圖像

 t-SNE(t-distributed stochastic neighbor embedding):t-分佈隨機領域嵌入,是用於降維的一種機器學習算法,是由 Laurens van der Maaten 和 Geoffrey Hinton在08年提出來。此外,t-SNE 是一種非線性降維算法,很是適用於高維數據降維到2維或者3維,進行可視化。

思路就是將數據從高維降維到地位,而後將低維上距離相近的圖像靠近,完成可視化。爲了嵌入,咱們能夠將圖像集合輸入卷機網絡,提取他們的CNN碼,CNN碼能夠是AlexNet中分類器以前的 4096-維矢量,而後將CNN碼插入t-SNE而後獲得圖像的2-維矢量,以下:

根據CNN碼將圖像進行t-SNE嵌入。CNN「認爲」靠的近的圖像更類似,這種類似性是語義與類別上類似性,而不是顏色或者像素值的類似性。 

more related visualizations at different scales refer to t-SNE visualization of CNN codes.

5. 遮擋圖像的一部分 

 若是CNN網絡將一幅圖像斷定爲「dog」,那麼如何肯定CNN網絡實際斷定的依據呢?它是依據圖中的dog來斷定的?仍是依據圖像上下文或者其餘物體來斷定的呢?爲了明確這一點,能夠經過遮擋圖像以後,畫出CNN網絡的預測類別來觀察。具體的就是,逐塊的遮擋圖像中的區域,使要遮擋的區域設置爲0,而後觀察CNN判斷類別爲 dog 的機率。還能夠將機率畫做2-位熱力圖,Matthew Zeiler 已經使用此方法 Visualizing and Understanding Convolutional Networks:

三幅圖像,遮擋都是以灰色區塊表示。最左側的 Dog 圖像,Dog圖像下方是 CNN斷定次圖像類別是 Dog 的機率,能夠看出當遮擋了上面圖像中Dog的臉部區域後,CNN斷定Dog類別的機率就大幅降低(表現爲藍色),這說明,Dog的臉部是斷定的主要依據。而那些遮擋後 類別機率不變的部位,對於類別斷定的影響能夠忽略。

 


Visualizing the data gradient and friends

Data Gradient.

Deep Inside Convolutional Networks: Visualising Image Classification Models and Saliency Maps

DeconvNet.

Visualizing and Understanding Convolutional Networks

Guided Backpropagation.

Striving for Simplicity: The All Convolutional Net

Reconstructing original images based on CNN Codes

Understanding Deep Image Representations by Inverting Them

How much spatial information is preserved?

Do ConvNets Learn Correspondence? (tldr: yes)

Plotting performance as a function of image attributes

ImageNet Large Scale Visual Recognition Challenge

Fooling ConvNets

Explaining and Harnessing Adversarial Examples

Comparing ConvNets to Human labelers

What I learned from competing against a ConvNet on ImageNet

 



 遷移學習(Transfer Learning)

 實際上,不多有人從零訓練整個卷積網絡,由於不多有足夠數目的數據供其訓練使用。通常都是使用一個大數據集(如ImageNet)來預訓練一個卷積模型,而後對於目標任務,使用這個模型做爲初始模型或者做爲固定特徵抽取器。三個主要的遷移學習場景以下,

  1. 卷積網絡做爲固定特徵抽取器。在ImageNet上預訓練一個卷積模型,而後去掉最後的全鏈接層,將剩餘的模型做爲新數據集合的固定特抽取器來抽取特徵。AlexNet中,在分類器以前的那一層輸出,每一個圖像都將計算獲得長爲4096的特徵矢量,稱之爲CNN碼。 通常須要對CNN碼進行ReLU操做,這樣能夠提升分類與預測性能。全部圖像的CNN碼提取完成以後,這些CNN碼構成了新的數據集合,能夠用線性分類器(linearSVM或softmax)分類。
  2. 對卷積網絡參數調優。這個策略不只僅替換掉卷積網絡模型最後一層的分類器,並且還要繼續對這個模型的參數調優。繼續進行BP迭代便可,既能夠對整個網絡調優,也能夠只固定前面的低層,僅僅對後面的的高層調優。這樣作的緣由在於,經過觀察能夠發現,卷積網絡前面的低層學習的通常是對許多任務都通用的特徵(如邊,線,點等低級特徵),然後面高層網絡學習到的是對原始數據集分類任務所須要的更具體的特徵(所以對不一樣的新數據集就不是最優的)。好比,ImageNet有許多種類的狗,模型的高層學習的更可能是如何區分不一樣品種的狗,低層學習的能夠是基本的線條形狀等更通用的。
  3. 預訓練模型。如今的模型在ImageNet上須要用2-3周的時間在多GPU上訓練,有人就會放出他們在保存點保存的模型,以供別人調優,減小時間。

 怎樣調優?什麼時候調優?  兩個重要的因素是新數據的大小、新數據集與原數據集的類似程度。

  1. 新數據集小並且與原數據集類似。 新數據集小,沒必要對模型參數調優,防止可能的過擬合。兩者類似,模型的高層特徵與新數據集也會相關。所以最好是訓練線性分類器對CNN碼分類。
  2. 新數據集很大,且與原數據集類似。能夠進行參數調優,而沒必要擔憂過擬合問題。
  3. 新數據集小,可是與原數據集差異很大。新數據集小,最好的直接訓練線性分類器就好。然而新、舊數據集差異很大,所以模型的高層特徵相關性比較小,不宜直接使用高層CNN碼進行線性分類,最好是使用低層的CNN碼。
  4. 新數據集大,並且於原數據集差異大。能夠直接對原模型調優,沒必要擔憂過擬合。
相關文章
相關標籤/搜索