訓練自己特定的圖片及預測單張圖片(僅CPU)

最近自己琢磨caffe,主要參考了博主徐其華denny的學習專欄,http://www.cnblogs.com/denny402/p/5083300.html,接下來的過程基本是按照他的步驟進行的。

好記性不如爛筆頭,雖然對深度學習的瞭解纔剛剛開始,但還是希望能記錄點滴學習過程。以下是我訓練自己的圖片的過程,正確率只有0.333,可能是樣本源的選擇不好,但總算是訓練出精度了,所以記錄一下。

以下所有操作都是在caffe根目錄下進行,否則都會出錯。

我根據http://www.2cto.com/kf/201606/515700.html博主提供的數據(共10類1000張train,200test)訓練36h後得到0.545的精度,訓練時間太長(是跟電腦配置有關?),網上博主使用上面的配置訓練,得到的結果準確率是0.2+,數據集的製作者迭代了12000次得到0.5的準確率。參數配置如下所示:


net: "examples/303file/train_val.prototxt"
test_iter: 4
test_interval: 300
base_lr: 0.001
lr_policy: "step"
gamma: 0.1
stepsize: 300
display: 20
max_iter: 1200
momentum: 0.9
weight_decay: 0.0005
snapshot:600
snapshot_prefix:"/home/jenny/caffe/examples/303file/"
solver_mode: CPU

我主要目的是想對高壓輸電線上的三種金具(防震錘,間隔器,懸垂線夾)進行分類,所以用攝像頭拍攝了一段視頻截取了部分圖片,圖片背景比較昏暗,而且防震錘與懸垂線夾的差別不大,不知這是不是精度較低的原因。
總共300張圖片,包括240張train,60張test,分三類,編號分別以1,3,5開頭,每類80張訓練,20張測試,圖片大小爲512*684。我將圖片放在caffe根目錄下的data文件夾下面。即訓練圖片目錄:data/obstacle/train/ ,測試圖片目錄: data/obstacle/test/



二、轉換lmdb格式


具體轉換過程可參考denny博主的http://www.cnblogs.com/denny402/p/5082341.html
在examples下面創建一個jennyfile的文件夾,來用存放配置文件和腳本文件。然後編寫一個腳本create_filelist.sh,用來生成train.txt和test.txt清單文件


sudo mkdir examples/jennyfile
sudo vi examples/jennyfile/create_filelist.sh


編輯此文件,寫入如下代碼,並按Esc鍵,再按冒號:wq保存


#!/usr/bin/env sh
DATA=data/obstacle/
MY=examples/jennyfile

echo "Create train.txt..."
rm -rf $MY/train.txt
for i in 1 3 5
do
find $DATA/train -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/train.txt
done
echo "Create test.txt..."
rm -rf $MY/test.txt
for i in 1 3 5
do
find $DATA/test -name $i*.jpg | cut -d '/' -f4-5 | sed "s/$/ $i/">>$MY/test.txt
done
echo "All done"
然後,運行此腳本

sudo sh examples/jennyfile/create_filelist.sh

