1. 程式人生 > >Layers Of Caffe

Layers Of Caffe

vat 區別 https 過濾 ase beta 例子 測試的 bottom

  本文試圖描述構建一個網絡結構的layers,可以用prototxt腳本直接寫,也可以用python接口實現。

  最簡單的神經網絡包含但不限於以下四部分:

        數據層(Data): Data、ImageData

        激活層(Activation): sigmoid、tanh、relu

        視覺層(vision) :Convolution、Pooling、 Local Response Normalization (LRN)、 im2col

        輸出層(output): softmax_loss、Inner Product、accuracy、reshape、dropout

A、數據層(Data)

  數據層是每個模型的最底層,是模型的入口,不僅提供數據的輸入,也提供數據從Blobs轉換成別的格式進行保存輸出。通常數據的預處理(如減去均值, 放大縮小, 裁剪和鏡像等),也在這一層設置參數實現。

  數據來源來自:

  高效率:高效的數據庫(如LevelDB和LMDB)、內存;

  低效率:磁盤的hdf5文件、圖片格式文件。

所有的數據層的都具有的公用參數:

layer {
  name: "cifar"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mean_file: 
"examples/cifar10/mean.binaryproto" scale: 0.00390625 # 用一個配置文件來進行均值操作 mirror: 1 # 1表示開啟鏡像,0表示關閉,也可用ture和false來表示 # 剪裁一個 227*227的圖塊,在訓練階段隨機剪裁,在測試階段從中間裁剪 如果超過這個數據就會裁剪 crop_size: 227 shuffle: true  #隨機打亂數據 } data_param { source: "examples/cifar10/cifar10_train_lmdb" batch_size:
100 backend: LMDB } }

name: 表示該層的名稱,可隨意取

type: 層類型,如果是Data,表示數據來源於LevelDB或LMDB。根據數據的來源不同,數據層的類型也不同(後面會詳細闡述)。一般在練習的時候,我們都是采 用的LevelDB或LMDB數據,因此層類型設置為Data。

top或bottom: 每一層用bottom來輸入數據,用top來輸出數據。如果只有top沒有bottom,則此層只有輸出,沒有輸入。反之亦然。如果有多個 top或多個bottom,表示有多個blobs數據的輸入和輸出。

data 與 label: 在數據層中,至少有一個命名為data的top。如果有第二個top,一般命名為label。 這種(data,label)配對是分類模型所必需的。

include: 一般訓練的時候和測試的時候,模型的層是不一樣的。該層(layer)是屬於訓練階段的層,還是屬於測試階段的層,需要用include來指定。如果沒有include參數,則表示該層既在訓練模型中,又在測試模型中。

Transformations: 數據的預處理,可以將數據變換到定義的範圍內。如設置scale為0.00390625,實際上就是1/255, 即將輸入數據由0-255歸一化到0-1之間

1、數據來自於數據庫(如LevelDB和LMDB)

  LMDB數據制作:圖像數據轉換成db(leveldb/lmdb)文件

  計算均值文件(非必須)計算圖片數據的均值

層類型(layer type):Data

必須設置的參數:

source: 包含數據庫的目錄名稱,如examples/mnist/mnist_train_lmdb

batch_size: 每次處理的數據個數,如64

可選的參數:

rand_skip: 在開始的時候,路過某個數據的輸入。通常對異步的SGD很有用。

backend: 選擇是采用LevelDB還是LMDB, 默認是LevelDB.

layer {
  name: "mnist"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    scale: 0.00390625
  }
  data_param {
    source: "examples/mnist/mnist_train_lmdb"
    batch_size: 64
    backend: LMDB
  }
}

2、數據來自於圖片image

層類型:ImageData

必須設置的參數:

source: 一個文本文件的名字,每一行給定一個圖片文件的名稱和標簽(label)

 /iamges/aaa.jpg 0

/images/bbb.jpg 1

batch_size: 每一次處理的數據個數,即圖片數

可選參數:

rand_skip: 在開始的時候,路過某個數據的輸入。通常對異步的SGD很有用。

shuffle: 隨機打亂順序,默認值為false

new_height,new_width: 如果設置,則將圖片進行resize

layer {
  name: "data"
  type: "ImageData"
  top: "data"
  top: "label"
  transform_param {
    mirror: false
    crop_size: 227
    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"
  }
  image_data_param {
    source: "examples/_temp/file_list.txt"
    batch_size: 50
    new_height: 256
    new_width: 256
  }
}

B、激活層(Activation)

