天天看點

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

文章目錄

  • 0. 前期準備(因人而異)
  • 1. 試驗官方模型
    • 1.1 下載下傳工程檔案
    • 1.2 轉換權重檔案
    • 1.3 圖檔識别
  • 2. 制作VOC資料集
    • 2.1 格式介紹
    • 2.2 準備樣本及XML标記
    • 2.3 生成索引
  • 3. YOLO模型訓練
    • 3.1 生成訓練索引
    • 3.2 修改配置檔案
    • 3.3 執行訓練
  • 4. 模型驗證
  • 5. 常見問題
    • 5.1 如何提高檢測效果
    • 5.2 Found 0 boxes for img
    • 5.3 loss值異常
    • 5.4 ResourceExhaustedError: OOM
    • 5.5 檢測時打開程式報錯:Dimension 0 in both shapes must be equal, but are 1 and 24.
    • 5.6 訓練模型如何在OpenCV中使用?

參考:

https://blog.csdn.net/patrick_Lxc/article/details/80615433

https://blog.csdn.net/m0_37857151/article/details/81330699

0. 前期準備(因人而異)

記錄一下前期的一些配置:

首先要安裝好python,部落客這裡用的是Python 3.6 64-bit。

path環境變量中加入python36和python36/Scripts的路徑。

使用管理者權限進入cmd指令提示符,運作一下代碼:

pip install --upgrade pip #更新pip
pip install tensorflow #安裝 tensorflow
pip install --upgrade numpy #numpy是一個基礎的數組計算包,有時候版本較老會報錯 
pip install keras #yolo train.py檔案裡面要用到keras這個高層神經網絡API
pip install pillow #安裝 圖檔處理子產品PIL(pillow)
pip install matplotlib #安裝 2D繪圖庫matplotlib
pip install opencv-python #安裝 opencv視覺庫
           

中間記得測試一下tensorflow安裝有沒有問題:

import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import tensorflow as tf
hello = tf.constant('Hello,TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
           

如果打算用 GPU版本 訓練的話,可以參考我另外一篇文章:https://blog.csdn.net/qinchang1/article/details/90693983

給個版本建議:

Tensorflow-gpu 1.4.0 + Keras 2.2.4(我用的版本)

Tensorflow-cpu 1.13.1 + Keras2.2.4(網友提供成功的版本)

1. 試驗官方模型

1.1 下載下傳工程檔案

YOLOv3下載下傳:

1)yolov3.weights權重檔案:https://pjreddie.com/media/files/yolov3.weights

2)keras-yolo3代碼: https://github.com/qqwweee/keras-yolo3 (工程檔案如下,記得把 .weights權重檔案也放進去)

推薦:百度網盤打包下載下傳(* ̄︶ ̄):連結:https://pan.baidu.com/s/1OIQGthndfLSfMC1ZlZH6lA 提取碼:rlkd

(建議用我的網盤資源下載下傳,因為github上面的工程檔案可能會有更改,導緻後續的操作出現不同或問題)

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

1.2 轉換權重檔案

這裡首先要需要将 DarkNet 的

.weights

檔案轉換成 Keras 的

.h5

檔案,在cmd中打開工程檔案的路徑,運作

convert.py

并告知 “.weights的輸入路徑 ” 和 “.h5的輸出路徑” ,代碼如下:

python convert.py yolov3.cfg yolov3.weights model_data/yolo.h5
           
【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

會在model_data檔案夾中生成一個yolo.h5檔案。

+注意:這個權重檔案要留着,後面可能會用上。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

1.3 圖檔識别

在工程檔案中打開yolo_video.py,其用法如下:

usage: yolo_video.py [-h] [–model MODEL] [–anchors ANCHORS]

[–classes CLASSES] [–gpu_num GPU_NUM] [–image]

[–input] [–output]

positional arguments:

–input Video input path

–output Video output path

optional arguments:

-h, --help show this help message and exit

