深度學習之 alexnet詳解2

AlexNet網絡詳解及各層作用

Alex在2012年提出的alexnet網絡結構模型引爆了神經網絡的應用熱潮,並贏得了2012屆圖像識別大賽的冠軍,使得CNN成爲在圖像分類上的核心算法模型。AlexNet 該模型一共分爲八層,5個卷積層,,以及3個全連接層,在每一個卷積層中包含了激勵函數RELU以及局部響應歸一化(LRN)處理,然後在經過降採樣(pool處理),下面我們對每一層開始詳細的分析。以下代碼塊來自Caffe源碼:

1.conv1層:
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 96
    kernel_size: 11
    stride: 4
  }
}
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "conv1"
  top: "conv1"
}
layer {
  name: "norm1"
  type: "LRN"
  bottom: "conv1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "norm1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}

1.輸入的圖像爲彩色圖片(RGB圖像):224 * 224 * 3 ,實際上會經過預處理變爲227 * 227 * 3,這個圖像被96個大小規格爲11 * 11 * 3(同樣也是三通道了)的卷積核,進行特徵提取,96個卷積核分成2組(因爲採用了2個GPU服務器進行處理),每組48個卷積核;

2.卷積覈對原始圖像的每次卷積都生成一個新的像素。卷積核沿原始圖像的x軸方向和y軸方向兩個方向移動,stride移動的步長是4個像素。因此,卷積核在移動的過程中會生成(227-11)/4+1=55個像素(卷積的計算方式,詳見本博主以前發的lenet網絡),注意這裏提取到的特徵圖是彩色的.這樣得到了96個55 * 55大小的特徵圖了,並且是RGB通道的.96個卷積核分成2組,每組48個卷積核。對應生成2組55 * 55 * 48的卷積後的像素層數據。這些像素層經過relu1單元的處理,生成激活像素層,尺寸仍爲2組55 * 55 * 48的像素層數據。

需要特別說明的一點是,我們在使用卷積核和數據進行卷積時(ps: 卷積就是[1,2,3][1,1,1] = 11+21+31=6,也就是對應相乘並求和),而且我們使用的卷積核尺寸是11 * 11,也就是採用的是局部鏈接,每次連接11 * 11大小區域,然後得到一個新的特徵,再次基礎上再卷積,再得到新的特徵,也就是將傳統上採用的全鏈接的淺層次神經網絡,通過加深神經網路層次也就是增加隱藏層,然後下一個隱藏層中的某一個神經元是由上一個網絡層中的多個神經元乘以權重加上偏置之後得到的,也就是所謂的權值共享,通過這來逐步擴大局部視野,(形狀像金字塔),最後達到全鏈接的效果. 這樣做的好處是節約內存,一般而言,節約空間的同時,消耗時間就會相應的增加,但是近幾年的計算機計算速度的提升,如GPU.已經很好的解決了這個時間的限制的問題.

3.使用RELU激勵函數,來確保特徵圖的值範圍在合理範圍之內,比如{0,1},{0,255},這些像素層經過relu1單元的處理,生成激活像素層,尺寸仍爲2組55 * 55 * 48的像素層數據。

4.這些像素層經過pool運算(最大池化)的處理,池化運算的尺度爲3 * 3,stride移動的步長爲2,則池化後圖像的尺寸爲(55-3)/2+1=27。 即池化後像素的規模爲27 * 27 * 96;

5.然後經過歸一化處理,歸一化運算的尺度爲5 * 5;第一卷積層運算結束後形成的像素層的規模爲27 *2 7 * 96。分別對應96個卷積核所運算形成。這96層像素層分爲2組,每組48個像素層,每組在一個獨立的GPU上進行運算。

2.conv2

layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 2
    kernel_size: 5
    group: 2
  }
}
layer {
  name: "relu2"
  type: "ReLU"
  bottom: "conv2"
  top: "conv2"
}
layer {
  name: "norm2"
  type: "LRN"
  bottom: "conv2"
  top: "norm2"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "norm2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}

1.conv2中使用256個5 * 5大小的過濾器filter對96 * 27 * 27個特徵圖,進行進一步提取特徵第二層輸入數據。第一層輸出的27 * 27 * 96的像素層,爲便於後續處理,每幅像素層的左右兩邊和上下兩邊都要填充2個像素27 * 27 * 96的像素數據分成27 * 27 * 48的兩組像素數據,兩組數據分別再兩個不同的GPU中進行運算。每組像素數據被5 * 5 * 48的卷積核進行卷積運算,卷積覈對每組數據的每次卷積都生成一個新的像素。在卷積的過程中,因爲步長是1個像素。因此,卷積核在移動的過程中會生成(27-5+2 * 2)/1+1=27個像素。(加上上下、左右各填充的2個像素,即生成27個像素,),行和列的27 * 27個像素形成對原始圖像卷積之後的像素層。共有256個5 * 5 * 48卷積核;這256個卷積核分成兩組,每組針對一個GPU中的27 * 27 * 48的像素進行卷積運算。會生成兩組27 * 27 * 128個卷積後的像素層。

2.這些像素層經過relu2單元的處理,生成激活像素層,尺寸仍爲兩組27 * 27 * 128的像素層。

3.這些像素層經過pool運算(最大池化)的處理,池化運算的尺度爲3 * 3,運算的步長爲2,則池化後圖像的尺寸爲(57-3)/2+1=13。 即池化後像素的規模爲2組13 * 13 * 128的像素層。

4.最後經過歸一化處理,歸一化運算的尺度爲5 * 5;第二卷積層運算結束後形成的像素層的規模爲2組13 * 13 * 128的像素層。分別對應2組128個卷積核所運算形成。每組在一個GPU上進行運算。即共256個卷積核,共2個GPU進行運算。

3.conv3

layer {
  name: "conv3"
  type: "Convolution"
  bottom: "pool2"
  top: "conv3"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
  }
}
layer {
  name: "relu3"
  type: "ReLU"
  bottom: "conv3"
  top: "conv3"
}


1.第三層沒有使用池化層,只有一個卷積層與另外一個激活函數。

2.輸入數據爲第二層輸出的2組13 * 13 * 128的像素層;爲便於後續處理,每幅像素層的左右兩邊和上下兩邊都要填充1個像素;2組像素層數據都被送至2個不同的GPU中進行運算。每個GPU中都有192個卷積核,每個卷積核的尺寸是3 * 3 * 256。因此,每個GPU中的卷積核都能對2組13 * 13 * 128的像素層的所有數據進行卷積運算。卷積覈對每組數據的每次卷積都生成一個新的像素。stride步長是1個像素。因此,運算後的卷積核的尺寸爲(13-3+1 * 2)/1+1=13(13個像素減去3,正好是10,在加上上下、左右各填充的1個像素,即生成12個像素,再加上被減去的3也對應生成一個像素),每個GPU中共13 * 13 * 192個卷積核。2個GPU中共13 * 13 * 384個卷積後的像素層。

3.這些像素層經過激活函數relu3,尺寸仍爲2組13 * 13 * 192像素層,共13 * 13 * 384個像素層。

4.conv4

layer {
  name: "conv4"
  type: "Convolution"
  bottom: "conv3"
  top: "conv4"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 384
    pad: 1
    kernel_size: 3
    group: 2
  }
}
layer {
  name: "relu4"
  type: "ReLU"
  bottom: "conv4"
  top: "conv4"
}


1.本卷積層沒有使用池化降採樣層,這一層的內容與第三層一致,就不贅述了。

5.conv5

layer {
  name: "conv5"
  type: "Convolution"
  bottom: "conv4"
  top: "conv5"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
    group: 2
  }
}
layer {
  name: "relu5"
  type: "ReLU"
  bottom: "conv5"
  top: "conv5"
}
layer {
  name: "pool5"
  type: "Pooling"
  bottom: "conv5"
  top: "pool5"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}


1.輸入數據2組13 * 13 * 192的像素層;爲便於後續處理,每幅像素層的左右兩邊和上下兩邊都要填充1個像素;2組像素層數據都被送至2個不同的GPU中進行運算。每個GPU中都有128個卷積核,每個卷積核的尺寸是3 * 3 * 192。因此,每個GPU中的卷積核能對1組13 * 13 * 192的像素層的數據進行卷積運算。卷積覈對每組數據的每次卷積都生成一個新的像素。stride步長是1個像素。因此,運算後的卷積核的尺寸爲(13-3+1 * 2)/1+1=13(在加上上下、左右各填充的1個像素,共生成13個像素),每個GPU中共1313128個卷積核。2個GPU中共13 * 13 * 256個卷積後的像素層。

2.這些像素層經過激活函數relu5單元處理,尺寸仍爲2組13 * 13 * 128像素層,共13 * 13 * 256個像素層。

