YOLOV3(yolov3)訓練自己的數據

前言:做目標檢測,選擇的算法是yolo v3,因爲它既有速度又有精度,還非常靈活,簡直是工業界良心。做項目免不了需要用到自己的數據集,所以得從頭一個腳印的來,走通了之後決定寫一個帖子,讓需要用的人少走歪路,節約時間。
官網上已經教我們如何跑起來yolo v3,因此大部分時間其實花在製作數據集上。總體來說,分爲四個步驟,分別是:標註數據,利用voc製作自己的數據集,下載並編譯源碼,局部修改和大功告成(前兩步可以在方便操作的環境下(windows或linux)進行,後面幾步在linux環境進行)

一、標註數據

  1. 工具:
    使用的標註工具是labelimg,其他標註工具也行,但是生成的標註label文件要是xml。這裏給一個labelimg軟件的傳送門 https://pan.baidu.com/s/1tuIQmuyedRHP1WeGVVSx_Q 提取碼: ejgx 。

  2. 數據集編號:
    爲了規劃自己的數據,減少出錯的可能性,最好自己先給自己的圖片編一個合理的序號,比如0001~0999。

  3. 標註數據:
    利用軟件把自己的數據標註好。每一個圖片名對應的有一個相應名字的label.xml。
    如圖所示
    xml中的數據如下所示。這時候的path不用管他,在訓練的時候不會用到這裏的數據,這裏後面會說到。
    在這裏插入圖片描述

二、利用voc製作自己的數據集

在目錄下新建VOC2007,並在VOC2007下新建Annotations,ImageSets和JPEGImages三個文件夾。在ImageSets下新建Main文件夾。文件目錄如下所示:
在這裏插入圖片描述
將自己的數據集圖片拷貝到JPEGImages目錄下。將數據集label文件拷貝到Annotations目錄下。在VOC2007下新建test.py文件夾,將下面代碼拷貝進去運行,將生成四個文件:train.txt,val.txt,test.txt和trainval.txt。


import os
import random

trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)

num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)

ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')

for i in list:
    name = total_xml[i][:-4] + '\n'
    if i in trainval:
        ftrainval.write(name)
        if i in train:
            ftest.write(name)
        else:
            fval.write(name)
    else:
        ftrain.write(name)

ftrainval.close()
ftrain.close()
fval.close()
ftest.close()

生成後的目錄結構如下所示:
在這裏插入圖片描述
做好這一步之後,自己的數據集基本做好了,接下來需要轉移陣地到代碼環境中去。

三、下載並編譯源碼

YOLOV3的主頁:https://pjreddie.com/darknet/yolo/
1、下載代碼:

git clone https://github.com/pjreddie/darknet
  • 1

2、編譯代碼:
YOLOV3使用一個開源的神經網絡框架Darknet53,使用C和CUDA,有CPU和GPU兩種模式。默認使用的是CPU模式,需要切換GPU模型的話,vim修改Makefile文件。

cd darknet
vim Makefile  #如果使用CPU模式。則不用修改Makefile文件
  • 1
  • 2

在這裏插入圖片描述
將前面三行置1,其他不用動。

make
  • 1

編譯成功後,可以先下載預訓練模型測試一下效果。

wget https://pjreddie.com/media/files/yolov3.weights
./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
  • 1
  • 2

可以看到YOLO的detection圖。到這裏,YOLOV3已經走通了,是時候加入自己的數據了。
3、加入自己的數據集
在代碼的darknet目錄下新建VOCdevkit文件夾,然後把剛纔製作的VOC2007文件夾拷貝到該文件夾下。
有的讀者可能瞭解過YOLOV3的label,YOLOV3的label標註的一行五個數分別代表類別(從 0 開始編號), BoundingBox 中心 X 座標,中心 Y 座標,寬,高。這些座標都是 0~1 的相對座標。和我們剛纔標註的label不同,因此我們需要下面的py文件幫我們轉換label。

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

這裏需要修改兩個地方,sets和classes,classes根據自己需要修改。
在這裏插入圖片描述
接下來運行該文件,我們的目錄下會生成三個txt文件2007_train.txt,2007_val.txt,2007_test.txt,VOCdevkit下的VOC2007也會多生成一個labels文件夾,下面是真正會使用到的label,點開看發現已經轉化成YOLOV3需要的格式了。這時候自己的數據集正式完成。

python voc_label.py
cat 2007_train.txt 2007_val.txt  > train.txt
  • 1
  • 2

四、局部修改

1、 修改cfg/voc.data

在這裏插入圖片描述
根據自己的路徑修改。

2、修改data/voc.names和coco.names
在這裏插入圖片描述
打開對應的文件都是原本數據集裏的類,改成自己的類就行。

3、修改參數文件cfg/yolov3-voc.cfg
ctrl+f搜 yolo, 總共會搜出3個含有yolo的地方。
每個地方都必須要改2處, filters:3*(5+len(classes));
其中:classes: len(classes) = 1,這裏以單個類dog爲例
filters = 18
classes = 1
可修改:random = 1:原來是1,顯存小改爲0。(是否要多尺度輸出。)
在這裏插入圖片描述

參數文件開頭的地方可以選訓練的batchsize,要注意!
在這裏插入圖片描述

五、大功告成

如果讀者按照步驟已經耐心的到這裏了,可以舒一口氣了,離成功只差一步了。
下載darknet53的預訓練模型。

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

開始訓練:

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

六、關於神經網絡訓練的討論:

過擬合該怎麼繼續訓練?
看到書上寫道:有了BN之後,就不要正則化去防止過擬合了,比如dropout,L2正則化。實際上也試過確實沒什麼效果,有時候還會降低結果。這時候train上和valid上表現有差異該怎麼解決?是數據集本身就有的分佈差異導致的,還是可以通過其他手段解決,如減小模型。歡迎大家討論留言。

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