YOLO3訓練自己數據(超詳細步驟)

須知: 對於佔比較小的目標檢測效果不好,雖然每個格子可以預測多個bounding box,但是最終只選擇IOU(預測的矩形框和真實目標的交集與並集之比)最高的bounding box作爲物體檢測輸出,即每個格子最多隻預測出一個物體。當一個格子中包含多個物體時,如鳥羣等,卻只能檢測出其中一個。另外,YOLO對車牌識別的效果一般。

一:下載YOLO3項目

git clone https://github.com/pjreddie/darknet
cd darknet

二:修改makefile配置

如果不使用相關功能,不必修改路徑。

GPU=1 #如果使用GPU設置爲1,CPU設置爲0
CUDNN=0  #如果使用CUDNN設置爲1,否則爲0
OPENCV=0 #如果調用攝像頭,還需要設置OPENCV爲1,否則爲0
OPENMP=0  #如果使用OPENMP設置爲1,否則爲0
DEBUG=0  #如果使用DEBUG設置爲1,否則爲0

CC=gcc
NVCC=nvcc #修改爲自己的路徑
AR=ar
ARFLAGS=rcs
OPTS=-Ofast
LDFLAGS= -lm -pthread 
COMMON= -Iinclude/ -Isrc/
CFLAGS=-Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC
...
ifeq ($(GPU), 1)
COMMON+= -DGPU -I/usr/local/cuda/include/ #修改爲自己的路徑
CFLAGS+= -DGPU
LDFLAGS+= -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand #修改爲自己的路徑
endif

保存後退出,在當前路徑make一下。

三:準備數據集

首先創建一個目錄來存儲所有數據,如VOCdevkit/來包含VOC訓練數據的子目錄。創建子目錄各文件夾結構如下所示:
—VOCdevkit
——VOC2019
———Annotations
———ImageSets
————Main
———JPEGImages

圖片及標註可以從網上找,也可自己爬取後使用labelImg標註。
圖片放入JPEGImages文件夾中。
對應圖片標註生成的XML文件放入Annotations文件夾中。

labelImg下載方式:使用git命令

git clone https://github.com/tzutalin/labelImg

安裝:

$ sudo apt-get install pyqt4-dev-tools # 安裝PyQt4
$ sudo pip install lxml # 安裝lxml,如果報錯,可以試試下面語句
$ sudo apt-get install python-lxml

在labelImg目錄下執行:

python labelImg.py

快捷鍵:
Ctrl + u 加載目錄中的所有圖像,鼠標點擊Open dir同功能
Ctrl + r 更改默認註釋目標目錄(xml文件保存的地址)
Ctrl + s 保存
Ctrl + d 複製當前標籤和矩形框
space 將當前圖像標記爲已驗證
w 創建一個矩形框
d 下一張圖片
a 上一張圖片
del 刪除選定的矩形框
Ctrl++ 放大
Ctrl-- 縮小

Main中包含train.txt和val.txt

使用如下代碼可生成對應的兩個txt文件(代碼位置與主目錄同級)

import os
from os import listdir, getcwd
from os.path import join
if __name__ == '__main__':
    source_folder='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/JPEGImages/'
    dest='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/train.txt' 
    dest2='/home/lixiaoyu/darknet/scripts/VOCdevkit/VOC2019/ImageSets/Main/val.txt'  
    file_list=os.listdir(source_folder)       
    train_file=open(dest,'a')                 
    val_file=open(dest2,'a')                  
    for file_obj in file_list:                
        file_path=os.path.join(source_folder,file_obj) 
       
        file_name,file_extend=os.path.splitext(file_obj)
       
        file_num=int(file_name) 
        
        if(file_num<80000):                     
            
            train_file.write(file_name+'\n')  
        else :
            val_file.write(file_name+'\n')    
    train_file.close()
val_file.close()

在VOCdevkit同級目錄下載voc_label.py文件

wget https://pjreddie.com/media/files/voc_label.py

修改文件中sets和classes,如:

sets=[('2019', 'train'), ('2019', 'val')]

classes = ["1",“2”,“3”]

運行它

python voc_label.py

幾分鐘後,此腳本將生成所有必需的文件。如2019_train.txt和2019_val.txt文件,還會在VOCdevkit/VOC2019/labels/中生成大量標籤文件。
類似於:

0 0.449074074074 0.679861111111 0.685185185185 0.456944444444

即:

<object-class> <x> <y> <width> <height>

四:下載預訓練權重

wget https://pjreddie.com/media/files/darknet53.conv.74 

五:修改3個配置文件

1.現在轉到Darknet目錄。我們必須更改cfg/voc.data配置文件以指向您的數據:

