alexeyab darknet 编译_【目标检测实战】Darknet—yolov3模型训练(VOC数据集)
原文發表在:語雀文檔
0.前言
本文為Darknet框架下,利用官方VOC數據集的yolov3模型訓練,訓練環境為:Ubuntu18.04下的GPU訓練,cuda版本10.0;cudnn版本7.6.5。經過一晚上的訓練,模型20個類別的mAP達到74%+。
主要模塊:
- 概述
- 源碼編譯
- 功能測試
- 模型訓練
- 模型驗證
【概述】主要介紹yolo系列模型和darknet框架的關系、資源網站和數據集下載
【源碼編譯】主要是用官方源碼和make命令編譯出Linux下可執行文件,包括cuda+cudnn的設置
【功能測試】主要是用官網給出的demo和與訓練模型來進行圖片測試
【模型訓練】主要是用darknet+yolov3模型訓練VOC圖像數據集(VOC2007+VOC2012) 【模型驗證】即用訓練好的模型,檢測模型訓練效果.
1.概述
官網:https://pjreddie.com/
1.1 Yolo
Yolo系列模型(v1~v3)在近年些來的目標檢測領域,非常火熱!Yolo為:You only look once的縮寫,同時也表明了其特點,只需要一次即可完成從圖像分割到檢測,故其被稱為one-stage系列模型的鼻祖。
two-stage類目標檢測模型如Fast R-CNN、Faster R-CNN1.2 Darknet
yolo系列就是深度學習領域中用于目標檢測的模型(yolov1~v3),那么darknet是什么?兩者關系如何? darknet是作者用c和cuda編寫的用于深度學習模型訓練的框架,支持CPU和GPU訓練,是個非常簡單輕量級框架,就和Tensorflow,Mxnet,Pytorch,Caffe一樣,雖然功能沒有它們多,不過小也有小的優勢,如果你會c語言,可以對其進行充分地利用和改造,或者讀讀源碼看一下其實現,也會收貨滿滿! So,總結一下:Darknet是深度學習框架,yolov1~v3是yolo系列的目標檢測模型
1.3 資源下載
官網
https://pjreddie.com/
源碼
Darknet源碼: https://github.com/pjreddie/darknet
Darknet是用純c和cuda編寫的,要想用darknet來訓練模型,最好用Linux/Unix系統,官方也提供了python的接口,如果是Windows系統,可以利用網友開源實現:https://github.com/AlexeyAB/darknet可以直接下載zip包darknet-master.zip也可直接執行
git clonehttps://github.com/pjreddie/darknet將源碼下載到本地
權重文件
yolov3-tiny.weights
yolov2.weights
yolov3.weights
darknet53.conv.74
VOC數據集
VOCtrainval_11-May-2012.tar
VOCtrainval_06-Nov-2007.tar
VOCtest_06-Nov-2007.tar
其他:
YOLO-V3可視化訓練過程中的參數,繪制loss、IOU、avg Recall等的曲線圖
AlexyAB大神總結的優化經驗
2.源碼編譯
2.1 編輯Makefile
指定是否使用GPU 在執行make指令編譯之前,需要編輯一下makefile,來指定是否需要用GPU(cuda),如果用cuda,是否需要用cudnn加速;是否需要用opencv等。我這里是用GPU且需要用CUDNN加速的,不使用OpenCV。 Makefile的前5行如下,這5項內容0表示不啟用,1表示啟用,可根據需求自己配置。
- GPU 是否啟用GPU1
- CUDNN 是否啟用CUDNN加速,若GPU = 1則CUDNN可選1或0;GPU=0則CUDNN=0
- OPENCV 是否啟用OpenCV,啟用的話需先編譯安裝好,啟用可支持對視頻和圖像流文件處理
- OPENMP 是否啟動多核CPU來加速Yolo,如果是用CPU訓練,建議開啟=1
- DEBUG 表示編譯的Yolo版本為是否為DEBUG版
如果不使用GPU則GPU=0,CUDNN=0;還有一點需注意,如果在shell執行nvcc找不到命令(沒有添加到環境變量),則需要將nvcc命令的全路徑寫出來 指定cuda的路徑 如果不使用GPU,則此步可忽略,如果使用GPU,則需要指定cuda路徑。官方的Makefile默認的cuda路徑為:/usr/local/cuda,如果你安裝了多個cuda,或者cuda路徑更改過,則需要指定你的cuda路徑,這里需要改兩處:51行的COMMON和53行的LDFAGS
2.2 執行make
執行make編譯完成后,在項目主目錄下生成可執行的darknet文件。然后我們就可以用這個可執行文件來進行模型訓練和測試了!
3.功能測試
將下載好的權重文件放入主目錄下,然后cd到該目錄下執行:
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg如果你看到如下輸出,且在主目錄下找到一張predictions.jpg的圖片,則執行成功,表明上一步驟中編譯的darknet可以正常使用。
你也可以指定一個閾值,yolo默認輸出置信度>0.25的預測框,你也可以自行指定:
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg -thresh 0.45-thresh 0.45表示:置信度低于45%的預測框都不會被輸出。
除了使用經典的yolov3模型外,你還可以換一個模型嘗試,譬如yolov3-tiny.weights
./darknet detect cfg/yolov3-tiny.cfg yolov3-tiny.weights data/dog.jpg當然,也可以通過連接攝像頭實現實時視頻畫面預測。(需要編譯時添加opencv)
./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights <video file>4.模型訓練
4.1 數據準備
模型訓練前首先準備數據集,我們用VOC數據集,將VOC數據集解壓,解壓后共同存放在VOCevkit文件夾中,我將VOCevkit放在了darknet主文件夾/data/VOC/下。 cd到/VOC目錄下,下載voc_label.py ,并運行:
python voc_label.py可以將該腳本復制到/scripts下留作備份文件夾下會生成7個.txt文件:
如果你的voc_label.py腳本是從官網wget https://pjreddie.com/media/files/voc_label.py下載的,則需要在腳本57行處額外加上如下兩行內容:
os.system("cat 2007_train.txt 2007_val.txt 2012_train.txt 2012_val.txt > train.txt") os.system("cat 2007_train.txt 2007_val.txt 2007_test.txt 2012_train.txt 2012_val.txt > train.all.txt")目的:將2007年的訓練和驗證圖像+2012年的圖像都放入了train.txt用于集中訓練
4.2 修改配置文件voc.data
配置cfg/voc.data,來確定你需要檢測的目標類別數量和名稱;修改train和valid的圖片資源路徑。訓練資源指向train.txt測試/驗證資源指向2007_test.txt
VOC數據集默認的類別數量為20個,名稱在data/voc.names中:
我這里使用默認的20個類別,所以無需修改;如果,你只想檢測其中的幾個類別,譬如person和car,那么可以設置voc.data中classes=2,names只保留person和car這兩種,不過后面相應的需要更改yolov3-voc.cfg里的卷積層配置等。
4.3 修改yolov3-voc.cfg
yolov3-voc.cfg文件定義了yolo的卷積神經網絡模型,和超參數配置等。這里需要注意,訓練時需要將#Testing區塊下的batch和subvisions注釋掉;測試和驗證時則放開注釋,同時注釋掉#Training區塊下的內容。 訓練時,可以根據自己GPU的內存來設置批的大小batch,可設為16、32、64、128 驗證時,batch和subvisions同時設為1即可。
4.4 開始訓練
cd回項目主目錄,將darknet53.conv.74權重放入主目錄下,運行:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74如果報錯提示cuda內存溢出,可以降低batch,再次運行;運行過程中可以通過nvidia-smi查看顯存占用情況:
訓練過程中會持續往backup/下生成權重文件,如:yolov3-voc_100.weights、yolov3-voc_200.weights....
5.模型驗證
檢驗生成的模型權重文件、測試準確率和map等指標。驗證前需要將yolov3-voc.cfg中的batch和subdivisions都改成1。然后找到需要測試的權重文件,默認權重文件保存在:項目目錄/bakcup/下,我選擇這個yolov3-voc_10000.weights,訓練大約一個晚上12小時左右,loss在0.6多。
5.1 測試
測試一
我們從VOC數據集中隨便找一找圖片來測試一下,這里我選取000275.jpg放入主目錄下
運行:
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights 000275.jpg運行結束會在控制臺打印出標注出的目標類別以及置信度、同時會在目錄下生成一張標注圖片:predictions.jpg **
測試二
再隨便找一張圖片試試
./darknet detector test cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights data/person.jpg5.2 驗證
測試只能一張張地直觀感受下模型的訓練效果,看看標注出的目標是否正確,通過驗證才能確定模型的整體訓練效果,驗證時會用模型對所有的4952張測試集圖片進行預測,同時與正確結果進行比對,得出一個模型預測準確率。
驗證測試集
可以運行以下腳本進行驗證:
./darknet detector valid cfg/voc.data cfg/yolov3-voc.cfg backup/yolov3-voc_10000.weights驗證完會在results文件夾下生成20個類別的驗證結果txt文件
默認的文件命名規則是:'comp4_det_test_' + '類別名稱' + .txt,如bird類生成comp4_det_test_bird.txt文件。
如圖,第一列000053表示圖像編號;第二列為置信度;后4列為檢測出的目標框坐標
計算map
計算map,我們需要兩個python文件:
- voc_eval.py
- compute_mAP.py
其中voc_eval.py是github上開源項目的代碼voc_eval.py;compute_mAP.py需要我們自己編寫
voc_eval.py 我們為了適配darknet中voc數據集的驗證,需要對源碼做幾處修改: a.源碼第9行:import cPickle 改為:
import _pickle as cPickle因為源碼是python2.x版本,如果python3.x版本的運行會報錯,故需要修改。
b.源碼103行: imagenames ``=`` [x.strip() ``for`` x ``in`` lines]改為:
imagenames = [x.strip().split('/')[-1].split('.')[0] for x in lines]這個主要是為了方便適配2007_test.txt,因為我們驗證時采用的是2007_test.txt中的測試集圖片,文件中存放的是圖片的全路徑,而imagenames需要用的是文件名、所以需要將全路徑做個轉換,截取到文件名。
c.115行with`` ``open``(cachefile, ``'w'``) ``as`` f:和 119行with`` ``open``(cachefile, ``'r'``) ``as f:改成:
with open(cachefile, 'wb') as f: with open(cachefile, 'rb') as f:如果不修改成‘wb’和‘rb’存儲二進制格式,運行時會報錯
compute_mAP.py 新建compute_mAP.py文件,用于調用voc_eval.py,內容如下:
from voc_eval import voc_eval import os map_ = 0 # classnames填寫訓練模型時定義的類別名稱 classnames = ['aeroplane','bicycle','bird','boat','bottle','bus','car','cat','chair','cow','diningtable','dog','horse','motorbike','person','pottedplant','sheep','sofa','train','tvmonitor'] for classname in classnames:ap = voc_eval('../results/{}.txt', '../data/VOC/VOCdevkit/VOC2007/Annotations/{}.xml', '../data/VOC/2007_test.txt', classname, '.')map_ += ap#print ('%-20s' % (classname + '_ap:')+'%s' % ap)print ('%s' % (classname + '_ap:')+'%s' % ap) # 刪除臨時的dump文件 if(os.path.exists("annots.pkl")):os.remove("annots.pkl")print("cache file:annots.pkl has been removed!") # 打印map map = map_/len(classnames) #print ('%-20s' % 'map:' + '%s' % map) print ('map:%s' % map)我這里在項目主目錄下新建了一個【yolo-compute-util】文件夾,將兩個.py文件放在文件夾中,cd /yolo-compute-util,然后運行:python compute_mAP.py即可根據results中的驗證結果統計出各個類別的ap,以及匯總的map。
可以看見,經過1晚上的訓練,我們的模型——yolov3-voc_10000.weights的mAP是0.740,雖然沒有達到yolov2系列76.8+的水平,不過一晚上的訓練能達到如此程度,也是挺高了。
總結
以上是生活随笔為你收集整理的alexeyab darknet 编译_【目标检测实战】Darknet—yolov3模型训练(VOC数据集)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 旧路由器怎么设置才能用如何利用旧路由器
- 下一篇: 3d目标检测_CVPR 2020 |基用