1. 程式人生 > >caffe網路模型詳解

caffe網路模型詳解

.資料層及引數

資料層是每個模型的最底層,是模型是入口,不僅提供資料的輸入,也提提供資料從Blobs轉化成別的格式進行儲存輸出。資料的預處理像去均值,放大縮小,裁剪和映象等操作都是在該層進行。

一般的資料的格式為LeveIDB和LMDB兩種。

layer {

  name: "data"

  type: "Data"

  top: "data"

  top: "label"

  include {

    phase: TRAIN

  }

  transform_param {

    scale:0.00390625

    mirror: true

    crop_size: 227

    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"

  }

  data_param {

    source: "examples/imagenet/ilsvrc12_train_lmdb"

    batch_size: 256

    backend: LMDB

  }

}

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

type表示層的型別,帶層的型別為”Data”,為資料層;

top或bottom:每一層用bottom表示輸入資料,用top表示輸出資料;

include:訓練和測試的時候是不一樣的,該層為訓練極端的層,如果沒有include則表示訓練和測試階段都要使用;

transform mations:資料的預處理,可以將資料轉換到定義的範圍內。如設定scale為0.00390625,實際上就是1/255,即將有0--255歸一劃到0--1之間。

mirror:表示開啟映象

crop_size:表示裁剪影象,上面所示為裁剪一個大小為277*277的影象,在訓練時隨機裁剪,在測試階段從中間裁剪。

  1. 資料來自於資料庫(如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、資料來自於記憶體

層型別:MemoryData

必須設定的引數:

 batch_size:每一次處理的資料個數,比如2

 channels:通道數

  height:高度

   width: 寬度

示例:

layer {

  top: "data"

  top: "label"

  name: "memory_data"

  type: "MemoryData"

  memory_data_param{

    batch_size: 2

    height: 100

    width: 100

    channels: 1

  }

  transform_param {

    scale: 0.0078125

    mean_file: "mean.proto"

    mirror: false

  }

}

3、資料來自於HDF5

層型別:HDF5Data

必須設定的引數:

source: 讀取的檔名稱

batch_size: 每一次處理的資料個數

示例:

layer {

  name: "data"

  type: "HDF5Data"

  top: "data"

  top: "label"

  hdf5_data_param {

    source: "examples/hdf5_classification/data/train.txt"

    batch_size: 10

  }

}

4、資料來自於圖片

層型別:ImageData

必須設定的引數:

  source: 一個文字檔案的名字,每一行給定一個圖片檔案的名稱和標籤(label)

  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

  }

}

5、資料來源於Windows

層型別:WindowData

必須設定的引數:

  source: 一個文字檔案的名字

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

示例:

layer {

  name: "data"

  type: "WindowData"

  top: "data"

  top: "label"

  include {

    phase: TRAIN

  }

  transform_param {

    mirror: true

    crop_size: 227

    mean_file: "data/ilsvrc12/imagenet_mean.binaryproto"

  }

  window_data_param {

    source: "examples/finetune_pascal_detection/window_file_2007_trainval.txt"

    batch_size: 128

    fg_threshold: 0.5

    bg_threshold: 0.5

    fg_fraction: 0.25

    context_pad: 16

    crop_mode: "warp"

  }

可選引數:

(1)mirror

(2)crop_size:裁剪的視窗的大小

(3)crop_mode:裁剪方式,“warps”代表將視窗固定大小crop_size,“square”表示能夠包圍視窗的最小正方形;預設“warp”

(4)fg_threshold:foreground overlap threshold ,預設0.5,代表只有BoundingBox與GroundTruth的重合面積比大於0.5時才認為是正樣本

(5)bg_threshold:background overlap threshold,預設0.5,代表只有BoundingBox與GroundTruth的重合比例小於0.5時才認為是負樣本

(6)fg_fraction:預設0.25,一個batch里正樣本視窗的比例

(7)context_pad:預設10個畫素點,代表輸入視窗資料的時候會自動在視窗周圍資料補充10個畫素點,畫素值填充0.

如下圖所示,最外圍的一圈即為context填充,此時context_pad為1:

}

  • 視覺層(Vision Layers)及引數

視覺層包括Convolution, Pooling, Local Response Normalization (LRN), im2col等層。

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"

    }

  }

}

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,前後兩次卷積部分重疊。

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

  }

}

  1. im2col