classes= 3
train  = /home/lixiaoyu/darknet/scripts/2019_train.txt
valid  = /home/lixiaoyu/darknet/scripts/2019_val.txt
names = /home/lixiaoyu/darknet/data/voc.names
backup = backup(忘說了...backup文件夾要自己創建在Darknet目錄下)

2.更改data/voc.names(數據集的標籤名)如本例:

1
2
3

3.修改cfg/yolov3-voc.cfg

[net]
#Testing
#batch=1
#subdivisions=1
#Training
batch=64 #批次,顯存不夠可減小,但會出現Nan問題(解決辦法:增大batch。。。)
subdivisions=16 #訓練迭代包含16組,每組4張圖片
width=416
height=416
channels=3
momentum=0.9 #滑動平均模型,在訓練的過程中不斷地對參數求滑動平均,這樣能夠更有效地保持穩定性,使其對當前參數更新不敏感
decay=0.0005 #權重衰減,防止過擬合
angle=0
saturation = 1.5
exposure = 1.5
hue=.1

learning_rate=0.001 #學習率 學習率決定了參數移動到最優值的速度快慢
burn_in=1000
max_batches = 50200
policy=steps
steps=40000,45000
scales=.1,.1
......

[convolutional]
size=1
stride=1
pad=1
filters=24  #3*(類別+5)
activation=linear

[yolo]
mask = 6,7,8
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=3  #類別
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=1  #如果顯存很小,將random設置爲0,關閉多尺度訓練
......

[convolutional]
size=1
stride=1
pad=1
filters=24  #這兒
activation=linear

[yolo]
mask = 3,4,5
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=3  #還有這兒
num=9
jitter=.3
ignore_thresh = .5
truth_thresh = 1
random=0  
......

[convolutional]
size=1
stride=1
pad=1
filters=24  #。。。
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
classes=3  #。。。
num=9
jitter=.3  
ignore_thresh = .5  
truth_thresh = 1 
random=0  

六:訓練

普通訓練:

./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74

若想使用多個GPU訓練

./darknet detector train cfg/coco.data cfg/yolov3.cfg darknet53.conv.74 -gpus 0,1,2,3

如終止訓練,權重會保存在backup文件夾下。如果要從檢查點停止並重新啓動訓練

./darknet detector train cfg/coco.data cfg/yolov3.cfg backup/yolov3.backup -gpus 0,1,2,3

七:關於訓練時打印的日誌詳解

如圖所示:

Region 82 Avg IOU: 0.874546, Class: 0.983519, Obj: 0.984566, No Obj: 0.008776, .5R: 1.000000, .75R: 0.750000,  count: 4
Region 94 Avg IOU: 0.686372, Class: 0.878314, Obj: 0.475262, No Obj: 0.000712, .5R: 1.000000, .75R: 0.200000,  count: 5
Region 106 Avg IOU: 0.893751, Class: 0.762553, Obj: 0.388385, No Obj: 0.000089, .5R: 1.000000, .75R: 1.000000,  count: 1

三個尺度上預測不同大小的框,82卷積層爲最大預測尺度,使用較大的mask,可以預測出較小的物體,94卷積層 爲中間預測尺度,使用中等的mask, 106卷積層爲最小預測尺度,使用較小的mask,可以預測出較大的物體。

下面以其中一個爲例:

Region 82 Avg IOU: 0.874546, Class: 0.983519, Obj: 0.984566, No Obj: 0.008776, .5R: 1.000000, .75R: 0.750000,  count: 4

詳解:
Region Avg IOU: 表示在當前subdivision內的圖片的平均IOU,代表預測的矩形框和真實目標的交集與並集之比。
Class: 標註物體分類的正確率,期望該值趨近於1。
Obj: 越接近1越好。
No Obj: 期望該值越來越小,但不爲零。
count: count後的值是所有的當前subdivision圖片中包含正樣本的圖片的數量。

每過一個批次會返回一個輸出:

1: 806.396851, 806.396851 avg, 0.000000 rate, 1.457291 seconds, 64 images

1: 指示當前訓練的迭代次數
806.396851:是總體的Loss(損失)
806.396851 avg:是平均Loss,這個數值應該越低越好,一般到0.幾的時候就可直接退出訓練。
0.000000 rate:代表當前的學習率,是在.cfg文件中定義的。
1.843955 seconds:表示當前批次訓練花費的總時間。
64 images:這一行最後的這個數值是1*64的大小,表示到目前爲止,參與訓練的圖片的總量。

八:測試

./darknet detect cfg/yolov3.cfg yolov3.weights data/one.jpg
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章