win10下YOLOv3訓練自己的數據集檢測車輛(vs2015)

 

目錄

一、數據集準備

二、配置文件的修改及訓練

三、訓練結果檢驗


環境:

WIN10 + vs2015 + python3.6 + YOLOV3 + GPU訓練

一、數據集準備

這裏有DETRAC數據集的包,用到的是其中的DETRAC-train-data及DETRAC-Train-Annotations-XML包。

鏈接:https://pan.baidu.com/s/1WE4jUbP9UoH7w3dghzDDWA 提取碼:oc8t 

使用的數據集爲DETRAC,此數據集來自北京和天津不同的24個區域道路的監控中的截取,爲車輛的俯拍,與本項目的應用場景相吻合。

1. 首先,這個數據集爲每個文件夾中的圖片提供了一個xml文件,不需要自己再進行手動標識,但是需要將xml文件分成對應每個圖片的xml,這裏參考的是https://blog.csdn.net/w5688414/article/details/78931910博客,博主也在自己的博客中給出了GitHub源碼。

DETRAC_xmlParser.py這個文件與xml文件夾放在同一路徑下就可以自動轉換了,最終會在同一目錄下生成xml_test文件夾,裏面存放的是每個圖片對應的xml文件。

2.這個數據集一個train文件夾下的圖片有幾萬張,這對我自己的項目來說太大了,所以我刪減了一部分,剩下了六千多張圖片。然後執行voc_data_migrate.py,將刪減後的六千多張圖片轉移到同一文件夾下。同樣,py文件與Insight-MVT_Annotation_Train文件夾在同一目錄下,最終生成picture_test文件夾,裏面含有六千多張圖片。

3.爲了讓xml文件及圖片文件對應起來,又刪減了一遍xml文件。到此爲止,已經有xml文件夾及圖片文件夾了,接下來要做的工作就是將xml文件轉換成YOLOv3規定的txt文件就大功告成了。網上有很多將xml文件轉成txt的python文件。並且會同時生成下面訓練時需要使用的train.txt文件(也可以同時生成test.txt)。

# -*- coding: utf-8 -*-
"""
Created on Tue Apr 23 16:31:07 2019

@author: lenovo
"""

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

classes = ["car"]
#myRoot = r'E:\python\spyder'
xmlRoot = r'data\xml_test'
txtRoot =  r'labels'
imageRoot = r'data\picture_tain'
#imageRoot = r'data\picture_test'
def getFile_name(file_dir):
    L=[]
    for root, dirs, files in os.walk(file_dir):
        print(files)
        for file in files:
            if os.path.splitext(file)[1] == '.jpg':
                L.append(os.path.splitext(file)[0]) #L.append(os.path.join(root, file))
    return L

def convert(size, box):
    dw = 1. / size[0]
    dh = 1. / size[1]
    x = (box[0] + box[1]) / 2.0
    y = (box[2] + box[3]) / 2.0
    w = box[1] - box[0]
    h = box[3] - box[2]
    x = x * dw
    w = w * dw
    y = y * dh
    h = h * dh
    return (x, y, w, h)


def convert_annotation(image_id):
    in_file = open(xmlRoot + '\\%s.xml' % (image_id))

    out_file = open(txtRoot + '\\%s.txt' % (image_id), 'w'
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls not in classes:
            continue
        cls_id = classes.index(cls)
        xmlbox = obj.find('bndbox')
        b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
             float(xmlbox.find('ymax').text))
        bb = convert((w, h), b)
        out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


#image_ids_train = open('D:/darknet-master/scripts/VOCdevkit/voc/list.txt').read().strip().split('\',\''image_ids_train = getFile_name(imageRoot)


list_file_train = open(r'train.txt', 'w')
#list_file_train = open(r'test.txt', 'w')
#list_file_val = open('boat_val.txt', 'w')

for image_id in image_ids_train:
    list_file_train.write(imageRoot + '\\%s.jpg\n' % (image_id))
    convert_annotation(image_id)
list_file_train.close()  

# for image_id in image_ids_val:

#    list_file_val.write('/home/*****/darknet/boat_detect/images/%s.jpg\n'%(image_id))
#    convert_annotation(image_id)
# list_file_val.close()

 

最後按照鏈接裏給出的步驟對將txt文件及圖片文件放在同一個文件夾內就可以進行YOLO的訓練啦。

二、配置文件的修改及訓練

從這一部分開始,根據大神的方法。

https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects

1.修改需要用到的數據集,比如我用到的是YOLOv3.cfg,那麼我將YOLOv3.cfg另存爲yolov3-car.cfg,再修改裏面的內容:

       我的GPU顯存是小於4G的,因此要將subdivision調大,subdivision是指將batch分成多少份進行運算,如果我的batch是64的話,subdivision必須也是64,纔不會報錯,但是我發現分別設成32、32要比64、64迭代的快一些,具體原因我還不太清楚,實踐出真知。

2.修改car.name,只有一個類別就是car

3.修改car.data中的內容

4.將剛纔我們生成的txt及圖片放在同一個文件夾下,並將這個文件夾data文件夾下。

5.將上面最後一步生成的train.txt文件放入data文件夾下。

6.在官網上下載鏈接:https://pjreddie.com/media/files/darknet53.conv.74

然後執行命令darknet.exe detector train data/car.data yolov3-car.cfg darknet53.conv.74

YOLO訓練數據集是可以分段的,YOLO會每一百次更新一次訓練的weights文件,每一千次保存一個weights文件,如下圖的說明:

最後我的數據集還正在訓練,我電腦的GPU真的太差勁了,上一次測試是迭代900次的時候,已經呈現了一個不錯的效果。

下圖是900次到1400左右迭代的loss圖像

IOU:代表預測的矩形框和真實目標的交集與並集之比;

class:標註物體分類的正確率,期望該值趨近於1;

Obj:越接近1越好;

No Obj:越接近0越好。

.5R: 1.000000: 是在 recall/count 中定義的, 是當前模型在所有 subdivision 圖片中檢測出的正樣本與實際的正樣本的比值;

0.75R: 以IOU=0.75爲閾值時候的recall;

count:正樣本數目。

三、訓練結果檢驗

經過大約兩三天的訓練…GPU實在是不給力,最後的訓練次數達到2500次,因爲只有一個類別,所以兩千次已經足夠了。

1.什麼時候停止訓練

官方給出的是,average loss在0.05~3之間,0.05是相對來說小模型而且簡單的數據集(for a small model and easy dataset),3是較大模型並且複雜的數據集 (for a big model and a difficult dataset)。非常簡單的特性,就是發現avg loss在很多代中不再下降了,就可以停止訓練了

最後我訓練的數據集的avg loss在0.7~1之間波動,第二條會講怎麼挑選最合適的weights文件。

貼兩張我自己的訓練時的average loss chart圖:

第一張是900~1700次的迭代,第二張是1700~2500次。前900次收斂較快,但是我忘記調max_batch了,所以都幾乎擠在一條線上看不出來趨勢。

2.並不是迭代次數越多越好,也不是avg loss越低越好。

官方的說法如下,訓練次數過多可能會出現過擬合的現象:可以在train數據集中檢測到物體,但是在其他的數據集中效果會降低。

For example, you stopped training after 9000 iterations, but the best result can give one of previous weights (7000, 8000, 9000). It can happen due to overfitting. Overfitting - is case when you can detect objects on images from training-dataset, but can't detect objects on any others images. You should get weights from Early Stopping Point:

3.選擇一個效果最好的weights文件。

在訓練過程中得到了三個weights文件,如下,迭代次數大小關係爲1000<2000<last。

分別使用三個命令行進行測試:

  • darknet.exe detector map data/car.data yolov3-car.cfg backup\yolo-car_1000.weights
  • darknet.exe detector map data/car.data yolov3-car.cfg backup\yolo-car_2000.weights
  • darknet.exe detector map data/car.data yolov3-car.cfg backup\yolo-car_last.weights

yolo-car_1000.weights:

 

 

yolo-car_2000.weights:

yolo-car_last.weights:

比較一下就能發現三個權重文件的avg precision及avg IoU的關係都是 1000<last<2000,可以得出在這三個文件中yolo-car_2000.weights是最佳的權重文件,而不是迭代次數最多的last文件。

4.最後來檢測一下識別效果,我是視頻識別,視頻中的圖片不包含在數據集中,截取了其中的一幀,效果還是不錯的。

OK!到此爲止訓練全部結束!可以愉快的使用在自己的項目中啦~

由於車輛數據集是俯視角度,所以最好是使用在這種監控視頻中進行識別。

我的配置文件和訓練出來的權重文件供大家參考吧。

鏈接:https://pan.baidu.com/s/1y5veNVp0i61cLxdNodxeFg 提取碼:gfvo 

參照博客:

https://blog.csdn.net/weixin_38106878/article/details/88684280

https://blog.csdn.net/w5688414/article/details/78931910

https://github.com/AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects

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