源碼獲取與安裝
GitHub 上搜索 YOLO
可以找到很多平臺的包,如: Tensorflow
, pyTorch
等等;本文使用 darknet
原因:方便把玩。請參考如下頁面安裝測試:
實測
自帶圖
其他任選
簡單場景
中等複雜
盆栽(potted plant)都可以, 當然花瓶是沒有的
複雜場景
注意下圖中的包和傘都能檢測出來:
還有這個圖,不是偶然
惡劣環境
下面的環境有點惡劣,不過還不錯,雖然漏了個車和路燈
失敗例子
哈哈,畫的畫果然還是不行,難道畫技太差,哈哈:
訓練
樣本
標記樣本
- 工具:Yolo_mark或者自寫,本人自己寫了個腳本
- 格式:類標從0開始,沒有背景(與訓練與微調均是)
其它說明見以下各自部分。
預訓練
準備訓練樣本
darknet 這個
微調
準備訓練樣本
訓練樣本標籤文件信息如下:
<object-class> <x> <y> <width> <height>
<object-class> <x> <y> <width> <height>
...
對應於:
<類別標籤數字> <物體中心水平方向座標/寬度> <物體中心垂直方向座標/高度> <物體區域寬度> <物體區域高度>
如對於 VOC2012
中的一幅飛機的圖像,對應的訓練樣本標籤信息如下:
0 0.578 0.474474474474 0.744 0.588588588589
其中,0
表示類別,0.578 0.474474474474
爲中心座標,0.744 0.588588588589
分別爲寬度和高度,如下圖所示:
訓練配置
learning_rate=0.0001
max_batches = 3 # 訓練代數 epoches
policy=steps
steps=1,2,3 # 每訓練step,保存一次
scales=10,.1,.1
開始微調訓練
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23 -gpus 0,1,2,3 >> backup/training.log
可視化訓練
參考:
問題解決
不畫框
是圖像長寬比太大導致不畫框,通過查看相關源碼發現,在 image.c
函數中含有如下代碼:
int width = im.h * .006;
可見源碼有BUG,對於高度過小的圖像,導致不畫框,因爲在 draw_box_width 函數裏:
for(i = 0; i < w; ++i){
draw_box(a, x1+i, y1+i, x2-i, y2-i, r, g, b);
所以解決方法是:
if(class >= 0){
int width = im.h * .006;
//============================Added by LiuZhi===========================//
if(width < 1) width = 1;
//============================Added by LiuZhi===========================//
/*
if(0){
width = pow(prob, 1./2.)*10+1;
alphabet = 0;
}
*/
//printf("%d %s: %.0f%%\n", i, names[class], prob*100);
int offset = class*123457 % classes;
float red = get_color(2,offset,classes);
float green = get_color(1,offset,classes);
float blue = get_color(0,offset,classes);
float rgb[3];
訓練時錯誤
Assertion `0’ failed
提示如下錯誤,試了網上的幾個方法,如改Makefile文件中的GPU ARCH,使用sudo
運行,等等均不行。後來想起自己曾改了batchsize爲64,於是將其改小爲8,該完後,重新運行,一切正常,是內存不足的問題。
darknet: ./src/cuda.c:36: check_error: Assertion `0' failed.
./train.sh: line 3: 12389 Aborted (core dumped)
測試
輸出類別與自定義的不同
自定義二分類任務,訓練後測試發現,目標種類始終爲 “Person” 這應該是VOC和COCO裏的類別,網上查了好久,無果。第二天睡醒後,決定自己看看源碼,追根溯源,很快,不到5分鐘,找到了問題所在,看到下面代碼段中的最後一行了嗎(約在源文件440行),是的輸入的配置文件是 “cfg/coco.data” , ~.~:
終端執行代碼: ./darknet detect cfg/yolov3-tiny-lpd.cfg backup/yolov3-tiny-lpd_800.weights data/002001.jpg -thresh 0.0000
文件: “darknet.c”
if (0 == strcmp(argv[1], "average")){
average(argc, argv);
} else if (0 == strcmp(argv[1], "yolo")){
run_yolo(argc, argv);
} else if (0 == strcmp(argv[1], "super")){
run_super(argc, argv);
} else if (0 == strcmp(argv[1], "lsd")){
run_lsd(argc, argv);
} else if (0 == strcmp(argv[1], "detector")){
run_detector(argc, argv);
} else if (0 == strcmp(argv[1], "detect")){
float thresh = find_float_arg(argc, argv, "-thresh", .5);
char *filename = (argc > 4) ? argv[4]: 0;
char *outfile = find_char_arg(argc, argv, "-out", 0);
int fullscreen = find_arg(argc, argv, "-fullscreen");
test_detector("cfg/coco.data", argv[2], argv[3], filename, thresh, .5, outfile, fullscreen);
你可以把”cfg/coco.data”換成你的,但是得重新編譯,注意看有個 “detector” ,在”detector.c”這個文件裏有:
void run_detector(int argc, char **argv)
{
...
char *datacfg = argv[3];
char *cfg = argv[4];
char *weights = (argc > 5) ? argv[5] : 0;
char *filename = (argc > 6) ? argv[6]: 0;
if(0==strcmp(argv[2], "test")) test_detector(datacfg, cfg, weights, filename, thresh, hier_thresh, outfile, fullscreen);
else if(0==strcmp(argv[2], "train")) train_detector(datacfg, cfg, weights, gpus, ngpus, clear);
else if(0==strcmp(argv[2], "valid")) validate_detector(datacfg, cfg, weights, outfile);
else if(0==strcmp(argv[2], "valid2")) validate_detector_flip(datacfg, cfg, weights, outfile);
else if(0==strcmp(argv[2], "recall")) validate_detector_recall(cfg, weights);
else if(0==strcmp(argv[2], "demo")) {
list *options = read_data_cfg(datacfg);
int classes = option_find_int(options, "classes", 20);
char *name_list = option_find_str(options, "names", "data/names.list");
char **names = get_labels(name_list);
demo(cfg, weights, thresh, cam_index, filename, names, classes, frame_skip, prefix, avg, hier_thresh, width, height, fps, fullscreen);
看到了吧:test_detector(datacfg
,於是決定 調用detector(這樣不用改代碼了),如下:
./darknet detector test cfg/data/lpd/lpd.data cfg/yolov3-tiny-lpd.cfg backup/yolov3-tiny-lpd_600.weights data/002003.jpg -thresh -0