YOLOV4-darknet windows訓(xùn)練自己的數(shù)據(jù)集

簡(jiǎn)介:Darknet項(xiàng)目是github上的一個(gè)開(kāi)源深度學(xué)習(xí)框架,用c語(yǔ)言編寫(xiě),部署C/C++環(huán)境比較方便。

1.圖片數(shù)據(jù)標(biāo)注

labelme標(biāo)注工具標(biāo)注的文件是json格式的文件楞抡,在yolo檢測(cè)的框架下需要txt格式的標(biāo)注,但是沒(méi)有關(guān)系析藕,轉(zhuǎn)換也很簡(jiǎn)單召廷。
沒(méi)有l(wèi)abelme的話直接,pip install labelme即可账胧。


image.png

(注:labelme默認(rèn)是保存圖片數(shù)據(jù)的竞慢,一般來(lái)說(shuō)用不到,菜單-Save With Image Data取消即可)
這里我標(biāo)注了4類數(shù)據(jù)找爱,分別用0 1 2 3表示梗顺,由于圖片數(shù)據(jù)涉及到其他公司秘密不方便展示,所以隨便找了個(gè)圖片做標(biāo)注示范车摄。

2. annotation格式轉(zhuǎn)換

json格式標(biāo)簽內(nèi)容如下