它先將一個大矩陣,重疊地劃分為多個子矩陣,對每個子矩陣序列化成向量,最後得到另外一個矩陣。

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

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

在啟用層中,對輸入資料進行啟用操作(實際上就是一種函式變換),是逐元素進行運算的。從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"

}

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的輸出和輸入相同以避免記憶體的消耗。

3TanH / Hyperbolic Tangent

利用雙曲正切函式對資料進行變換。

層型別:TanH

layer {

  name: "layer"

  bottom: "in"

  top: "out"

  type: "TanH"

}

4Absolute Value

求每個輸入資料的絕對值。

f(x)=Abs(x)

層型別:AbsVal

layer {

  name: "layer"

  bottom: "in"

  top: "out"

  type: "AbsVal"

}

5Power

對每個輸入資料進行冪運算

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

  }

}

6BNLL

binomial normal log likelihood的簡稱

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

層型別:BNLL

layer {

  name: "layer"

  bottom: "in"

  top: "out"

  type: “BNLL”

}

  • 其它常用層及引數

本文講解一些其它的常用層,包括:softmax_loss層,Inner Product層,accuracy層,reshape層和dropout層及其它們的引數配置。

1softmax-loss

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

softmax與softmax-loss的區別:

softmax計算公式:

而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"

}

2Inner 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"

    }

  }

}

3accuracy

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

層型別:Accuracy

layer {

  name: "accuracy"

  type: "Accuracy"

  bottom: "ip2"

  bottom: "label"

  top: "accuracy"

  include {

    phase: TEST

  }

}

4reshape

在不改變資料的情況下,改變輸入的維度。

層型別: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

5Dropout

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

先看例子:

layer {

  name: "drop7"

  type: "Dropout"

  bottom: "fc7-conv"

  top: "fc7-conv"

  dropout_param {

    dropout_ratio: 0.5

  }

}layer {

  name: "drop7"

  type: "Dropout"

  bottom: "fc7-conv"

  top: "fc7-conv"

  dropout_param {

    dropout_ratio: 0.5

  }

}

只需要設定一個dropout_ratio就可以了

  • Blob,Layer and Net以及對應配置檔案的編寫

深度網路(net)是一個組合模型,它由許多相互連線的層(layers)組合而成。Caffe就是組建深度網路的這樣一種工具,它按照一定的策略,一層一層的搭建出自己的模型。它將所有的資訊資料定義為blobs,從而進行便利的操作和通訊。Blob是caffe框架中一種標準的陣列,一種統一的記憶體介面,它詳細描述了資訊是如何儲存的,以及如何在層之間通訊的。

1blob

Blobs封裝了執行時的資料資訊,提供了CPU和GPU的同步。從數學上來說, Blob就是一個N維陣列。它是caffe中的資料操作基本單位,就像matlab中以矩陣為基本操作物件一樣。只是矩陣是二維的,而Blob是N維的。N可以是2,3,4等等。對於圖片資料來說,Blob可以表示為(N*C*H*W)這樣一個4D陣列。其中N表示圖片的數量,C表示圖片的通道數,H和W分別表示圖片的高度和寬度。當然,除了圖片資料,Blob也可以用於非圖片資料。比如傳統的多層感知機,就是比較簡單的全連線網路,用2D的Blob,呼叫innerProduct層來計算就可以了。

在模型中設定的引數,也是用Blob來表示和運算。它的維度會根據引數的型別不同而不同。比如:在一個卷積層中,輸入一張3通道圖片,有96個卷積核,每個核大小為11*11,因此這個Blob是96*3*11*11. 而在一個全連線層中,假設輸入1024通道圖片,輸出1000個數據,則Blob為1000*1024

2layer

層是網路模型的組成要素和計算的基本單位。層的型別比較多,如Data,Convolution,Pooling,ReLU,Softmax-loss,Accuracy等,一個層的定義大至如下圖:

從bottom進行資料的輸入 ,計算後,通過top進行輸出。圖中的黃色多邊形表示輸入輸出的資料,藍色矩形表示層。

每一種型別的層都定義了三種關鍵的計算:setup,forward and backword

setup: 層的建立和初始化,以及在整個模型中的連線初始化。

forward: 從bottom得到輸入資料,進行計算,並將計算結果送到top,進行輸出。