3.2組13 * 13 * 128像素層分別在2個不同GPU中進行池化(最大池化)處理。池化運算的尺度爲3 * 3,運算的步長爲2,則池化後圖像的尺寸爲(13-3)/2+1=6。 即池化後像素的規模爲兩組6 * 6 * 128的像素層數據,共6 * 6 * 256規模的像素層數據。

6.fc6
layer {
  name: "fc6"
  type: "InnerProduct"
  bottom: "pool5"
  top: "fc6"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
  }
}
layer {
  name: "relu6"
  type: "ReLU"
  bottom: "fc6"
  top: "fc6"
}
layer {
  name: "drop6"
  type: "Dropout"
  bottom: "fc6"
  top: "fc6"
  dropout_param {
    dropout_ratio: 0.5
  }
}


1.Dropout說的簡單一點就是我們讓在前向傳導的時候,讓某個神經元的激活值以一定的概率p,讓其停止工作。

2.輸入數據的尺寸是6 * 6 * 256,採用6 * 6 * 256尺寸的濾波器對輸入數據進行卷積運算;每個6 * 6* 256尺寸的濾波器對第六層的輸入數據進行卷積運算生成一個運算結果,通過一個神經元輸出這個運算結果;共有4096個6 * 6 * 256尺寸的濾波器對輸入數據進行卷積運算,通過4096個神經元輸出運算結果;

3.這4096個運算結果通過relu激活函數生成4096個值;

4.在dropout中是說在訓練的以1/2概率使得隱藏層的某些neuron的輸出爲0,這樣就丟到了一半節點的輸出,BP的時候也不更新這些節點。通過drop運算後輸出4096個本層的輸出結果值。

7.fc7

layer {
  name: "fc7"
  type: "InnerProduct"
  bottom: "fc6"
  top: "fc7"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 4096
  }
}
layer {
  name: "relu7"
  type: "ReLU"
  bottom: "fc7"
  top: "fc7"
}
layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7"
  top: "fc7"
  dropout_param {
    dropout_ratio: 0.5
  }
}


1.輸入的4096個數據與第七層的4096個神經元進行全連接;

2.操作如同然後上一層一樣經由relu7進行處理後生成4096個數據;

3.再經過dropout7(同樣是以0.5的概率)處理後輸出4096個數據。

8.fc8

layer {
  name: "fc8"
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8"
  param {
    lr_mult: 1
    decay_mult: 1
  }
  param {
    lr_mult: 2
    decay_mult: 0
  }
  inner_product_param {
    num_output: 1000
  }
}
layer {
  name: "prob"
  type: "Softmax"
  bottom: "fc8"
  top: "prob"
}


1.第七層輸出的4096個數據與第八層的1000個神經元進行全連接,經過訓練後輸出被訓練的數值。

附註:
ReLU和多個GPU        
    爲了提高訓練速度,AlexNet使用ReLU代替了Sigmoid,其能更快的訓練,同時解決sigmoid在訓練較深的網絡中出現的梯度消失,或者說梯度彌散的問題.

重疊的pool池化        
    提高精度, 不容易產生過擬合,在以前的CNN中普遍使用平均池化層,AlexNet全部使用最大池化層,避免了平均池化層的模糊化的效果,並且步長比池化的核的尺寸小,這樣池化層的輸出之間有重疊,提升了特徵的豐富性.

局部響應歸一化             
    提高精度,局部響應歸一化,對局部神經元創建了競爭的機制,使得其中響應小打的值變得更大,並抑制反饋較小的.

數據增益 Dropout       
減少過擬合,使用數據增強的方法緩解過擬合現象