{
  "version": "4.5.6",
  "flags": {},
  "shapes": [
    {
      "label": "0",
      "points": [
        [
          1966.75,
          1436.375
        ],
        [
          2088.625,
          1567.625
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {}
    },
    {
      "label": "1",
      "points": [
        [
          666.75,
          895.75
        ],
        [
          935.5,
          1186.375
        ]
      ],
      "group_id": null,
      "shape_type": "rectangle",
      "flags": {}
    },
  ],
  "imagePath": "..\\FOV_0000.bmp",
  "imageData": null,
  "imageHeight": 2984,
  "imageWidth": 4080
}

yolo的txt標(biāo)簽格式
<class> <x_center> <y_center> <width> <height>
由于圖片可能有尺度縮放所以YOLO里邊的位置用的是圖片的百分比坐標(biāo)
python轉(zhuǎn)換代碼如下

import json
import os
import cv2
img_folder_path=r'F:\imagedata\FOV\FOV'
folder_path=r"F:\imagedata\FOV\FOV\annotation"#標(biāo)注數(shù)據(jù)的文件地址
txt_folder_path = r"F:\imagedata\FOV\FOV\txt"


def create_txt(img_name,json_d,img_path):
    src_img=cv2.imread(img_path)
    h,w = src_img.shape[:2]
    #txt文件名和圖片名保持一致
    txt_name = img_name.split(".")[0]+".txt"
    txt_path = os.path.join(txt_folder_path,txt_name)
    print(txt_path)
    with open(txt_path,'a+') as f:
        for item in json_d["shapes"]:
            print(item['points'])
            print(item['label'])
            point=item['points']
            x_center = (point[0][0]+point[1][0])/2
            y_center = (point[0][1]+point[1][1])/2
            width = point[1][0]-point[0][0]
            hight = point[1][1]-point[0][1]
            print(x_center)
            f.write(" {} ".format(item['label']))
            f.write(" {} ".format(x_center/w))
            f.write(" {} ".format(y_center/h))
            f.write(" {} ".format(width/w))
            f.write(" {} ".format(hight/h))
            f.write(" \n")
            


for jsonfile in os.listdir(folder_path):
    temp_path=os.path.join(folder_path,jsonfile)
    #如果是一個(gè)子目錄就繼續(xù)
    if os.path.isdir(temp_path):
        continue
    print("json_path:\t",temp_path)
    jsonfile_path=temp_path

    with open(jsonfile_path, "r", encoding='utf-8') as f:
        json_d = json.load(f)
        #讀取圖片名
        img_name=json_d['imagePath'].split("\\")[1]
        img_path=os.path.join(img_folder_path,img_name)
        print("img_path:\t",img_path)
        create_txt(img_name,json_d,img_path)
       

生成的txt標(biāo)簽文件

 0  0.4969822303921569  0.5033512064343163  0.029871323529411766  0.043984584450402146  
 1  0.19635416666666666  0.3488815348525469  0.06587009803921569  0.09739443699731903  
 1  0.2717984068627451  0.3488815348525469  0.07123161764705882  0.09739443699731903  
 1  0.19673713235294119  0.24677446380697052  0.0666360294117647  0.09425268096514745  
 1  0.2714154411764706  0.2483453418230563  0.0628063725490196  0.09111092493297587  

最后把圖片和標(biāo)簽數(shù)據(jù)放到darknet\build\darknet\x64\data\obj目錄下寺谤,標(biāo)簽和圖片在同一個(gè)目錄下,且標(biāo)簽名和圖片名一樣吮播,如圖


image.png

3. darknet cfg文件設(shè)置

在darknet\build\darknet\x64\cfg目錄下修改yolov4-tiny-obj.cfg文件(記得備份原文件)变屁,修改bath,width,height,max_batches(下面的steps= max_batches0.8,max_batches0.9),官網(wǎng)的要求width height需要能被32整除意狠,max_batches=classes*2000.

# Training
batch=4
subdivisions=4
width=2048
height=1024
............

learning_rate=0.00261
burn_in=1000
max_batches = 8000
policy=steps
steps=6400,7200
scales=.1,.1

修改classes為你訓(xùn)練數(shù)據(jù)的種類數(shù)粟关,有兩處,另外一個(gè)很重要的參數(shù)每一個(gè)[yolo]層前面的filters=(種類數(shù)+5)3,有兩處,例如如果有4類环戈,則filters=(4+5)3=27,5類:filters=(5+5)*3=30

[convolutional]
size=1
stride=1
pad=1
filters=27
activation=linear

[yolo]
mask = 3,4,5
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=4
num=6
...........
[convolutional]
size=1
stride=1
pad=1
filters=27
activation=linear

[yolo]
mask = 0,1,2
anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
classes=4
num=6
............

4.創(chuàng)建.data .name 文件

在darknet\build\darknet\x64\data目錄下創(chuàng)建FOV_obj.data文件(文件名隨便取),寫(xiě)入內(nèi)容

classes= 4
train  = data/train.txt
valid  = data/test.txt
names = data/FOV_obj.names
backup = backup/

創(chuàng)建FOV_obj.name文件寫(xiě)入以下內(nèi)容

0
1
2
3

創(chuàng)建train.txt文件寫(xiě)入你想要訓(xùn)練的圖片

data/obj/FOV_0000.jpg
data/obj/FOV_0001.jpg
data/obj/FOV_0002.jpg
data/obj/FOV_0003.jpg
data/obj/FOV_0004.jpg
..............

創(chuàng)建test.txt文件寫(xiě)入

data/obj/FOV_0065.jpg
data/obj/FOV_0066.jpg
data/obj/FOV_0067.jpg
data/obj/FOV_0068.jpg
.............

python代碼

#train.txt
txt_ = r"D:\mydoc\ML\yolo\darknet\build\darknet\x64\data\train.txt"
with open(txt_,'a+') as f:
    for i in range(60):
        item = "data/obj/"+"FOV_{}.jpg".format(str(i).zfill(4))
        f.write(item)
        f.write("\n")

#test.txt
txt_ = r"D:\mydoc\ML\yolo\darknet\build\darknet\x64\data\test.txt"
with open(txt_,'a+') as f:
    for i in range(60,69):
        item = "data/obj/"+"FOV_{}.jpg".format(str(i).zfill(4))
        f.write(item)
        f.write("\n")

最后的文件如下


image.png

5. 下載yolo預(yù)訓(xùn)練模型

https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.conv.29
放入darknet\build\darknet\x64目錄下

6.train

打開(kāi)cmd進(jìn)入darknet.exe所在目錄
輸入

darknet.exe detector train data/FOV_obj.data cfg/yolov4-tiny-obj.cfg yolov4-tiny.conv.29 29
image.png

可以看到訓(xùn)練損失開(kāi)始很大闷板,在訓(xùn)練200-300個(gè)batch時(shí)下降到3點(diǎn)幾,并在此處震蕩院塞,另外每訓(xùn)練1000個(gè)batch會(huì)保存一次模型遮晚。模型權(quán)值保存在darknet\build\darknet\x64\backup目錄下,某次訓(xùn)練中斷了拦止,想要接著上一次的訓(xùn)練過(guò)程繼續(xù)的話也很方便县遣,輸入:

darknet.exe detector train data/FOV_obj.data cfg/yolov4-tiny-obj.cfg backup\yolov4-tiny-obj_last.weights
image.png

7.demo test

使用剛剛訓(xùn)練的模型權(quán)重做測(cè)試

darknet.exe detector test data/FOV_obj.data cfg/yolov4-tiny-obj.cfg backup\yolov4-tiny-obj_1000.weights
image.png

在Enter Image path:處填入圖片路徑(eg:data/test.jpg)

data
OK,至此基本訓(xùn)練流程走完糜颠,剩下的就是提升網(wǎng)絡(luò)性能了。

訓(xùn)練過(guò)程的一點(diǎn)總結(jié)

  • 在yolov4-tiny-obj.cfg配置中圖片的高度和寬度應(yīng)該能被32整除萧求,用其他高寬也能訓(xùn)練其兴,但是會(huì)出現(xiàn)比較大的震蕩,test測(cè)試的時(shí)候找不到目標(biāo)夸政,或者是有一層的輸入不匹配(圖像輸入0x0x0)元旬。
  • 訓(xùn)練yolov4完整框架,用yolov4.conv.137預(yù)訓(xùn)練權(quán)重秒梳,圖像尺寸大一點(diǎn)常常會(huì)導(dǎo)致GPU out of memory法绵,解決方法是在.cfg文件中提高subdivisions=4(或者8箕速、16酪碘、32、64)盐茎,另外就是改輸入的尺寸width height兴垦。參考https://www.ccoderun.ca/programming/2020-09-25_Darknet_FAQ/#cuda_out_of_memory
  • 網(wǎng)絡(luò)會(huì)把尺寸*1.4,例如在.cfg文件中設(shè)置width=1024,height=768,
    image.png
  • yolov4完整版的配置和yolov4-tiny版配置差不多字柠,就是改width,height,classes,yolo層前面卷積層的filters(classes,filters有三處需要改探越,因?yàn)樗腥齻€(gè)yolo層)。改用yolov4完整模型訓(xùn)練自己的數(shù)據(jù)集效果出乎意料窑业,非常好钦幔。130多張圖片,因?yàn)閱螐垐D片太大提高了subdivisions常柄,用quadro M4000 GPU訓(xùn)練了一個(gè)白天加一個(gè)晚上再加一個(gè)早上鲤氢。


    image.png
  • 使用python darknet_images.py,希望輸出prediction 時(shí),需要先編譯yolo_cpp_dll.dll和yolo_cpp_dll_nogpu.dll,我兩個(gè)都直接編譯完成沒(méi)報(bào)任何錯(cuò)誤西潘,但是用的時(shí)候出現(xiàn)這個(gè)問(wèn)題


    image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卷玉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子喷市,更是在濱河造成了極大的恐慌相种,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件品姓,死亡現(xiàn)場(chǎng)離奇詭異寝并,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)腹备,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)衬潦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人馏谨,你說(shuō)我怎么就攤上這事别渔。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵哎媚,是天一觀的道長(zhǎng)喇伯。 經(jīng)常有香客問(wèn)我,道長(zhǎng)拨与,這世上最難降的妖魔是什么稻据? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮买喧,結(jié)果婚禮上捻悯,老公的妹妹穿的比我還像新娘。我一直安慰自己淤毛,他們只是感情好今缚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著低淡,像睡著了一般姓言。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔗蹋,一...
    開(kāi)封第一講書(shū)人閱讀 52,441評(píng)論 1 310
  • 那天何荚,我揣著相機(jī)與錄音,去河邊找鬼猪杭。 笑死餐塘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的皂吮。 我是一名探鬼主播戒傻,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涮较!你這毒婦竟也來(lái)了稠鼻?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狂票,失蹤者是張志新(化名)和其女友劉穎候齿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體闺属,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慌盯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掂器。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亚皂。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖国瓮,靈堂內(nèi)的尸體忽然破棺而出灭必,到底是詐尸還是另有隱情狞谱,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布禁漓,位于F島的核電站跟衅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏播歼。R本人自食惡果不足惜伶跷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秘狞。 院中可真熱鬧叭莫,春花似錦、人聲如沸烁试。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)廓潜。三九已至抵皱,卻和暖如春善榛,著一層夾襖步出監(jiān)牢的瞬間辩蛋,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工移盆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悼院,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓咒循,卻偏偏與公主長(zhǎng)得像据途,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叙甸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359