backward: 從層的輸出端top得到資料的梯度,計算當前層的梯度,並將計算結果送到bottom,向前傳遞。

3Net

就像搭積木一樣,一個net由多個layer組合而成。

現給出 一個簡單的2層神經網路的模型定義( 加上loss 層就變成三層了),先給出這個網路的拓撲。

第一層:name為mnist, type為Data,沒有輸入(bottom),只有兩個輸出(top),一個為data,一個為label

第二層:name為ip,type為InnerProduct, 輸入資料data, 輸出資料ip

第三層:name為loss, type為SoftmaxWithLoss,有兩個輸入,一個為ip,一個為label,有一個輸出loss,沒有畫出來。

對應的配置檔案prototxt就可以這樣寫:

name: "LogReg"

layer {

  name: "mnist"

  type: "Data"

  top: "data"

  top: "label"

  data_param {

    source: "input_leveldb"

    batch_size: 64

  }

}

layer {

  name: "ip"

  type: "InnerProduct"

  bottom: "data"

  top: "ip"

  inner_product_param {

    num_output: 2

  }

}

layer {

  name: "loss"

  type: "SoftmaxWithLoss"

  bottom: "ip"

  bottom: "label"

  top: "loss"

}

第一行將這個模型取名為LogReg, 然後是三個layer的定義,引數都比較簡單,只列出必須的引數。

六.Solver及其配置

solver算是caffe的核心的核心,它協調著整個模型的運作。caffe程式執行必帶的一個引數就是solver配置檔案。執行程式碼一般為

# caffe train --solver=*_slover.prototxt

在Deep Learning中,往往loss function是非凸的,沒有解析解,我們需要通過優化方法來求解。solver的主要作用就是交替呼叫前向(forward)演算法和後向(backward)演算法來更新引數,從而最小化loss,實際上就是一種迭代的優化演算法。

到目前的版本,caffe提供了六種優化演算法來求解最優引數,在solver配置檔案中,通過設定type型別來選擇。

Stochastic Gradient Descent (type: "SGD"),

AdaDelta (type: "AdaDelta"),

Adaptive Gradient (type: "AdaGrad"),

Adam (type: "Adam"),

Nesterov’s Accelerated Gradient (type: "Nesterov") and

RMSprop (type: "RMSProp")

      具體的每種方法的介紹,請看本系列的下一篇文章, 本文著重介紹solver配置檔案的編寫。

Solver的流程:

1.設計好需要優化的物件,以及用於學習的訓練網路和用於評估的測試網路。(通過呼叫另外一個配置檔案prototxt來進行)

2.通過forward和backward迭代的進行優化來跟新引數。

3.定期的評價測試網路。(可設定多少次訓練後,進行一次測試)

4.在優化過程中顯示模型和solver的狀態

在每一次的迭代過程中,solver做了這幾步工作:

1、呼叫forward演算法來計算最終的輸出值,以及對應的loss

2、呼叫backward演算法來計算每層的梯度

3、根據選用的slover方法,利用梯度進行引數更新

4、記錄並儲存每次迭代的學習率、快照,以及對應的狀態。

接下來,我們先來看一個例項:

net: "examples/mnist/lenet_train_test.prototxt"

test_iter: 100

test_interval: 500

base_lr: 0.01

momentum: 0.9

type: SGD

weight_decay: 0.0005

lr_policy: "inv"

gamma: 0.0001

power: 0.75

display: 100

max_iter: 20000

snapshot: 5000

snapshot_prefix: "examples/mnist/lenet"

solver_mode: CPU

接下來,我們對每一行進行詳細解譯:

net: "examples/mnist/lenet_train_test.prototxt"

設定深度網路模型。每一個模型就是一個net,需要在一個專門的配置檔案中對net進行配置,每個net由許多的layer所組成。每一個layer的具體配置方式可參考本系列文文章中的(2)-(5)。注意的是:檔案的路徑要從caffe的根目錄開始,其它的所有配置都是這樣。

也可用train_net和test_net來對訓練模型和測試模型分別設定。例如:

train_net: "examples/hdf5_classification/logreg_auto_train.prototxt"

test_net: "examples/hdf5_classification/logreg_auto_test.prototxt"

接下來第二行:

test_iter: 100