各個網絡層的作用簡析:
卷積層:
    卷積層是整個神經網絡中最重要的一層,該層最核心的部分爲過濾器,或者稱爲卷積核,卷積核有大小和深度兩個屬性,大小常用的有3X3、5X5,也有11X11的卷積核,而深度通俗一點理解就是卷積核的個數。卷積核的大小和深度均由人工指定,而權重參數則在初始化的時候由程序隨機生成,並在後期訓練過程中不斷優化這些權重值,以達到最好的分類效果。卷積的過程就是用這些權重值不斷的去乘這些圖片的RGB值,以提取圖片數據信息。卷積不僅提取了圖片信息,也可以達到降維效果。如果希望卷積後的特徵值維度和原圖片一致,需要設置padding值(全零填充)爲SAME(如果爲VALID表示不填充),其中i爲輸入圖片,k爲卷積核大小,strides爲移動步長(移動步長>1也可以達到降維的效果)。

    在卷積層中,過濾器中的參數是共享的,即一個過濾器中的參數值在對所有圖片數據進行卷積過程中保持不變,這樣卷積層的參數個數就和圖片大小無關,它只和過濾器的尺寸,深度,以及當前層節點的矩陣深度有關。比如,以手寫圖片爲例,輸入矩陣的維度是28X28X1,假設第一層卷積層使用的過濾器大小爲5X5,深度爲16,則該卷積層的參數個數爲5X5X1X16+16=416個,而如果使用500個隱藏節點的全鏈層會有1.5百萬個參數,相比之下,卷積層的參數個數遠遠小於全鏈層,這就是爲什麼卷積網絡廣泛用於圖片識別上的原因。

    卷積計算完成後,往往會加入一個修正線性單元ReLU函數,也就是把數據非線性化。爲什麼要把數據進行非線性化呢,這是因爲非線性代表了輸入和輸出的關係是一條曲線而不是直線,曲線能夠刻畫輸入中更爲複雜的變化。比如一個輸入值大部分時間都很穩定,但有可能會在某個時間點出現極值,但是通過ReLU函數以後,數據變得平滑,這樣以便對複雜的數據進行訓練。    ReLU是分段線性的,當輸入爲非負時,輸出將與輸入相同;而當輸入爲負時,輸出均爲0。它的優點在於不受“梯度消失”的影響,且取值範圍爲[0,+∞];其缺點在於當使用了較大的學習速率時,易受達到飽和的神經元的影響。

池化層:
    卷積層後一般會加入池化層,池化層可以非常有效地縮小矩陣的尺寸,從而減少最後全鏈層中的參數,使用池化層既可以加快計算速度也有防止過擬合問題的作用。    池化層也存在一個過濾器,但是過濾器對於輸入的數據的處理並不是像卷積覈對輸入數據進行節點的加權和,而只是簡單的計算最大值或者平均值。過濾器的大小、是否全0填充、步長等也是由人工指定,而深度跟卷積核深度不一樣,卷積層使用過濾器是橫跨整個深度的,而池化層使用的過濾器隻影響一個深度上的節點,在計算過程中,池化層過濾器不僅要在長和寬兩個維度移動,還要在深度這個維度移動。使用最大值操作的池化層被稱之爲最大池化層,這種池化層使用得最多,使用平均值操作的池化層被稱之爲平均池化層,這種池化層的使用相對要少一點。

全連接層:
    在KNN或線性分類中有對數據進行歸一化處理,而在神經網絡中,也會做數據歸一化的處理,原因和之前的一樣,避免數據值大的節點對分類造成影響。歸一化的目標在於將輸入保持在一個可接受的範圍內。例如,將輸入歸一化到[0.0,1.0]區間內。在卷積神經網絡中,對數據歸一化的處理我們有可能放在數據正式輸入到全鏈層之前或之後,或其他地方,每個網絡都可能不一樣。

    全鏈層的作用就是進行正確的圖片分類,不同神經網絡的全鏈層層數不同,但作用確是相同的。輸入到全鏈層的神經元個數通過卷積層和池化層的處理後大大的減少了,比如以AlexNet爲例,一張227*227大小,顏色通道數爲3的圖片經過處理後,輸入到全鏈層的神經元個數有4096個,最後softmax的輸出,則可以根據實際分類標籤數來定。

在全鏈層中,會使用dropout以隨機的去掉一些神經元,這樣能夠比較有效地防止神經網絡的過擬合。相對於一般如線性模型使用正則的方法來防止模型過擬合,而在神經網絡中Dropout通過修改神經網絡本身結構來實現。對於某一層神經元,通過定義的概率來隨機刪除一些神經元,同時保持輸入層與輸出層神經元的個人不變,然後按照神經網絡的學習方法進行參數更新,下一次迭代中,重新隨機刪除一些神經元,直至訓練結束。

參考文章:

https://www.cnblogs.com/gongxijun/p/6027747.html

https://blog.csdn.net/hjimce/article/details/50413257https://blog.csdn.net/taoyanqi8932/article/details/71081390
————————————————
版權聲明:本文爲CSDN博主「Rasin_Wu」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Rasin_Wu/article/details/80017920

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章