成功的話,就會在examples/jennyfile/ 文件夾下生成train.txt和test.txt兩個文本文件,裏面就是圖片的列表清單。(此處需要注意的是圖片名稱與類別數字之間是一個空格,我之前遇到過can't find or open xxx.jpg的錯誤,原因就是中間是tab鍵而不是空格鍵,改過後就OK了)

接着再編寫一個腳本文件,調用convert_imageset命令來轉換數據格式。

sudo vi examples/jennyfile/create_lmdb.sh


插入代碼如下:

#!/usr/bin/env sh
MY=examples/jennyfile

echo "Create train lmdb.."
rm -rf $MY/img_train_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_height=256 \
--resize_width=256 \
/home/jenny/caffe/data/obstacle/ \
$MY/train.txt \
$MY/img_train_lmdb

echo "Create test lmdb.."
rm -rf $MY/img_test_lmdb
build/tools/convert_imageset \
--shuffle \
--resize_width=256 \
--resize_height=256 \
/home/jenny/caffe/data/obstacle/ \
$MY/test.txt \
$MY/img_test_lmdb
因爲圖片大小不一,因此我統一轉換成256*256大小。運行成功後,會在 examples/jennyfile下面生成兩個文件夾img_train_lmdb和img_test_lmdb,分別用於保存圖片轉換後的lmdb文件。



三、計算均值並保存

圖片減去均值再訓練,會提高訓練速度和精度。因此,一般都會有這個操作。

caffe程序提供了一個計算均值的文件compute_image_mean.cpp,我們直接使用就可以了

sudo build/tools/compute_image_mean examples/jennyfile/img_train_lmdb examples/jennyfile/mean.binaryproto

compute_image_mean帶兩個參數,第一個參數是lmdb訓練數據位置,第二個參數設定均值文件的名字及保存路徑。
運行成功後,會在 examples/jennyfile/ 下面生成一個mean.binaryproto的均值文件(一定要保證均值文件生成成功,檢查它的大小)。


四、創建模型並編寫配置文件

模型就用程序自帶的caffenet模型,位置在 models/bvlc_reference_caffenet/文件夾下, 將需要的兩個配置文件,複製到jennyfile文件夾內


sudo cp models/bvlc_reference_caffenet/solver.prototxt examples/myfile/
sudo cp models/bvlc_reference_caffenet/train_val.prototxt examples/myfile/


修改其中的solver.prototxt

sudo vi examples/jennyfile/solver.prototxt


更改爲如下參數:

net: "examples/jennyfile/train_val.prototxt"
test_iter:60
test_interval: 40
base_lr: 0.0001
lr_policy: "step"
gamma:0.1
stepsize:50
display: 10
max_iter: 100
momentum: 0.9
snapshot:50
snapshot_prefix:"/home/jenny/caffe/examples/jennyfile/"
weight_decay: 0.005
solver_mode: CPU

60個測試數據,batch_size爲1,因此test_iter設置爲60就能全cover了(這兩個參數調整了多次,每次訓練都不太理想,所以最後將batch_size設爲1)。在訓練過程中,調整學習率,逐步變小。
修改train_val.protxt,只需要修改兩個階段的data層就可以了,其他可以不用管。


name:"CaffeNet"
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 227
    mean_file: "examples/jennyfile/mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: true
#  }
  data_param {
    source: "examples/jennyfile/img_train_lmdb"
    batch_size: 60
    backend: LMDB
  }
}
layer {
  name: "data"
  type: "Data"
  top: "data"
  top: "label"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 227
    mean_file: "examples/jennyfile/mean.binaryproto"
  }
# mean pixel / channel-wise mean instead of mean image
#  transform_param {
#    crop_size: 227
#    mean_value: 104
#    mean_value: 117
#    mean_value: 123
#    mirror: false
#  }
  data_param {
    source: "examples/jennyfile/img_test_lmdb"
    batch_size:1
    backend: LMDB
  }
}


除了修改兩個Data layer的mean_file和source這兩個地方,還要修改最後一個全連接層fc8的num_output參數,你訓練的有幾類就改爲幾類,我改爲了3類。

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: 3
    weight_filler {
      type: "gaussian"
      std: 0.01
    }
    bias_filler {
      type: "constant"
      value: 0
    }
  }
}

五、訓練和測試

如果前面都沒有問題,數據準備好了,配置文件也配置好了,這一步就比較簡單。在終端輸入:

sudo build/tools/caffe train -solver examples/jennyfile/solver.prototxt


運行時間和最後的精確度會根據機器配置、參數配置的不同而不同。我的是僅CPU運行100次,大約50分鐘,精度爲0.333,LOSS爲1.32062.訓練完成後會生成_iter_100.caffemodel和_iter_100.solverstate兩個文件,接下來用一個訓練好的caffemodel來對一張新的圖片進行分類。(在訓練的時候一直出現Restarting data prefetching from start,此時需要耐心等待,我有時候出現三四次,歷時30min纔會顯示下一次)

六、用訓練好的caffemodel來分類


此步驟需要三個文件,caffemodel文件、均值文化和label.txt文件,其中caffemodel文件是訓練好後保存的模型文件,在測試階段,需要把測試數據減去均值mean.binaryproto,label.txt文件中存放的是各個類的名稱,比如的這次分類較少只有三類,所以我可以手動完成。如果類別太多,必須要批量處理了。



數據準備好了,我們就可以開始分類了,我採用的是C++方法。
在caffe根目錄下的 examples/cpp-classification/ 文件夾下面,有個classification.cpp文件,就是用來分類的。當然編譯後,放在/build/examples/cpp_classification/ 下面
我們可以直接運行命令或者寫個腳本文件

sudo vi examples/jennyfile/testonepicture.sh
打開sh文件後插入如下代碼:

sudo .build/examples/cpp_classification/classification.bin \
  examples/jennyfile/deploy.prototxt \
  examples/jennyfile/_iter_100.caffemodel \
  examples/jennyfile/mean.binaryproto \
  examples/jennyfile/labels.txt \
  examples/images/jgq.jpg


其中jgq.jpg圖片是我另找的一張間隔器圖片,




最後得到的測試結果爲0.3391的可能性爲間隔器:


這次測試的精度很不理想,參數也沒有仔細調,但是完整地走了一遍,最大的感受就是不要放棄。接下來就是學會調參,想辦法提高精度。
caffe入門我主要是學習denny的學習專欄,非常感謝博主,裏面有一系列的博文,http://www.cnblogs.com/denny402/tag/caffe/ 有興趣的可以看看。



千里之行,始於足下,fighting!




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