–model MODEL path to model weight file, default model_data/yolo.h5

–anchors ANCHORS path to anchor definitions, default

model_data/yolo_anchors.txt

–classes CLASSES path to class definitions, default

model_data/coco_classes.txt

–gpu_num GPU_NUM Number of GPU to use, default 1

–image Image detection mode, will ignore all positional arguments

例如:識别一張圖檔,則在cmd中的工程檔案路徑下輸入:

python yolo_video.py --image
           
【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

會提示你輸入圖檔路徑(這裡我的圖檔是直接放在工程檔案裡面的,是以直接輸入檔案名):

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

效果如下:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

2. 制作VOC資料集

VOC全稱Visual Object Classes,出自The PASCAL Visual Object Classes(VOC)Challenge,這個挑戰賽從2005年開始到2012年,每年主辦方都會提供一些圖檔樣本供挑戰者識别分類。

PASCAL VOC官網:http://host.robots.ox.ac.uk/pascal/VOC/

2.1 格式介紹

可以在官網中下載下傳每一年的資料集,也可以自己仿照VOC的格式制作。

其檔案格式如下圖:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

下面是本人對每個檔案功能的總結和了解:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

我們可以把官方下載下傳的VOC資料集裡面的内容删除,隻保留各個檔案夾;或者按照這個格式建立一個檔案夾集。

這個檔案夾我們直接放到前面的工程檔案keras-yolo3-master中(以便之後的訓練不用更改路徑)。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

2.2 準備樣本及XML标記

在JPEGImage檔案夾中放入準備好的樣本圖檔:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

需要制作每張圖檔對應的同名xml檔案,這裡我們以下面這張圖檔為例,右邊的代碼是其對應的xml檔案内容:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

如果你有精力的話,當然可以自己一個個去寫:)

不過這裡我們用一個labelImg的軟體進行标記,

labelImg下載下傳連結:https://pan.baidu.com/s/1Ibenx26FaJUI_t-J3EhSLw 提取碼:2gba

解壓之後就兩個檔案,labelImg.exe運作檔案,data檔案夾裡面有個predefined_classes.txt檔案。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

在predefined_classes.txt檔案裡面添加需要标記的類的名稱。

打開軟體,其實操作很簡單,就是手動去标注物體,并給其選擇對應的類名稱:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

之後儲存xml檔案,注意路徑。

把所有xml檔案都放置到VOC資料集裡面的Annotations檔案夾中。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

打了3種标簽,如下所示。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

2.3 生成索引

在VOC2007檔案夾中建立一個**.py檔案**(名字随意)

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

在py檔案中輸入以下代碼并運作,用以生成索引

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()
           

之後就會在ImageSets\Main檔案夾中生成幾個索引檔案

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

{class}_train.txt 儲存類别為 class 的訓練集的所有索引

{class}_val.txt 儲存類别為 class 的驗證集的所有索引

{class}_trainval.txt 儲存類别為 class 的訓練驗證集的所有索引

3. YOLO模型訓練

3.1 生成訓練索引

在工程檔案keras-yolo3-master中,修改voc_annotation.py檔案

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

主要是把裡面classes的内容改成要訓練的對象(要和前面标記的一緻,這裡我隻有三個對象"twistlock",後兩個沒加上,圖檔是老的了)

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

運作這個py程式,生成三個檔案"2007_test.txt", “2007_train.txt”, “2007_val.txt”,把字首"2007_"去掉,得到 “test.txt”, “train.txt”, “val.txt”。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

PS:其實這一步有個問題,仔細看過train.py代碼的人估計會發現實際訓練隻加載了train.txt檔案,然後将train.txt檔案裡面的索引再分成了訓練集和樣本集。

3.2 修改配置檔案

首先要修改一下 model_data 檔案夾中的coco_classes.txt和voc_classes.txt,将裡面的對象改成自己要訓練的對象名稱

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

3.3 執行訓練

