最近一直和師兄在調試ncnn下使用yolov2-Tiny,感覺資料很少,踩了很多坑,就記錄一下過程吧。
yolov2-Tiny在darknet下訓練過程可以參考我之前的博客:
https://blog.csdn.net/qq_29377279/article/details/83141239
過程都類似,只是聚類的anchor有點不太一樣,yolov3是9個,yolov2-Tiny是5個。
這是我聚類的腳本:https://github.com/yuace/yolo_python/blob/master/kmeans.py
注意:(我這裏是給yolov3使用的,在yolov2-Tiny使用時,注意classes改爲5,結果要除以32(下採樣率))。
我們做的是一個目標檢測的demo。
我們用的120000的權重,先看一下在darknet下測試效果:
下面要用到兩個文件,一個是網絡結構的.cfg,另一個是訓練出來的權重文件的.weights
我這裏就是:
yolov2-tiny_tarmac.cfg
yolov2-tiny_tarmac_120000.weights
先轉到caffe下:
先要安裝caffe,轉換時使用,轉換模型之後也可以用來測試測試。
參考:https://blog.csdn.net/lwplwf/article/details/83011667
看他提出了一個需要注意的問題:
對於YOLOv2_tiny,416×416的輸入,經過最後一個max pool(size=2,stride=1),可以看到特徵圖13×13處理後還是13×13。
這就有點問題了,測試發現,Caffe中經過這一層特徵圖由13*13變成了12×12,會導致在Caffe下檢測結果的box有偏差。
我們經過測試果然是這樣,根據他的建議進行修改:
DarkNet中max pool層加上padding=2
Caffe中max pool層加上pad=1
這裏要注意保持兩個框架一致,darknet下再進行訓練。
DarkNet下訓練的yolo的.cfg文件和.weights文件轉換爲Caffe的.prototxt文件和.caffemodel文件
轉換腳本:https://github.com/lwplw/darknet2caffe
這裏使用他的darknet2caffe.py腳本時,只需修改caffe_root的路徑即可。
使用命令:
python darknet2caffe.py yolov2-tiny_tarmac.cfg yolov2-tiny_tarmac_120000.weights yolov2-tiny_tarmac.prototxt yolov2-tiny_tarmac.caffemodel
完成之後會生成兩個文件:
yolov2_tiny_tarmac.prototxt ---- 待生成的Caffe框架下的模型結構文件
yolov2_tiny_tarmac.caffemodel – 待生成的Caffe框架下的模型權重文件
注意:
修改.prototxt文件:
將第一層:
input: "data"
input_dim: 1
input_dim: 3
input_dim: 416
input_dim: 416
改爲:
layer {
name: "data"
type: "Input"
top: "data"
input_param { shape: { dim: 1 dim: 3 dim: 416 dim: 416 } }
}
還有最後一層:
layer {
name: "region1"
type: "Region"
bottom: "layer15-conv"
top: "region1"
region_param {
classes: 1
coords: 4
boxes_of_each_grid: 5
softmax: true
}
}
修改爲:
layer {
name: "detection_out"
type: "YoloDetectionOutput"
bottom: "layer15-conv"
top: "detection_out"
include {
phase: TEST
}
yolo_detection_output_param {
num_classes: 1
coords: 4
confidence_threshold: 0.4
nms_threshold: 0.45
biases: 1.08
biases: 1.19
biases: 3.42
biases: 4.41
biases: 6.63
biases: 11.38
biases: 9.42
biases: 5.11
biases: 16.62
biases: 10.52
}
}
這裏爲自己的classes和anchor,threshold自己定就好。
再轉到ncnn下:
參考:https://blog.csdn.net/lwplwf/article/details/83016219 安裝ncnn
安裝完成後進入ncnn/build/tools/caffe下執行
轉換命令:
./caffe2ncnn yolov2_tiny_tarmac.prototxt yolov2_tiny_tarmac.caffemodel yolov2_tiny_tarmac.param yolov2_tiny_tarmac.bin
轉換完成即可得到ncnn下的權重和網絡文件:
yolov2_tiny_tarmac.param
yolov2_tiny_tarmac.bin
修改NCNN根目錄下CMakeLists.txt 文件取消註釋add_subdirectory(examples)
add_subdirectory(examples)
修改官方examples裏的yolov2.cpp
(因爲官方有了yolov2.cpp,所以我們只要編譯使用就ok了,後面轉到手機端也會照着這個cpp寫哦)
https://github.com/Tencent/ncnn/blob/master/examples/yolov2.cpp
我們只需修改param和bin,以及classes_names。(注意這裏classe_names第一個爲background,第二個開始才爲我們的目標名稱。)
完成後全部重新編譯。
使用ncnn來測試一下我們的轉換效果吧:
測試命令:
./yolov2 ncnn.jpg
看着效果和darknet下效果一樣哦,到此我們模型及權重的轉化就完成了啊。
這是在pc端的測試,下一篇將分享我們移植到android端的過程哦。