這個要與test layer中的batch_size結合起來理解。mnist資料中測試樣本總數為10000,一次性執行全部資料效率很低,因此我們將測試資料分成幾個批次來執行,每個批次的數量就是batch_size。假設我們設定batch_size為100,則需要迭代100次才能將10000個數據全部執行完。因此test_iter設定為100。執行完一次全部資料,稱之為一個epoch

test_interval: 500

測試間隔。也就是每訓練500次,才進行一次測試。

base_lr: 0.01

lr_policy: "inv"

gamma: 0.0001

power: 0.75

這四行可以放在一起理解,用於學習率的設定。只要是梯度下降法來求解優化,都會有一個學習率,也叫步長。base_lr用於設定基礎學習率,在迭代的過程中,可以對基礎學習率進行調整。怎麼樣進行調整,就是調整的策略,由lr_policy來設定。

lr_policy可以設定為下面這些值,相應的學習率的計算為:

- fixed:保持base_lr不變.

- step: 如果設定為step,則還需要設定一個stepsize,  返回

      base_lr * gamma ^ (floor(iter / stepsize)),其中iter表示當前的迭代次數

- exp: 返回base_lr * gamma ^ iter, iter為當前迭代次數

- inv:如果設定為inv,還需要設定一個power, 返回base_lr * (1 + gamma * iter) ^ (- power)

- multistep: 如果設定為multistep,則還需要設定一個stepvalue。這個引數和step很相似,step是均勻等間隔變化,而multistep則是根據 stepvalue值變化

- poly:學習率進行多項式誤差, 返回 base_lr (1 - iter/max_iter) ^ (power)

- sigmoid:學習率進行sigmod衰減,返回 base_lr ( 1/(1 + exp(-gamma * (iter - stepsize))))

multistep示例:

base_lr: 0.01

momentum: 0.9

weight_decay: 0.0005

# The learning rate policy

lr_policy: "multistep"

gamma: 0.9

stepvalue: 5000

stepvalue: 7000

stepvalue: 8000

stepvalue: 9000

stepvalue: 9500

接下來的引數:

momentum :0.9

上一次梯度更新的權重,具體可參看下一篇文章。

type: SGD

優化演算法選擇。這一行可以省掉,因為預設值就是SGD。總共有六種方法可選擇,在本文的開頭已介紹。

weight_decay: 0.0005

權重衰減項,防止過擬合的一個引數

display: 100

每訓練100次,在螢幕上顯示一次。如果設定為0,則不顯示。

max_iter: 20000

最大迭代次數。這個數設定太小,會導致沒有收斂,精確度很低。設定太大,會導致震盪,浪費時間。

snapshot: 5000

snapshot_prefix: "examples/mnist/lenet"

快照。將訓練出來的model和solver狀態進行儲存,snapshot用於設定訓練多少次後進行儲存,預設為0,不儲存。snapshot_prefix設定儲存路徑。

還可以設定snapshot_diff,是否儲存梯度值,預設為false,不儲存。

也可以設定snapshot_format,儲存的型別。有兩種選擇:HDF5 和BINARYPROTO ,預設為BINARYPROTO

solver_mode: CPU

設定執行模式。預設為GPU,如果你沒有GPU,則需要改成CPU,否則會出錯。

 注意:以上的所有引數都是可選引數,都有預設值。根據solver方法(type)的不同,還有一些其它的引數,在此不一一列舉。

七.Solver優化方法

到目前為止,caffe總共提供了六種優化方法:

Stochastic Gradient Descent (type: "SGD"),

AdaDelta (type: "AdaDelta"),

Adaptive Gradient (type: "AdaGrad"),

Adam (type: "Adam"),

Nesterov’s Accelerated Gradient (type: "Nesterov") and

RMSprop (type: "RMSProp")

Solver就是用來使loss最小化的優化方法。對於一個數據集D,需要優化的目標函式是整個資料集中所有資料loss的平均值。

其中,fW(x(i))計算的是資料x(i)上的loss, 先將每個單獨的樣本x的loss求出來,然後求和,最後求均值。 r(W)是正則項(weight_decay),為了減弱過擬合現象。

如果採用這種Loss 函式,迭代一次需要計算整個資料集,在資料集非常大的這情況下,這種方法的效率很低,這個也是我們熟知的梯度下降採用的方法。