在激活層中,對輸入數據進行激活操作(實際上就是一種函數變換),是逐元素進行運算的。從bottom得到一個blob數據輸入,運算後,從top輸入一個blob數據。在運算過程中,沒有改變數據的大小,即輸入和輸出的數據大小是相等的。

輸入:n*c*h*w

輸出:n*c*h*w

常用的激活函數有sigmoid, tanh,relu等,下面分別介紹。

1、Sigmoid

對每個輸入數據,利用sigmoid函數執行操作。這種層設置比較簡單,沒有額外的參數。

技術分享圖片

層類型:Sigmoid

示例:

layer {
  name: "encode1neuron"
  bottom: "encode1"
  top: "encode1neuron"
  type: "Sigmoid"
}

python代碼:

2、ReLU / Rectified-Linear and Leaky-ReLU

ReLU是目前使用最多的激活函數,主要因為其收斂更快,並且能保持同樣效果。

標準的ReLU函數為max(x, 0),當x>0時,輸出x; 當x<=0時,輸出0

f(x)=max(x,0)

層類型:ReLU

可選參數:

  negative_slope:默認為0. 對標準的ReLU函數進行變化,如果設置了這個值,那麽數據為負數時,就不再設置為0,而是用原始數據乘以negative_slope

layer {
  name: "relu1"
  type: "ReLU"
  bottom: "pool1"
  top: "pool1"
}

RELU層支持in-place計算,這意味著bottom的輸出和輸入相同以避免內存的消耗。

python代碼實現

relu = Layers.ReLU(inputs, in_place=True)

3、TanH / Hyperbolic Tangent

利用雙曲正切函數對數據進行變換。

技術分享圖片

層類型:TanH

layer {
  name: "layer"
  bottom: "in"
  top: "out"
  type: "TanH"
}

4、Absolute Value

求每個輸入數據的絕對值。

f(x)=Abs(x)

層類型:AbsVal

layer {
  name: "layer"
  bottom: "in"
  top: "out"
  type: "AbsVal"
}

5、Power

對每個輸入數據進行冪運算

f(x)= (shift + scale * x) ^ power

層類型:Power

可選參數:

  power: 默認為1

  scale: 默認為1

  shift: 默認為0

layer {
  name: "layer"
  bottom: "in"
  top: "out"
  type: "Power"
  power_param {
    power: 2
    scale: 1
    shift: 0
  }
}

6、BNLL

binomial normal log likelihood的簡稱

f(x)=log(1 + exp(x))

層類型:BNLL

layer {
  name: "layer"
  bottom: "in"
  top: "out"
  type: “BNLL”
}

C、視覺層(vision)

視覺層(Vision Layers)的參數,視覺層包括Convolution, Pooling, Local Response Normalization (LRN), im2col等層。

前一節中Data層用python代碼實現:

data, label = L.Data(source=lmbd_file, backend=P.Data.LMDB, batch_size=batch_size_num,ntop=2,transform_parm=dict(crop_size=40,mean_file=mean_file,mirror=True))

這塊預留ImageData的python實現代碼:

1、Convolution層:

就是卷積層,是卷積神經網絡(CNN)的核心層。

層類型:Convolution

  lr_mult: 學習率的系數,最終的學習率是這個數乘以solver.prototxt配置文件中的base_lr。如果有兩個lr_mult, 則第一個表示權值的學習率,第二個表示偏置項的學習率。一般偏置項的學習率是權值學習率的兩倍。

在後面的convolution_param中,我們可以設定卷積層的特有參數。

必須設置的參數:

  num_output: 卷積核(filter)的個數

  kernel_size: 卷積核的大小。如果卷積核的長和寬不等,需要用kernel_h和kernel_w分別設定

其它參數:

   stride: 卷積核的步長,默認為1。也可以用stride_h和stride_w來設置。

   pad: 擴充邊緣,默認為0,不擴充。 擴充的時候是左右、上下對稱的,比如卷積核的大小為5*5,那麽pad設置為2,則四個邊緣都擴充2個像素,即寬度和高度都擴充了4個像素,這樣卷積運算之後的特征圖就不會變小。也可以通過pad_h和pad_w來分別設定。

  weight_filler: 權值初始化。 默認為“constant",值全為0,很多時候我們用"xavier"算法來進行初始化,也可以設置為”gaussian"   bias_filler: 偏置項的初始化。一般設置為"constant",值全為0。    bias_term: 是否開啟偏置項,默認為true, 開啟    group: 分組,默認為1組。如果大於1,我們限制卷積的連接操作在一個子集內。如果我們根據圖像的通道來分組,那麽第i個輸出分組只能與第i個輸入分組進行連接。 輸入:n*c0*w0*h0 輸出:n*c1*w1*h1 其中,c1就是參數中的num_output,生成的特征圖個數 w1=(w0+2*pad-kernel_size)/stride+1; h1=(h0+2*pad-kernel_size)/stride+1; 如果設置stride為1,前後兩次卷積部分存在重疊。如果設置pad=(kernel_size-1)/2,則運算後,寬度和高度不變。 示例:
