YOLO目標檢測快速上手這篇文章咱們經過簡短的代碼就實現了一個視頻目標檢測功能。本文將介紹如何使用其餘數據集從新訓練YOLO模型,文章將會詳細介紹每一步。python
咱們將使用Pascal VOC數據集訓練咱們的模型,該數據集能夠用來作圖像分類、目標檢測、圖像分割。
下載並解壓文件後,咱們介紹下相關文件的做用。segmentfault
如圖所示,文件保存了圖片文件名,尺寸,標註,座標,是否分割等信息。dom
「layout」文件夾:保存具備人體部位的圖片名字列表。
「main」文件夾:保存用於圖像物體識別的圖片名字列表。
「segmenttions」文件夾:保存用於圖像分割的圖片名字列表。
由於本次項目使用「main」文件夾,因此咱們再詳細看下:ide
文件夾一共有20個分類的文件,經過文件名字我想你們確定也知道做用了。這裏介紹下文件裏的正負數表明正負樣本,如:函數
這裏咱們要留意的是圖片名字,之後咱們在本身建立數據集的時候,最好也參考此命名方式。學習
標籤的結構是四維分別是("類別",「中心點x座標」,「中心點y」座標,「圖片寬度」,「圖片高度」),其實就是上面所說的圖片xml文件中的內容。咱們能夠經過官方提供的python文件來執行此操做。優化
# 獲取py文件 wget https://pjreddie.com/media/files/voc_label.py
執行此文件以前留意下相關路徑是否正確spa
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')] classes = ["aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"] 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(year, image_id): in_file = open('VOCdevkit/VOC%s/Annotations/%s.xml'%(year, image_id)) out_file = open('VOCdevkit/VOC%s/labels/%s.txt'%(year, 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'): difficult = obj.find('difficult').text cls = obj.find('name').text if cls not in classes or int(difficult) == 1: 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') wd = getcwd() for year, image_set in sets: if not os.path.exists('VOCdevkit/VOC%s/labels/'%(year)): os.makedirs('VOCdevkit/VOC%s/labels/'%(year)) image_ids = open('VOCdevkit/VOC%s/ImageSets/Main/%s.txt'%(year, image_set)).read().strip().split() list_file = open('%s_%s.txt'%(year, image_set), 'w') for image_id in image_ids: list_file.write('%s/VOCdevkit/VOC%s/JPEGImages/%s.jpg\n'%(wd, year, image_id)) convert_annotation(year, image_id) list_file.close()
執行py文件:code
python voc_label.py
執行成功後會生成一個label文件夾和三個txt文件,分別是「2007_train.txt」,"2007_test.txt","2007_val.txt"(我只下載了2007的數據集),文件保存的是對應功能的所有圖片路徑:orm
label文件夾內文件格式:
分別是:("類別",「中心點x座標」,「中心點y」座標,「圖片寬度」,「圖片高度」)
打開darknet/cfg/voc.data,修改「train」,「valid」文件路徑。
首先下載YOLOv3模型:
wget https://pjreddie.com/media/files/darknet53.conv.74
訓練以前,咱們先看下yolov3-voc.cfg文件裏都是什麼:
[net] # Testing # batch=1 # subdivisions=1 # 模型訓練模式 Training # batch_size batch=64 # 用於進一步分割batch_size,分割後的batch_size大小爲:batch_size/subdivisions subdivisions=16 # 模型輸入圖像寬 width=416 # 模型輸入圖像高 height=416 # 圖像通道數 channels=3 # 使用帶動量優化函數的動量參數 momentum=0.9 # 權重衰減率,用於防止過擬合 decay=0.0005 # 如下4項是經過改變圖像角度,飽和度,曝光量,色調來生成更多樣本,可用於防止過擬合 angle=0 saturation = 1.5 exposure = 1.5 hue=.1 # 初始學習率 learning_rate=0.001 burn_in=1000 # 迭代次數 max_batches = 50200 # 當迭代到40000,45000時更改學習率 policy=steps steps=40000,45000 scales=.1,.1 [convolutional] # BN標準化處理,能夠經過改變數據分佈,處理梯度太小問題,加快模型收斂 batch_normalize=1 # 輸出特徵大小 filters=32 # 卷積核大小3x3 size=3 # 卷積步長爲1 stride=1 # pad爲0,padding由 padding參數指定。若是pad爲1,padding大小爲size/2 pad=1 # 激活函數,和relu的區別是當輸入值小於0時,輸出不爲0 activation=leaky **。。。。。省略。。。。。。** [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=20 # 每一個cell預測box數量,yolov1時只有一個 num=9 # 增長噪聲 jitter=.3 ignore_thresh = .5 truth_thresh = 1 random=1
執行訓練:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg darknet53.conv.74
訓練完成後,權重文件保存在backup文件夾內。
若是訓練咱們本身的數據,數據準備工做參考VOC數據集,在模型訓練以前還要更改cfg/yolov3-voc.cfg文件,修改classes類別數量和filter數量,其中filter計算方式:3*(classes+1+4),而後訓練便可。