1. 程式人生 > >caffe 學習系列之finetuning

caffe 學習系列之finetuning

在安裝好caffe之後,下一步自然就是執行一些demo 來玩下。
在caffe 的官網的notebook 中已經介紹瞭如何對caffe 提供的demo 的資料集進行finetuning, 這裡就不過多的介紹了。caffe finetuning 的demo

這一篇主要是介紹如何用caffe提供的model 來訓練我們自己的資料集。

我用的系統是mac osx 10.11 EI, 主要實現的工具是使用terminal 終端和caffe c++ 的命令列介面

  1. 資料集是大概16000張照片,主要是對這些照片的9中照片做影象的分類。(因為這是我的一個課程作業,老師提供了大概3000張左右的照片給我們預測,預測結果在課程網站上面直接顯示出來,所以我沒有從訓練集選擇30%的照片作為測試集來驗證。如果想要自己訓練並且測試的話,可以寫一個小程式自己生成訓練集和測試集。)
    我把我的測試集放到百度雲了
    連結:
    http://pan.baidu.com/s/1i5rsMFF
    密碼: edpc
    有興趣的同學可以去下載下來玩一玩。
    資料集包括了16000張照片 和 包含他們檔案位置和label 的train.txt

2.選擇的model 是caffe 提供的googlenet, 它是2014 ilvsrc 影象分類比賽的冠軍。裝好caffe之後,可以在命令列進入caffe的根目錄之後輸入:

python scripts/download_model_binary.py models/bvlc_reference_googlenet

然後會下載一個大概50M 左右的googlenet.caffemodel 下載完成之後可以在 models/bvlc_googlenet/ 的資料夾中看到 以下檔案:
train_val.prototxt
quick_solver.prototxt
solver.prototxt
deploy.protoxt
bvlc_googlenet.caffemodel
readme.md

3.在model 下載完成之後,下一步是要使用caffe tools中的convert_imagenet 把我們的資料集轉成LMDB 格式。(在caffe中資料預設是通過LMDB 格式來存取的,所以要轉格式。)當然,caffe 的框架也有提供其他的格式存取,不過入門的話還是用LMDB 比較方便。
轉格式的程式碼如下:
進入caffe 根目錄

GLOG_logtostderr=1 ./build/tools/convert_imageset \
/這裡寫的是照片根目錄的路徑 \
/這裡寫的是train.txt 的路徑 \
/這裡寫的是生成的train_lmdb 存的路徑 \

要注意的是:在命令列輸入命令的時候,每個路徑之間是用空格隔開的,要是想要換行可以輸入 \
如果報錯的話 看它提示的error,一般就是找不到照片的檔名或者存train_lmdb 的路徑出錯。 第一個問題在train.txt 的照片檔案寫檔案的絕對路徑,第二個問題就要看原來的路徑下面是不是已經存在一個這樣的lmdb檔案夾了,如果有就把它刪除就可以了。

轉成lmdb 格式之後,下一步是生成mean.binaryproto
使用下面這個命令

./build_release/tools/compute_image_mean /path/to/train_lmdb /path/to/train_mean.binaryproto

兩個檔名:一個是train_lmdb 的路徑,一個是生成的mean.binaryproto 的路徑

4.在資料格式準備完成之後,我們就是要修改原來的solver 或者quick_solver 的檔案來進行訓練了。

我們來看下solver.prototxt

net: "models/bvlc_googlenet/train_val.prototxt" # 這個是caffemodel 在的路徑,預設是相對路徑,也可以改成絕對路徑
#test_iter: 1000        # 要是有測試集的話就可以用這個
#test_interval: 4000    # 也可以直接用全部訓練集訓練,然後輸出正確率
#test_initialization: false # 這樣就不需要用到這個了
display: 40             # 這裡是每隔40個迴圈就顯示一次結果
average_loss: 40
base_lr: 0.01           # 這個是基本的學習率
lr_policy: "step"       
# 這個是每過一定數量的迴圈之後就降低學習率,可以改成"fixed" 把學習率固定下來
stepsize: 320000  # 這個就設定下降學習率的step size
gamma: 0.96       # 下降是 * gamma
max_iter: 10000000  # 迴圈的次數
momentum: 0.9     # 衝量,一般都是0.9
weight_decay: 0.0002
snapshot: 40000
snapshot_prefix: "models/bvlc_googlenet/bvlc_googlenet"
solver_mode: GPU

然後我們還要設定train_val.prototxt:
由於這個比較長,所以我就只貼要修改的地方了:

layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN # 還有一個data layer 這裡是TEST 的,可以把那個layer註釋掉,我沒有使用到它
  }
  transform_param { # 這裡也可以放mean.binaryproto
    mirror: true
    crop_size: 224
    mean_value: 104
    mean_value: 117
    mean_value: 123
  }
  data_param {
    source: "/path/to/train_lmdb" # 這裡是要改的地方
    batch_size: 16
    backend: LMDB
  }
}
layer {
  name: "fc8_flickr" # 這裡原來是fc8, 但是我們要改成我們自己名字,這樣就不會報錯啦
  type: "InnerProduct"
  bottom: "fc7"
  top: "fc8_flickr" # 這裡也要改
  # lr_mult is set to higher than for other layers, because this layer is starting from random while the others are already trained
  param {
    lr_mult: 10
    decay_mult: 1
  }
  param {
    lr_mult: 20
    decay_mult: 0
  }
  inner_product_param {
    num_output: 9     # 這裡我只分9類,所以就num_output 就是9
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}
layer {
  name: "loss3/loss3"
  type: "SoftmaxWithLoss"
  bottom: "fc8_flickr"
  bottom: "label"
  top: "loss3/loss3"
  loss_weight: 1
}
layer {
  name: "loss3/top-1"
  type: "Accuracy"
  bottom: "fc8_flickr"
  bottom: "label"
  top: "loss3/top-1"
  include {
    phase: TRAIN     # 這裡改成train 每次都可以輸出正確率了
  }
}

在修改完solver 和train_val 之後,就可以嘗試train了
進入caffe 根目錄

./build/tools/caffe train -solver /path/to solver -weights /path/to/yourname.caffemodel

要是訓練到一半退出了,caffe會儲存一個snapshot,我們可以重新恢復訓練

./build/tools/caffe train -solver /path/to solver -snapshot /path/to/yourname.solverstate

下一篇將會介紹caffe 的python介面 和視覺化測試