天天看點

了解Caffe的網絡模型

目錄

  • ​​1. 初見LeNet原始模型​​
  • ​​2. Caffe LeNet的網絡結構​​
  • ​​3. 逐層了解Caffe LeNet​​
  • ​​3.1 Data Layer​​
  • ​​3.2 Conv1 Layer​​
  • ​​3.3 Pool1 Layer​​
  • ​​3.4 Conv2 Layer​​
  • ​​3.5 Pool2 Layer​​
  • ​​3.6 Ip1 Layer​​
  • ​​3.7 Relu1 Layer​​
  • ​​3.8 Ip2 Layer​​
  • ​​3.9 Loss Layer​​

1. 初見LeNet原始模型

​​

了解Caffe的網絡模型

​​

Fig.1. Architecture of original LeNet-5.

圖檔來源: Lecun, et al., Gradient-based learning applied to document recognition, P IEEE, vol. 86, no. 11, 1998, pp. 2278-2324.

在這篇圖檔的論文中,較長的描述了LeNet-5的結構。

這裡不對LeNet-5原始模型進行讨論。可以參考這些資料:

​​回到頂部(go to top)​​

2. Caffe LeNet的網絡結構

他山之石,可以攻玉。本來是準備畫出Caffe LeNet的圖的,但發現已經有人做了,并且畫的很好,就直接拿過來輔助了解了。

第3部分圖檔來源:​​http://www.2cto.com/kf/201606/518254.html​​

先從整體上感覺Caffe LeNet的拓撲圖,由于Caffe中定義網絡的結構采用的是bottom&top這種上下結構,是以這裡的圖也采用這種方式展現出來,更加友善了解。

​​

了解Caffe的網絡模型

​​

Fig.2. Architecture of caffe LeNet.

3. 逐層了解Caffe LeNet
本節将采用定義與圖解想結合的方式逐層了解Caffe LeNet的結構。

3.1 Data Layer
#==============定義TRAIN的資料層============================================
layer { 
  name: "mnist" #定義該層的名字
  type: "Data"  #該層的類型是資料
  top: "data"   #該層生成一個data blob
  top: "label"  #該層生成一個label blob
  include {
    phase: TRAIN #說明該層隻在TRAIN階段使用
  }
  transform_param {
    scale: 0.00390625 #資料歸一化系數,1/256,歸一到[0,1)
  }
  data_param {
    source: "E:/MyCode/DL/caffe-master/examples/mnist/mnist_train_lmdb" #訓練資料的路徑
    batch_size: 64 #批量處理的大小
    backend: LMDB
  }
}
#==============定義TEST的資料層============================================
layer { 
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST #說明該層隻在TEST階段使用
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "E:/MyCode/DL/caffe-master/examples/mnist/mnist_test_lmdb" #測試資料的路徑
    batch_size: 100
    backend: LMDB
  }
}
2

Fig.3. Architecture of data layer.

Fig.3 是train情況下,資料層讀取lmdb資料,每次讀取64條資料,即N=64。

Caffe中采用4D表示,N*C*H*W(Num*Channels*Height*Width)。

3.2 Conv1 Layer
#==============定義卷積層1=============================
layer {
  name: "conv1"       #該層的名字conv1,即卷積層1
  type: "Convolution" #該層的類型是卷積層
  bottom: "data"      #該層使用的資料是由資料層提供的data blob
  top: "conv1"        #該層生成的資料是conv1
  param {
    lr_mult: 1        #weight learning rate(簡寫為lr)權值的學習率,1表示該值是lenet_solver.prototxt中base_lr: 0.01的1倍
  }
  param {
    lr_mult: 2        #bias learning rate偏移值的學習率,2表示該值是lenet_solver.prototxt中base_lr: 0.01的2倍
  }
  convolution_param {
    num_output: 20    #産生20個輸出通道
    kernel_size: 5    #卷積核的大小為5*5
    stride: 1         #卷積核移動的步幅為1
    weight_filler {
      type: "xavier"  #xavier算法,根據輸入和輸出的神經元的個數自動初始化權值比例
    }
    bias_filler {
      type: "constant"  #将偏移值初始化為“穩定”狀态,即設為預設值0
    }
  }
}
3

Fig.4. Architecture of conv1 layer.

conv1的資料變化的情況:batch_size*1*28*28->batch_size*20*24*24

3.3 Pool1 Layer
#==============定義池化層1=============================
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"     #該層使用的資料是由conv1層提供的conv1
  top: "pool1"        #該層生成的資料是pool1
  pooling_param {
    pool: MAX         #采用最大值池化
    kernel_size: 2    #池化核大小為2*2
    stride: 2         #池化核移動的步幅為2,即非重疊移動
  }
}
4

Fig.5. Architecture of pool1 layer.

池化層1過程資料變化:batch_size*20*24*24->batch_size*20*12*12

3.4 Conv2 Layer
#==============定義卷積層2=============================
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
conv2層的圖與Fig.4 類似,卷積層2過程資料變化:batch_size*20*12*12->batch_size*50*8*8。

3.5 Pool2 Layer
#==============定義池化層2=============================
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
pool2層圖與Fig.5類似,池化層2過程資料變化:batch_size*50*8*8->batch_size*50*4*4。