在實際中,通過將整個資料集分成幾批(batches), 每一批就是一個mini-batch,其數量(batch_size)為N<<|D|,此時的loss 函式為:

有了loss函式後,就可以迭代的求解loss和梯度來優化這個問題。在神經網路中,用forward pass來求解loss,用backward pass來求解梯度。

在caffe中,預設採用的Stochastic Gradient Descent(SGD)進行優化求解。後面幾種方法也是基於梯度的優化方法(like SGD),因此本文只介紹一下SGD。其它的方法,有興趣的同學,可以去看文獻原文。

1Stochastic gradient descentSGD)

隨機梯度下降(Stochastic gradient descent)是在梯度下降法(gradient descent)的基礎上發展起來的,梯度下降法也叫最速下降法,具體原理在網易公開課《機器學習》中,吳恩達教授已經講解得非常詳細。SGD在通過負梯度和上一次的權重更新值Vt的線性組合來更新W,迭代公式如下:


其中,是負梯度的學習率(base_lr)是上一次梯度值的權重(momentum),用來加權之前梯度方向對現在梯度下降方向的影響。這兩個引數需要通過tuning來得到最好的結果,一般是根據經驗設定的。如果你不知道如何設定這些引數,可以參考相關的論文。

在深度學習中使用SGD,比較好的初始化引數的策略是把學習率設為0.01左右(base_lr: 0.01),在訓練的過程中,如果loss開始出現穩定水平時,對學習率乘以一個常數因子(gamma),這樣的過程重複多次。

對於momentum,一般取值在0.5--0.99之間。通常設為0.9momentum可以讓使用SGD的深度學習方法更加穩定以及快速。

關於更多的momentum,請參看Hinton的《A Practical Guide to Training Restricted Boltzmann Machines》。  

例項: 

base_lr: 0.01

lr_policy: "step"

gamma: 0.1  

stepsize: 1000 

max_iter: 3500

momentum: 0.9

lr_policy設定為step,則學習率的變化規則為 base_lr * gamma ^ (floor(iter / stepsize))

即前1000次迭代,學習率為0.01; 1001-2000次迭代,學習率為0.001; 2001-3000次迭代,學習率為0.00001,第3001-3500次迭代,學習率為10-5  

上面的設定只能作為一種指導,它們不能保證在任何情況下都能得到最佳的結果,有時候這種方法甚至不work。如果學習的時候出現diverge(比如,你一開始就發現非常大或者NaN或者infloss值或者輸出),此時你需要降低base_lr的值(比如,0.001),然後重新訓練,這樣的過程重複幾次直到你找到可以workbase_lr

2AdaDelta

AdaDelta是一種魯棒的學習率方法,是基於梯度的優化方法(like SGD)。

具體的介紹文獻:

示例:

net: "examples/mnist/lenet_train_test.prototxt"

test_iter: 100

test_interval: 500

base_lr: 1.0

lr_policy: "fixed"

momentum: 0.95

weight_decay: 0.0005

display: 100

max_iter: 10000

snapshot: 5000

snapshot_prefix: "examples/mnist/lenet_adadelta"

solver_mode: GPU

type: "AdaDelta"

delta: 1e-6

從最後兩行可看出,設定solver typeAdadelta時,需要設定delta的值。

3AdaGrad

