1. 程式人生 > >darknet yolo訓練自己的資料

darknet yolo訓練自己的資料

首先要說明的是,darknet官網給出的例子是使用yolo(you only look once)網路結構來對影象進行檢測的。Yolo比常見的rcnn 、fast-rcnn、faster-rcnn、SSD要快,但是快的同時損失了精度。
這裡給出兩個效果的對照表
這裡寫圖片描述
該表來自yolo的paper

這裡寫圖片描述
該表來自darknet官網。

由於Yolo是一個速度較快的影象檢測結構,所以將其用於實時檢測具有非常好的效果。Faster-rcnn雖然精度很高,但不具有實時性,所以用作實時檢測的效果要不yolo差。

關於yolo的paper的具體內容,我會在之後的部落格中再進一步詳解,這裡不再深入。本篇部落格以跑通官網給出的例子為主。

第一步:資料標註

有了自己的影象資料以後就要對影象進行標註了,常用的軟體是labelimg。下載後可以直接執行,無需安裝,選擇開啟資料夾後就可以批量匯入圖片了。開啟後Ctrl+R選擇預設儲存路徑(設定預設儲存路徑後,生成的標記檔案實xml檔案,切直接下一張就自動儲存了,如果不設定,生成的標記檔案實lif格式的檔案,且需要手動儲存),w開始畫標籤,d表示下一張圖片,a表示上一張圖片。
這裡寫圖片描述

第二步:生成TXT檔案
標記完後會生成每張圖片對應的xml檔案,也就是每張圖片的label檔案,我們需要提取其中的一些boundingbox的資訊。
在darknet的scripts資料夾下有一個voc_label.py的檔案,這個是針對voc圖片集的xml生成對應圖片TXT檔案的指令碼,根據自己的情況進行修改,生成自己的影象資料的TXT檔案資料。TXT檔案的內容每行都是 這種形式,且座標和長寬都應該是歸一化後的數值。
在執行voc_label.py 指令碼時還會生成一個train.txt檔案,改檔案裡存放的是每張圖片的絕對路徑。Train.txt是訓練時需要的檔案。
生成txt檔案後,記得將原影象和txt檔案放到同一個資料夾下。
這裡寫圖片描述

第三步:建立一個.names檔案
檔案命名任意,例如my.names 該檔案裡存放的是型別的名稱,每一類另起一行。
這裡寫圖片描述

第四步:修改.data檔案
之後我們修改darknet下cfg檔案中的voc.data檔案,當然我們也可以自己建立一個.data檔案。
這裡寫圖片描述

classes= 1                          #訓練資料的類別數目,我這裡只有一類,所以這裡是1
train  = <path-to-voc>/train.txt                           #上面1.2步驟生成的train檔案路徑
valid  = <path-to-voc>test.txt
#上面1.2步驟生成的val檔案路徑 names = data/voc.names #上面2.1步驟建立的names檔案路徑 backup = backup #這是訓練得到的model的存放目錄,建議自己修改。

根據我們實際的檔案路徑和類別等相關資訊,對.data檔案進行修改。

第五步:修改.cfg檔案
假設我們使用yolo_voc.cfg網路來進行訓練,我們需要到darknet/cfg/資料夾下找到yolo_voc.cfg檔案進行修改。當然,使用不同的網路,要修改對應的.cfg檔案。
這裡寫圖片描述
該檔案有兩處需要修改的地方:
第一處:[region]層中classes改成你的類別數,圖片中的資訊使用的是voc的資料集,有20類,所以classes=20。
第二處:[region]層上方的[convolution]層中,filters的數量改成(classes+coords+1)*NUM。上圖是(20+4+1)*5=125

第六步:修改src/yolo.c檔案
這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

1)在檔案的開始部分,也就是上圖的第9行,將類別名稱改成自己資料集的類別名稱。
2)在檔案的第13行,將訓練影象的路徑修改成我們在第三步生成的train.txt的檔案路徑。
3)在檔案的第14行,將backup的路徑修改為你自己想設定的存量訓練權重的路徑。
4)在validate_yolo()函式中,也就是上圖的第117行,將路徑修改為自己指定的路徑。
5)在檔案的第119行,將路徑修改為可由第三步生成的驗證集val.txt的路徑。
6)在validate_yolo_recall()函式中,也就是上圖的第205和206行,其修改與4)、5)的改法相同。
7)在test_yolo()函式中,有處呼叫draw_detections函式,也就是上圖中的第318行,將其最後的引數20修改為自己訓練集的類別數。
8)在檔案的最後,run_yolo()函式中最後一行,也就是上圖中的第351行,需要呼叫demo()函式,將其引數中的20修改為自己資料集的類別數。

第七步:修改src/detector.c檔案
這裡寫圖片描述

在檔案的最後有個option_find_int函式,也就是上圖的第716行,將其引數中的20修改為你自己資料的類別數。
有部落格上講到需要修改list *plist = get_paths(),將其內容修改為第三步生成的train.txt 檔案的檔案路徑,但是我在檔案中找到了4出該函式的呼叫,不確定如何修改。

也有部落格上講到需要修改src/yolo_kernels.cu檔案,將draw_detections函式最後一個引數由20改成你的類別數。但是我沒有找到該檔案。

第八步:重新編譯darknet

cd <darknet_root>  
make clean  
make -j 

上述準備做完後便可以開始訓練了。

第九步:訓練
為了加速訓練,我們可以先下載官網提前訓練好的模型,或者使用我們之前已經訓練過的模型,對現在的訓練進行fine-tuning.
1../darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23
這裡使用的是和官網相同的程式碼。進入darknet根目錄下後,會有一個darknet可執行檔案./darknet表示執行該檔案,train表示此次為訓練,也可以換成其他引數,例如test表示測試。之後跟隨的是.data檔案的路徑,也就是我們第四步所修改的檔案。再接著跟的是.cfg
檔案,該檔案裡存放的是網路結構的定義,也就是我們第五步修改的檔案。最後一個引數是我們下載的預訓練好的模型。執行上述命令後,便開始訓練。如何我們有多塊GPU,也可以在最後加上-gpus 0,1。這表示使用第0塊和第1塊GPU。預設只使用第0塊。

第十步:測試
測試有很多種形式,有測試單張圖片的,有測試已有視屏的,有測試攝像頭實時檢測場景的,預測測試集,還有就是統計測試集合測試效果。
測試單張圖片:
./darknet detector test cfg/voc.data cfg/yolo-voc.cfg final_voc.weights your_img_path.jpg
執行上述程式碼後,會在data資料夾下找到預測後的圖片。

測試已有視屏:
./darknet detector demo cfg/voc.data cfg/yolo-voc.cfg final_voc.weights your_video_path.mp4
測試時會直接彈出一個視窗播放視屏,可以看是實時檢測視屏的效果。

測試攝像頭實時檢測場景:
./darknet detector demo cfg/voc.data cfg/yolo-voc.cfg final_voc.weights
和測試已有視屏類似,執行該命令後,會呼叫攝像頭,彈出一個視窗顯示攝像頭拍攝實時場景,並做實時檢測。

預測測試集:
./darknet detector valid cfg/voc.data cfg/yolo-voc.cfg final_voc.weights

統計測試集合測試效果:
./darknet detector recall cfg/voc.data cfg/yolo-voc.cfg final_voc.weights

最後兩個測試沒有試過,所以不太清楚展出效果是什麼樣的。

至此,所有的訓練過程都已完成。