3.6 Ip1 Layer
#==============定義全連接配接層1=============================
layer {
  name: "ip1"
  type: "InnerProduct" #該層的類型為全連接配接層
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500 #有500個輸出通道
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
5

Fig.6. Architecture of ip11 layer.

ip1過程資料變化:batch_size*50*4*4->batch_size*500*1*1。

此處的全連接配接是将C*H*W轉換成1D feature vector,即800->500.

3.7 Relu1 Layer
#==============定義ReLU1層=============================
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}
6
Fig.7. Architecture of relu1 layer.
ReLU1層過程資料變化:batch_size*500*1*1->batch_size*500*1*1

3.8 Ip2 Layer
#==============定義全連接配接層2============================
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10          #10個輸出資料,對應0-9十個數字
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
ip2過程資料變化:batch_size*500*1*1->batch_size*10*1*1

3.9 Loss Layer
#==============定義損失函數層============================
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip2"
  bottom: "label"
  top: "loss"
}
7

Fig.8. Architecture of loss layer.

損失層過程資料變化:batch_size*10*1*1->batch_size*10*1*1

note:注意到caffe LeNet中有一個accuracy layer的定義,這是輸出測試結果的層。

回到頂部(go to top)
4. Caffe LeNet的完整定義
name: "LeNet" #定義網絡的名字
#==============定義TRAIN的資料層============================================
layer { 
  name: "mnist" #定義該層的名字
  type: "Data"  #該層的類型是資料
  top: "data"   #該層生成一個data blob
  top: "label"  #該層生成一個label blob
  include {
    phase: TRAIN #說明該層隻在TRAIN階段使用
  }
  transform_param {
    scale: 0.00390625 #資料歸一化系數,1/256,歸一到[0,1)
  }
  data_param {
    source: "E:/MyCode/DL/caffe-master/examples/mnist/mnist_train_lmdb" #訓練資料的路徑
    batch_size: 64 #批量處理的大小
    backend: LMDB
  }
}
#==============定義TEST的資料層============================================
layer { 
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST #說明該層隻在TEST階段使用
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "E:/MyCode/DL/caffe-master/examples/mnist/mnist_test_lmdb" #測試資料的路徑
    batch_size: 100
    backend: LMDB
  }
}
#==============定義卷積層1=============================
layer {
  name: "conv1"       #該層的名字conv1,即卷積層1
  type: "Convolution" #該層的類型是卷積層
  bottom: "data"      #該層使用的資料是由資料層提供的data blob
  top: "conv1"        #該層生成的資料是conv1
  param {
    lr_mult: 1        #weight learning rate(簡寫為lr)權值的學習率,1表示該值是lenet_solver.prototxt中base_lr: 0.01的1倍
  }
  param {
    lr_mult: 2        #bias learning rate偏移值的學習率,2表示該值是lenet_solver.prototxt中base_lr: 0.01的2倍
  }
  convolution_param {
    num_output: 20    #産生20個輸出通道
    kernel_size: 5    #卷積核的大小為5*5
    stride: 1         #卷積核移動的步幅為1
    weight_filler {
      type: "xavier"  #xavier算法,根據輸入和輸出的神經元的個數自動初始化權值比例
    }
    bias_filler {
      type: "constant"  #将偏移值初始化為“穩定”狀态,即設為預設值0
    }
  }
}#卷積過程資料變化:batch_size*1*28*28->batch_size*20*24*24
#==============定義池化層1=============================
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"     #該層使用的資料是由conv1層提供的conv1
  top: "pool1"        #該層生成的資料是pool1
  pooling_param {
    pool: MAX         #采用最大值池化
    kernel_size: 2    #池化核大小為2*2
    stride: 2         #池化核移動的步幅為2,即非重疊移動
  }
}#池化層1過程資料變化:batch_size*20*24*24->batch_size*20*12*12
#==============定義卷積層2=============================
layer {
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}#卷積層2過程資料變化:batch_size*20*12*12->batch_size*50*8*8
#==============定義池化層2=============================
layer {
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}#池化層2過程資料變化:batch_size*50*8*8->batch_size*50*4*4
#==============定義全連接配接層1=============================
layer {
  name: "ip1"
  type: "InnerProduct" #該層的類型為全連接配接層
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500 #有500個輸出通道
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}#全連接配接層1過程資料變化:batch_size*50*4*4->batch_size*500*1*1
#==============定義ReLU1層=============================
layer {
  name: "relu1"
  type: "ReLU"
  bottom: "ip1"
  top: "ip1"
}#ReLU1層過程資料變化:batch_size*500*1*1->batch_size*500*1*1
#==============定義全連接配接層2============================
layer {
  name: "ip2"
  type: "InnerProduct"
  bottom: "ip1"
  top: "ip2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10          #10個輸出資料,對應0-9十個數字
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}#全連接配接層2過程資料變化:batch_size*500*1*1->batch_size*10*1*1
#==============定義顯示準确率結果層============================
layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip2"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}
#==============定義損失函數層============================
layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip2"
  bottom: "label"
  top: "loss"
}#損失層過程資料變化:batch_size*10*1*1->batch_size*10*1*1