layer {
  name: "conv1"
  type: "Convolution"
  bottom: "data"
  top: "conv1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 20
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"  #或者使用高斯進行初始化
    }
    bias_filler {
      type: "constant"  #0
    }
  }
}

用python代碼實現:

conv1 = Layer.Convolution(data,kernel_size=5, stride=1, num_output=16,pad=2,weight_filler=dict(type=‘xavier‘))

參數:

  data為數據層傳遞的數據

2、Pooling層

也叫池化層,為了減少運算量和數據維度而設置的一種層。 層類型:Pooling 必須設置的參數:    kernel_size: 池化的核大小。也可以用kernel_h和kernel_w分別設定。 其它參數:  pool: 池化方法,默認為MAX。目前可用的方法有MAX, AVE(平均池化), 或STOCHASTIC   pad: 和卷積層的pad的一樣,進行邊緣擴充。默認為0   stride: 池化的步長,默認為1。一般我們設置為2,即不重疊。也可以用stride_h和stride_w來設置。 示例:
layer {
  name: "pool1"
  type: "Pooling"
  bottom: "conv1"
  top: "pool1"
  pooling_param {
    pool: MAX
    kernel_size: 3
    stride: 2
  }
}

pooling層的運算方法基本是和卷積層是一樣的。

輸入:n*c*w0*h0 輸出:n*c*w1*h1 和卷積層的區別就是其中的c保持不變 w1=(w0+2*pad-kernel_size)/stride+1; h1=(h0+2*pad-kernel_size)/stride+1; 如果設置stride為2,前後兩次卷積部分不重疊。100*100的特征圖池化後,變成50*50. python實現代碼:
pool1 = Layer.Pooling(inputs,pool=Pooling.Max,kernel_size=3,stride=2)
3、Local Response Normalization (LRN)層 此層是對一個輸入的局部區域進行歸一化,達到“側抑制”的效果。可去搜索AlexNet或GoogLenet,裏面就用到了這個功能 層類型:LRN 參數:全部為可選,沒有必須   local_size: 默認為5。如果是跨通道LRN,則表示求和的通道數;如果是在通道內LRN,則表示求和的正方形區域長度。   alpha: 默認為1,歸一化公式中的參數。   beta: 默認為5,歸一化公式中的參數。   norm_region: 默認為ACROSS_CHANNELS。有兩個選擇,ACROSS_CHANNELS表示在相鄰的通道間求和歸一化。WITHIN_CHANNEL表示在一個通道內部特定的區域內進行求和歸一化。與前面的local_size參數對應。 歸一化公式:對於每一個輸入, 去除以技術分享圖片,得到歸一化後的輸出 示例:
layers {
  name: "norm1"
  type: LRN
  bottom: "pool1"
  top: "norm1"
  lrn_param {
    local_size: 5
    alpha: 0.0001
    beta: 0.75
  }
}

python代碼實現:

待續。。

4、im2col層

如果對matlab比較熟悉的話,就應該知道im2col是什麽意思。它先將一個大矩陣,重疊地劃分為多個子矩陣,對每個子矩陣序列化成向量,最後得到另外一個矩陣。

看一看圖就知道了:

技術分享圖片

在caffe中,卷積運算就是先對數據進行im2col操作,再進行內積運算(inner product)。這樣做,比原始的卷積操作速度更快。

看看兩種卷積操作的異同:

技術分享圖片

D、輸出層(output)

包括:softmax_loss層,Inner Product層,accuracy層,reshape層和dropout層及其它們的參數配置。

1、softmax-loss

softmax-loss層和softmax層計算大致是相同的。softmax是一個分類器,計算的是類別的概率(Likelihood),是Logistic Regression 的一種推廣。Logistic Regression 只能用於二分類,而softmax可以用於多分類。

softmax與softmax-loss的區別:

softmax計算公式:

技術分享圖片

而softmax-loss計算公式:

技術分享圖片

