前言#
上一篇博客寫了用作者提供的 VGG 網絡完整走完一遍流程後,馬上開始嘗試用 MobileNet 訓練。
還有兩個問題待解決:
1. 均值問題。【2017.11.20 解決此問題】
2. 無法用 MobileNet 提供的 caffemodel 做 finetune。 【2017.11.3 解決此問題】
【2017.11.03 更新】成功轉換成 ncnn 格式。
一、數據集收集、整理#
參考: 【SSD】用 caffe-ssd 框架自帶 VGG 網絡訓練自己的數據集
用的到的東西如圖:
二、下載 MobileNet 相關文件#
路徑自己看著弄。
三、生成 train.prototxt、test.prototxt、deploy.prototxt#
這裡哦,我需要提前說點事兒。
-
默認有一個 MobileNet_deploy.prototxt,沒有 batch_norm 層。可以跟官網提供的 caffemodel 一起用。
-
template 裡面有四個文件。兩個 deploy,一個 train,一個 test。
經驗證,train 和 test 跟一會我們自己生成的網絡結構一致。
但我們不用 template 目錄中的東西,因為後面幾層 num_output 需要自己手動改。麻煩!
作者提供了兩個工具用於生成 prototxt 文件。一個是 gen.py 一個是 gen_model.sh。
我傾向用後者,操作簡單點。
運行命令:
sh gen_model.sh 7
後面接的數字是類別數 + 1。
生成的文件在 example 目錄下。
這裡有一點哦,如果你的數據集裡面不完全是 RGB 三通道的。
那麼你要修改 train.prototxt 和 test.prototxt 文件:
transform_param {
scale: 0.007843
force_color: true ###添加
mean_value: 127.5
mean_value: 127.5
mean_value: 127.5
具體報錯內容可以看我上一篇博客 【SSD】用 caffe-ssd 框架自帶 VGG 網絡訓練自己的數據集
。
然後再分別修改文件中 source 和 label_map_file 的路徑,盡量用絕對路徑。
四、修改 solver.prototxt 文件#
我直接拿來 solver_train.prototxt 用的,路徑改好,盡量用絕對路徑。其他參數自己看著改吧。
這裡說一下坑了半天的一個問題吧。
一開始為了排錯,我習慣性設置 test_initialization 為 true。
然後就一直提示 Couldn't find ant detections。
但是訓練階段沒問題的。
後來明白問題所在,因為我沒有 finetune,所以一開始 val 階段並不能檢測到任何東西。
將 test_initialization 設置為 false 後,先訓練一段時間後再 val,就不會提示找不到東西了。
五、訓練腳本#
#!/bin/sh
/home/hans/caffe-ssd/build/tools/caffe train \
--solver="/home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/doc/solver_train.prototxt \
-gpu 6 2>&1 | tee /home/hans/data/ImageNet/Detection/cup/MobileNet-SSD/MobileNet-SSD.log
根據下面 2017.11.03 更新的內容可以看出,訓練結束後,要通過作者提供的工具將 bn 層和 conv 層參數 merge 到一起,以加快計算速度。
修改 merge_bn.py 中路徑和文件名。
新生成的模型應該會比原始模型稍微小一點。
六、訓練輸出可視化(2017.11.02)#
參考: 【SSD】用 caffe-ssd 框架自帶 VGG 網絡訓練自己的數據集
七、測試模型效果(2017.11.03)#
參考: 【SSD】用 caffe-ssd 框架自帶 VGG 網絡訓練自己的數據集
後記#
為什麼一用 pre_trained model 做 finetune 就報錯!!!!!說 conv0 輸入數量不對(1 vs.
2)。應該是 1,結果傳入 2 個???我各種對比檢查了 train.prototxt 和 test.prototxt 文件,然並卵!!!!
-------【2017.11.3 解決不能 finetune 的問題】-------
終於找到原因!
我把現在能做 finetune 的模型和 deploy 文件放出來。
https://pan.baidu.com/s/16dw-dJ779By9AWdiSOxSuQ
github 上作者放出兩個 caffemodel,一個是訓練時候的,這個模型 bn 層和 cnov 層參數是分開的。另一個是 deploy 的,這個模型將 bn 層和 conv 層參數 merge 到一起了。
作者的原話是 merge 後的模型速度會快一點。
-------【2017.11.3 成功轉換成 ncnn 格式】---------
https://github.com/arlose/ncnn-mobilenet-ssd
.param 文件建議就用上面作者提供的吧。如果是自己訓練的數據的話,把類別數改一下就好了,一共要改八處。
自己轉換過來的有兩個問題,
一是缺少頭兩層 Input 和 Split,這個問題要修改 deploy.prototxt 文件開頭為:
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 300 dim: 300 } }
}
二是後面幾層的處理像素變成了 600*600。
.bin 文件一定要用經過 merge.py 處理過的 caffemodel 轉換!
-------【2017.11.16 更新】---------
暈了我之前一直在用 6 月剛發布的 ncnn,
這兩天移植工作交給我才發現官方的 ncnn 已經加入 ssd 的支持。
並且還加入的模型壓縮,雖然只是從計算位數上做的壓縮,並且對效果會有折扣,但也是很實用的。
-------【2017.11.20 更新】---------
自帶 make_mean.sh 並不能求均值,發現有兩個轉 lmdb 工具,一個帶 annotation,一個不帶。
ssd 用的帶 annotation 工具中 detection 方法轉換的。
我就用老方法求了均值,使用 build/tools/convert_imageset 和 build/tools/compute_iamge_mean
shell 腳本代碼:
先把圖片轉換成普通 lmdb 格式
#!/bin/sh
set -e
size=300
TOOLS=/home/hans/caffe/build/tools
cur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
DATA_ROOT="${cur_dir}/data/"
FILE_PATH="${cur_dir}/doc"
echo "Creating train lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$size \
--resize_width=$size \
--shuffle=false \
$DATA_ROOT \
$FILE_PATH/train.txt \
$FILE_PATH/train_lmdb_mean
計算均值,並將輸出保存到 mean.txt 中
#!/bin/sh
TOOLS=/home/hans/caffe/build/tools
$TOOLS/compute_image_mean doc/train_lmdb_mean doc/mean.binaryproto 2>&1 | tee doc/mean.txt
echo "Done."