直接将model_data檔案夾中原版的yolo.h5複制,改名為yolo_weights.h5,将其作為預訓練權重。

PS: 對于這個預訓練權重,其實是遷移學習的方法,有些博文其實是讓修改yolo3.cfg檔案,然後重新生成權重檔案,但是我發現這樣的做法最後訓練時會出現val_loss:nan的情況,是以我建議直接用原來官方的權重檔案yolo.h5。還有一些博文修改了原來train.py的訓練代碼,不預加載訓練權重,重頭開始訓練,但是我發現由于樣本量少,這樣訓練出來的結果很不穩定,是以我也不推薦。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

完成yolo_weights.h5檔案之後,在keras-yolo3-master工程檔案夾中找到train. py,根據需要,可以更改裡面的疊代次數epochs 等參數。如果顯存小的話,可以改小batch_size。

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

之後運作這個python程式,下面是我的運作效果

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

訓練過程:

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

訓練結束後,會生成很多過程的h5檔案,最後隻需要保留trained_weights_final.h5就行。

訓練樣本約400多張,最後兩種loss都降到15左右。

4. 模型驗證

參照前面1.3節内容,可以在yolo. py 中把權重檔案的名字改成 trained_weights_final.h5 ,也可以直接把 trained_weights_final.h5名字改成 yolo. h5,總之就是之後要加載新的權重檔案。

同樣地,則在cmd中的工程檔案路徑下輸入:

python yolo_video.py --image
           

輸入圖檔路徑(這裡是将圖檔直接放在工程檔案裡,是以直接輸入名字就行)

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題
【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題
【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

B站上放了一個最新的訓練效果:

https://www.bilibili.com/video/av78397208

5. 常見問題

5.1 如何提高檢測效果

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

1. 訓練前

(1)在.cfg檔案中設定flag

random=1

,它将通過不同分辨率來訓練yolo以提高精度。

(2)提高.cfg檔案中網絡的分辨率,(例如

height = 608

width = 608

或者任意32的倍數),這樣可以提高精度。

(3)確定資料集中每個類都帶有标簽,并且保證标簽正确。(原文裡面提供一個腳本工具)

(4)對于要檢測的每個對象,訓練資料集中必須至少有一個類似的對象,其形狀、對象側面、相對大小、旋轉角度、傾斜、照明等條件大緻相同。

(5)資料集中應包括對象的不同縮放、旋轉、照明、不同的面、不同背景的圖像,最好為每個類提供2000個不同的圖像,并且訓練(

2000* 類的數量

)的疊代次數或更多。

(6)確定訓練的資料集中包含不想被檢測的不帶标簽的對象,即負樣本,負樣本的數量最好和正樣本的數量相同。

(7)對于目标物體較多的圖像,在.cfg檔案中最後一個[yolo]層加入

max=200

參數或者更高的值。(yolov3可以檢測到的對象的全局最大數目是

0.0615234375 *(width*height)

,其中width和height是.cfg檔案中[net]部分的參數)

(8)訓練小物體時(圖像調整到416x416後物體小于16x16),将[route]參數替換為

layers = -1, 11

,将[upsample]參數改為

stride =4

(9)對于都包含小對象和大對象可以使用以下的修改模型:

Full-model: 5 yolo layers: https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3_5l.cfg

Tiny-model: 3 yolo layers: https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3-tiny_3l.cfg

Spatial-full-model: 3 yolo layers: https://raw.githubusercontent.com/AlexeyAB/darknet/master/cfg/yolov3-spp.cfg

(10)如果要訓練區分左右的對象(例如左手右手,道路上左轉右轉标志等),需要禁用資料翻轉增強,在.cfg檔案中17行左右的位置加入

flip=0

(11)一般規律——訓練資料集應該包含一組您想要檢測的對象的相對大小。簡單來說,就是需要檢測的對象在圖像中的百分比是多少,那麼訓練的圖像中也應該包含這個百分比的對象。例如:如果訓練的時候目标在圖像中都占80-90%,那檢測的時候很可能就檢測不出目标占0-10%情況。