關於兩者的區別更加具體的介紹,可參考:softmax vs. softmax-loss

用戶可能最終目的就是得到各個類別的概率似然值,這個時候就只需要一個 Softmax層,而不一定要進行softmax-Loss 操作;或者是用戶有通過其他什麽方式已經得到了某種概率似然值,然後要做最大似然估計,此時則只需要後面的 softmax-Loss 而不需要前面的 Softmax 操作。因此提供兩個不同的 Layer 結構比只提供一個合在一起的 Softmax-Loss Layer 要靈活許多。

不管是softmax layer還是softmax-loss layer,都是沒有參數的,只是層類型不同而已

softmax-loss layer:輸出loss值

layer {
  name: "loss"
  type: "SoftmaxWithLoss"
  bottom: "ip1"
  bottom: "label"
  top: "loss"
}

softmax layer: 輸出似然值

layers {
  bottom: "cls3_fc"
  top: "prob"
  name: "prob"
  type: “Softmax"
}

python代碼:

loss = Layers.SoftmaxWithLoss(fc,label)  #label是數據層的label

2、Inner Product

全連接層,把輸入當作成一個向量,輸出也是一個簡單向量(把輸入數據blobs的width和height全變為1)。

輸入: n*c0*h*w

輸出: n*c1*1*1

全連接層實際上也是一種卷積層,只是它的卷積核大小和原數據大小一致。因此它的參數基本和卷積層的參數一樣。

層類型:InnerProduct

lr_mult: 學習率的系數,最終的學習率是這個數乘以solver.prototxt配置文件中的base_lr。如果有兩個lr_mult, 則第一個表示權值的學習率,第二個表示偏置項的學習率。一般偏置項的學習率是權值學習率的兩倍。

必須設置的參數:

  num_output: 過濾器(filfter)的個數

其它參數:

  weight_filler: 權值初始化。 默認為“constant",值全為0,很多時候我們用"xavier"算法來進行初始化,也可以設置為”gaussian"   bias_filler: 偏置項的初始化。一般設置為"constant",值全為0。    bias_term: 是否開啟偏置項,默認為true, 開啟
layer {
  name: "ip1"
  type: "InnerProduct"
  bottom: "pool2"
  top: "ip1"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}

 python實現代碼:

fc = Layers.InnerProduct(pool2, num_output=1024,weight_filler=dict(type=xavier))

3、accuracy

輸出分類(預測)精確度,只有test階段才有,因此需要加入include參數。

層類型:Accuracy

layer {
  name: "accuracy"
  type: "Accuracy"
  bottom: "ip2"
  bottom: "label"
  top: "accuracy"
  include {
    phase: TEST
  }
}

python代碼實現:

accurary = Layers.Accurary(fc,label)

4、reshape

在不改變數據的情況下,改變輸入的維度。

層類型:Reshape

先來看例子

layer {
    name: "reshape"
    type: "Reshape"
    bottom: "input"
    top: "output"
    reshape_param {
      shape {
        dim: 0  # copy the dimension from below
        dim: 2
        dim: 3
        dim: -1 # infer it from the other dimensions
      }
    }
  }

有一個可選的參數組shape, 用於指定blob數據的各維的值(blob是一個四維的數據:n*c*w*h)。

dim:0 表示維度不變,即輸入和輸出是相同的維度。

dim:2 或 dim:3 將原來的維度變成2或3

dim:-1 表示由系統自動計算維度。數據的總量不變,系統會根據blob數據的其它三維來自動計算當前維的維度值 。

假設原數據為:64*3*28*28, 表示64張3通道的28*28的彩色圖片

經過reshape變換:

reshape_param {
      shape {
        dim: 0 
        dim: 0
        dim: 14
        dim: -1 
      }
    }

輸出數據為:64*3*14*56

5、Dropout

Dropout是一個防止過擬合的trick。可以隨機讓網絡某些隱含層節點的權重不工作。

先看例子:

layer {
  name: "drop7"
  type: "Dropout"
  bottom: "fc7-conv"
  top: "fc7-conv"
  dropout_param {
    dropout_ratio: 0.5
  }
}

只需要設置一個dropout_ratio就可以了。

還有其它更多的層,但用的地方不多,就不一一介紹了。

隨著深度學習的深入,各種各樣的新模型會不斷的出現,因此對應的各種新類型的層也在不斷的出現。這些新出現的層,我們只有在等caffe更新到新版本後,再去慢慢地摸索了。

https://www.cnblogs.com/denny402/tag/caffe/

Layers Of Caffe