YOLO目標檢測模型重新訓練

介紹

圖片描述

YOLO目標檢測快速上手這篇文章我們通過簡短的代碼就實現了一個視頻目標檢測功能。本文將介紹如何使用其他數據集重新訓練YOLO模型,文章將會詳細介紹每一步。

下載數據集

我們將使用Pascal VOC數據集訓練我們的模型,該數據集可以用來做圖像分類、目標檢測、圖像分割。
下載並解壓文件後,我們介紹下相關文件的作用。

clipboard.png

  • “Annotations”文件夾:用於存放圖片描述,文件格式爲.xml,具體內容如下圖所示:

clipboard.png

如圖所示,文件保存了圖片文件名,尺寸,標註,座標,是否分割等信息。

  • “ImageSets”文件夾:保存了不同用途的圖片名字列表,文件格式是.txt。

clipboard.png

“layout”文件夾:保存具有人體部位的圖片名字列表。
“main”文件夾:保存用於圖像物體識別的圖片名字列表。
“segmenttions”文件夾:保存用於圖像分割的圖片名字列表。
因爲本次項目使用“main”文件夾,所以我們再詳細看下:

clipboard.png

文件夾一共有20個分類的文件,通過文件名字我想大家肯定也知道作用了。這裏介紹下文件裏的正負數代表正負樣本,如:

clipboard.png

  • “JPEGImages”文件夾:保存全部圖片源文件。

clipboard.png

這裏我們要留意的是圖片名字,以後我們在自己創建數據集的時候,最好也參考此命名方式。

  • “SegmentationClass”,“SegmentationObject”保存用於圖像分割的源圖片,兩者區別如圖所示:

clipboard.png

創建標籤

標籤的結構是四維分別是("類別",“中心點x座標”,“中心點y”座標,“圖片寬度”,“圖片高度”),其實就是上面所說的圖片xml文件中的內容。我們可以通過官方提供的python文件來執行此操作。

# 獲取py文件
wget https://pjreddie.com/media/files/voc_label.py

執行此文件之前留意下相關路徑是否正確

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文件:

python voc_label.py

執行成功後會生成一個label文件夾和三個txt文件,分別是“2007_train.txt”,"2007_test.txt","2007_val.txt"(我只下載了2007的數據集),文件保存的是對應功能的全部圖片路徑:

clipboard.png

label文件夾內文件格式:

clipboard.png

分別是:("類別",“中心點x座標”,“中心點y”座標,“圖片寬度”,“圖片高度”)

修改配置文件

打開darknet/cfg/voc.data,修改“train”,“valid”文件路徑。

clipboard.png

  1. “classes”:數據集中圖片分類數量。
  2. “train”:用於訓練的圖片數據集絕對路徑。
  3. “valid”:用於驗證的圖片數據集絕對路徑。
  4. “names”:數據集中圖片分類名字,如:“dog”,“person”等。
  5. “backup”:模型訓練完成後,權重文件保存路徑。

模型訓練

首先下載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

clipboard.png

訓練完成後,權重文件保存在backup文件夾內。

總結

如果訓練我們自己的數據,數據準備工作參考VOC數據集,在模型訓練之前還要更改cfg/yolov3-voc.cfg文件,修改classes類別數量和filter數量,其中filter計算方式:3*(classes+1+4),然後訓練即可。

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