(12)同一個對象在不同的光照條件、側面、尺寸、傾斜或旋轉30度的情況下,對于神經網絡的内部來說,都是不同的對象。是以,如果想檢測更多的不同對象,就應該選擇更複雜的神經網絡。

(13)在.cfg中重新計算錨(anchors)的width和height:在.cfg檔案中的3個[yolo]層中的每個層中設定相同的9個錨,但是應該為每個[yolo]層更改錨點

masks=

的索引,以便[yolo]第一層的錨點大于60x60,第二層大于30x30,第三層剩餘。此外,還應在每個[yolo]層之前更改過濾器

filters=(classes + 5) * <number of mask>

。如果許多計算出的錨找不到适當的層,那麼隻需嘗試使用所有的預設錨。

2.訓練後(對于檢測):

通過在.cfg檔案中設定(

height=608

width=608

)或(

height=832

width=832

)或(32的任意值倍數)來提高網絡的分辨率,這将提高精度并使檢測小對象成為可能。

這裡提高了網絡的分辨率,但是可以不需要重新訓練(即使之前使用416*416分辨率訓練的)。但是為了提高精度,還是建議使用更高的分辨率來重新訓練。

注意:如果出現了

Out of memory

的錯誤,建議提高.cfg檔案中的

subdivisions=16

參數,改成32或者64等。

5.2 Found 0 boxes for img

在檢測時,減小 yolo. py 檔案參數中的 score 和 iou,如下圖:

(這樣可以使得置信度小和交并比小的框也能顯示出來)

【YOLO】使用VOC資料集訓練自己的YOLOv3模型(Keras/TensorFlow)0. 前期準備(因人而異)1. 試驗官方模型2. 制作VOC資料集3. YOLO模型訓練4. 模型驗證5. 常見問題

如果這時候能出現框了,但是會發現效果不是很好,或者說置信度特别低,說明檢測是成功的,但是訓練做得比較差;

如果還是不能出現框,考慮有可能檢測方法錯了(路徑設定等),或者是訓練過程錯誤(類名稱和索引沒配置好等)。

不管什麼情況都可以試試5.1節中提到的方法。

5.3 loss值異常

模型訓練時,有兩個loss值:

1)Train loss(對應本次訓練中的

loss

):使用訓練集的樣本來計算的損失;

2)Test loss(對應本次訓練中的

val_loss

):使用驗證集的樣本來計算的損失。

一般來說,損失函數越小,模型就越好。但要考慮過拟合情況:

過拟合:為了得到一緻假設而使假設變得過度嚴格。

例如:訓練出來的模型對訓練樣本檢測的效果很好,但是對于驗證集(也就是沒有進行訓練的樣本)的檢測效果卻很差。

結果分析:( ↓ 表示 不斷下降,↑ 表示 不斷增加,→ 表示 趨于不變)

train loss test loss 說明
網絡正在不斷學習收斂
網絡過拟合
資料集有問題
此次條件下學習達到瓶頸
網絡結構或設計參數有問題,無法收斂

5.4 ResourceExhaustedError: OOM

開始訓練後有時候會報錯,例如:

ResourceExhaustedError (see above for traceback): OOM when allocating tensor with shape[10,256,52,52]

這種情況通常是GPU顯存被占滿了,你要麼清理一下,要麼把程式中的

batch_size

改小

5.5 檢測時打開程式報錯:Dimension 0 in both shapes must be equal, but are 1 and 24.

這個是由于标明的類數量和訓練的類數量對應不上,檢查一下voc_classes.txt和coco_classes.txt

5.6 訓練模型如何在OpenCV中使用?

參考我另一篇文章:

https://blog.csdn.net/qinchang1/article/details/105776132

如有錯誤,歡迎指正!

繼續閱讀