自適應梯度(adaptive gradient)是基於梯度的優化方法(like SGD

具體的介紹文獻:

示例:

net: "examples/mnist/mnist_autoencoder.prototxt"

test_state: { stage: 'test-on-train' }

test_iter: 500

test_state: { stage: 'test-on-test' }

test_iter: 100

test_interval: 500

test_compute_loss: true

base_lr: 0.01

lr_policy: "fixed"

display: 100

max_iter: 65000

weight_decay: 0.0005

snapshot: 10000

snapshot_prefix: "examples/mnist/mnist_autoencoder_adagrad_train"

# solver mode: CPU or GPU

solver_mode: GPU

type: "AdaGrad"

4Adam

是一種基於梯度的優化方法(like SGD)。

 具體的介紹文獻:

D. Kingma, J. Ba. International Conference for Learning Representations, 2015.

5NAG

Nesterov 的加速梯度法(Nesterov’s accelerated gradient)作為凸優化中最理想的方法,其收斂速度非常快。

 具體的介紹文獻:

 I. Sutskever, J. Martens, G. Dahl, and G. Hinton. Proceedings of the 30th International Conference on Machine Learning, 2013.

示例:

net: "examples/mnist/mnist_autoencoder.prototxt"

test_state: { stage: 'test-on-train' }

test_iter: 500

test_state: { stage: 'test-on-test' }

test_iter: 100

test_interval: 500

test_compute_loss: true

base_lr: 0.01

lr_policy: "step"

gamma: 0.1

stepsize: 10000

display: 100

max_iter: 65000

weight_decay: 0.0005

snapshot: 10000

snapshot_prefix: "examples/mnist/mnist_autoencoder_nesterov_train"

momentum: 0.95

# solver mode: CPU or GPU

solver_mode: GPU

type: "Nesterov"

6RMSprop

RMSpropTieleman在一次 Coursera課程演講中提出來的,也是一種基於梯度的優化方法(like SGD

具體的介紹文獻:

 示例:

net: "examples/mnist/lenet_train_test.prototxt"

test_iter: 100

test_interval: 500

base_lr: 1.0

lr_policy: "fixed"

momentum: 0.95

weight_decay: 0.0005

display: 100

max_iter: 10000

snapshot: 5000

snapshot_prefix: "examples/mnist/lenet_adadelta"

solver_mode: GPU

type: "RMSProp"

相關推薦

caffe網路模型

一.資料層及引數 資料層是每個模型的最底層,是模型是入口,不僅提供資料的輸入,也提提供資料從Blobs轉化成別的格式進行儲存輸出。資料的預處理像去均值,放大縮小,裁剪和映象等操作都是在該層進行。 一般的資料的格式為LeveIDB和LMDB兩種。 layer {   n

win10下caffe快速配置(包括PythonCaffe)+Caffe官方教程中譯本及caffe網路模型各層教程

借鑑: 文章1:http://www.cnblogs.com/love6tao/p/5706830.html 文章2:http://www.itdadao.com/articles/c15a26208

muduo網路庫——muduo多執行緒模型

6.3     非阻塞網路程式設計應該用邊沿觸發(ET)還是電平觸發(LT)?如果是電平觸發,那麼什麼時候關注POLLOUT事件?會不會造成busy-loop?如果是邊沿觸發,如果和防止漏讀造成的飢餓? epoll一定比poll快麼? 6.4        在fi

神經網路語言模型

1 簡介 語言模型是自然語言處理領域的基礎問題,其在詞性標註、句法分析、機器翻譯、資訊檢索等任務中起到了重要作用。簡而言之,統計語言模型表示為:在詞序列中,給定一個詞和上下文中所有詞,這個序列出現的概率,如下式, 其中,是序列中第詞,, 可以使用 近似,這就是n-gram語言模型,詳細請閱讀[我們是這樣

Caffe網路引數(Alexnet舉例)

本文為博主學習caffe的相關筆記。 在caffe框架中,網路的各個層的引數可以自己配置。檔名一般是train_val.prototxt。 一、Alexnet: 1. 資料層。 資料層一般作為網路的第一層,由cpu讀取資料庫中的資料,後面的層的計算由gpu進行。 #資料層(第

OSI七層模型物理層、資料鏈路層、網路層、傳輸層.....應用層協議

OSI 七層模型通過七個層次化的結構模型使不同的系統不同的網路之間實現可靠的通訊,因此其最主要的功能就是幫助不同型別的主機實現資料傳輸 。 完成中繼功能的節點通常稱為中繼系統。在OSI七層模型中,處於不同層的中繼系統具有不同的名稱。    一個裝置工作在哪一層,關鍵看它工作時利用哪一層的資料

綜合運用: C++11 多線程下生產者消費者模型(轉)

並發 rep 生產 我會 交流 模型 操作 const ref 生產者消費者問題是多線程並發中一個非常經典的問題,相信學過操作系統課程的同學都清楚這個問題的根源。本文將就四種情況分析並介紹生產者和消費者問題,它們分別是:單生產者-單消費者模型,單生產者-多消費者模型,多生產

Java虛擬機:內存模型

調用 數據類型 可擴展 空間 共享 sof 虛擬機 進程 部分 版權聲明:本文為博主原創文章,轉載請註明出處,歡迎交流學習! 我們都知道,當虛擬機執行Java代碼的時候,首先要把字節碼文件加載到內存,那麽這些類的信息都存放在內存中的哪個區域呢?當我們創建一個

OSI七層模型

集線器 提高 ram 轉發數據 -m 數據傳遞 prot 電子郵件 bio OSI 七層模型通過七個層次化的結構模型使不同的系統不同的網絡之間實現可靠的通訊,因此其最主要的功能就是幫助不同類型的主機實現數據傳輸 。 完成中繼功能的節點通常稱為中繼系統。在OSI七層

SSD(single shot multibox detector)算法及Caffe代碼[轉]

作者 3.4 pdf 論文 做了 對比度調整 覆蓋 eccv 添加 這篇博客主要介紹SSD算法,該算法是最近一年比較優秀的object detection算法,主要特點在於采用了特征融合。 論文:SSD single shot multibox detector論文鏈接:h

【轉】中文分詞之HMM模型

實現 含義 jieba 順序 清晰 bsp 中國 matrix 統計 關於HMM模型的介紹,網上的資料已經爛大街,但是大部分都是在背書背公式,本文在此針對HMM模型在中文分詞中的應用,講講實現原理。 盡可能的撇開公式,撇開推導。結合實際開源代碼作為例子,爭取做到雅俗共賞,

JVM內存模型

基本 過程 nio 認識 靜態變量 maxperm 工作原理 函數 不變 JVM內存模型也叫JVM運行時區域,是認識和了解JVM工作原理的基礎,從java誕生以來,JVM內存模型基本保持著大同小異的整體形態,由此可見JVM內存模型是相當穩定的,直到jdk1.8之後JVM內存

web服務處理過程,各種I/O模型

web服務處理過程 各種i/o模型詳解 一, 進程,線程?進程是具有一定獨立功能的,在計算機中已經運行的程序的實體。在linux2.4以前,進程是基本運作的單位,在只是線程的系統中,線程才是最基本的運作單位,而進程只是線程的容器,程序本身只是指令,數據及其組織形式的描述,進程才是程序的真正運行實例。若

網絡通信協議三之TCP/IP模型

udp protocol bubuko 傳遞 alt 公司 技術 png 代名詞 TCP/IP模型 註:PDU:Protocol Date Unit:表示對等層之間傳遞的數據單位 TCP:Transmission Control Protocol:傳輸控制協議 UD

Nginx epoll模型

select epoll 舉個例子:假設進程有10萬個TCP連接,且只有幾百個連接是有事件需要處理的。那麽在每一個時刻進程只需要處理這幾百個有事件需要處理的連接即可。事件:即TCP連接上有數據需要交互。 select和poll這樣處理的:在某一時刻,進程收集所有的連接。並把所有連接的套接字傳給操作系統

TCP/IP五層模型

tro 一個個 idt 字節 主機 註意 分享圖片 現在 比較   將應用層,表示層,會話層並作應用層,從tcp/ip五層協議的角度來闡述每層的由來與功能,搞清楚了每層的主要協議就理解了整個互聯網通信的原理。   首先,用戶感知到的只是最上面一層應用層,自上而下每層都依賴

MapReduce編程模型(基於Windows平臺Eclipse)

lib read 找到 lin @override ext logs 設置 otf 本文基於Windows平臺Eclipse,以使用MapReduce編程模型統計文本文件中相同單詞的個數來詳述了整個編程流程及需要註意的地方。不當之處還請留言指出。 前期準備 hadoop集群

django模型(四)

imp 參數 des 也會 超過 分類 空白 fault note 1 概述 (1)概述 : Django對各種數據庫提供了很好的支持,Django為這些數據庫提供了統一的調用API,根據不同的業務需求選擇不同的數據庫 (2)定義模型 模型,屬性,表,字段間的關系

機器學習中的概率模型和概率密度估計方法及VAE生成式模型之二(作者簡介)

AR aca rtu href beijing cert school start ica Brief Introduction of the AuthorChief Architect at 2Wave Technology Inc. (a startup company

機器學習中的概率模型和概率密度估計方法及VAE生成式模型之一(簡介)

價值 新書 The aar 生成 syn TE keras 第一章 A Gentle Introduction to Probabilistic Modeling and Density Estimation in Machine LearningAndA Detailed