1.引言
YOLO自誕生以來,每個版本都會引起學術界和工業界的極大關注。在工業界,即使精度稍差,YOLO往往也會比一些Two-Stage的目标檢測器更受青睐,因為它是真的很快,完全能滿足實時性的應用要求。YOLO最新的版本是YOLOv3,主要改進是提升了小目标檢測的效果。YOLOv3官方的權重是在COCO資料集上訓練的,總共有80類目标,但是在實際應用中,我們往往需要檢測特定的目标。比如在自動駕駛應用中,我們需要檢測的目标有汽車、行人、自行車、交通燈、交通标志等。為了檢測這些目标,我們就需要用自己的資料集來訓練目标檢測器。本文将介紹如何用一個貓狗資料集訓練YOLOv3來檢測圖檔中的貓和狗。
2.資料集
本文使用的貓狗資料集來源于資料集Open Images Dataset V4,該資料集總共包含600類目标,我們從中其中的Cat和Dog類中分别取出4000張圖像用來訓練YOLOv3。
Darknet需要的标注資訊格式為
-id>
其含義如下:
object-class-id: 類别序号。
x: 目标中心點的橫坐标,相對于圖像的寬度做歸一化處理。
y: 目标中心點的縱坐标,相對于圖像的高度做歸一化處理。
width: 目标的寬度,相對于圖像的寬度做歸一化處理。
height: 目标的高度,相對于圖像的高度做歸一化處理。
如果資料集的标注資訊不是這種格式,可以寫一個python腳本來做轉換,這個比較簡單,可以參考scripts/目錄下的voc_label.py腳本來實作。轉換後的标注檔案為txt格式,與圖像放在同一目錄下,每張圖像對應一個标注檔案。
準備好圖像和标注檔案後,我們還要生成訓練集和驗證集的檔案清單。訓練集和驗證集按9:1的比例劃分,生成的檔案清單檔案分别為train.list和val.list。
檔案清單中的每一行都對應一張圖檔的路徑(最好用絕對路徑),訓練的時候程式會根據這個路徑去讀取圖檔。檔案清單中的格式類似于:
/home/anyu/datasets/cat_dog/dog/144fda747fc5bda8.jpg/home/anyu/datasets/cat_dog/cat/03c22fcbc7ce0312.jpg
3.訓練
YOLOv3的作者自己用C語言寫了一個深度學習架構Darknet,是以我們要訓練YOLOv3的話需要先從github上下載下傳Darknet:
git clone https://github.com/pjreddie/darknet
下載下傳完成後,先修改Makefile檔案。如果我們的機器有英偉達顯示卡,并安裝了CUDA,cuDNN和OpenCV,可以按下面的修改:
GPU=1CUDNN=1OPENCV=1
這樣就能用GPU進行加速。如果還需要CPU優化,可以設定OPENMP=1。
修改完成後,執行make指令進行編譯,如果沒有錯誤的話,會在目前目錄下生産可執行檔案“darknet”。
在進行訓練之前,我們還需要準備幾個檔案(下面這些檔案放在哪個目錄都可以,隻要對應上就好了)。
- YOLOv3模型配置檔案
首先把cfg/目錄下的yolov3.cfg檔案複制一份,重命名為cat_and_dog_yolov3.cfg,然後設定裡面的内容。
[net]#設定batchsizebatch=64subdivisions=16#輸入圖像的分辨率width=608height=608channels=3#momentum參數momentum=0.9decay=0.0005#資料增強參數angle=0saturation = 1.5exposure = 1.5hue=.1#最大訓練次數max_batches =20000#學習率及調整政策learning_rate=0.001burn_in=1000policy=stepssteps=15000scales=.1
然後修改yolo層的參數,把類别數量classes改為2。另外還要把yolo層上面convolutional層中filters的參數改為21,該參數的計算方法為(classes+5)*3,在本文中是(2+5)*3=21。如果是用COCO資料集訓練,該參數就是(80+5)*3=255,在實際應用中注意根據實際情況進行修改。
[convolutional]size=1stride=1pad=1filters=21activation=linear[yolo]mask = 6,7,8anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326classes=2num=9jitter=.3ignore_thresh = .7truth_thresh = 1random=1
注意:YOLOv3有3個yolo層,都需要進行上述修改。
- 類别名稱檔案
在data/目錄下建立一個檔案cat_and_dog.names用來儲存類别的名稱,檔案内容為:
catdog
- 配置檔案
在cfg/目錄下建立一個檔案cat_and_dog.data,内容如下:
#類别數量classes= 2#訓練集檔案清單的路徑train = /path/to/train.list#驗證集檔案清單的路徑valid = /path/to/val.list#類别名稱檔案names = data/cat_and_dog.names#訓練過程中權重檔案的儲存目錄backup =backup/
- 預訓練權重檔案
用下面的指令下載下傳預訓練的權重檔案:
wget https://pjreddie.com/media/files/darknet53.conv.74
此檔案是YOLOv3的骨幹網絡darknet53在ImageNet上訓練得到的權重檔案,可以加速訓練過程,因為ImageNet裡是有貓和狗的。當然,這個檔案不是必須的,不用也是可以的。
準備好這些檔案後,我們就可以執行以下指令開始訓練了:
./darknet detector train cfg/cat_and_dog.data cfg/cat_and_dog_yolov3.cfg darknet53.conv.74
4.結果
訓練完成後,在backup/目錄下會得到權重檔案cat_and_dog_yolov3_final.weights。首先把cat_and_dog_yolov3.cfg檔案中batch和subdivisions都設定為1,然後運作下面的指令就可以進行測試了:
./darknet detector train cfg/cat_and_dog.data cfg/cat_and_dog_yolov3.cfg backup/cat_and_dog_yolov3_final.weights data/dog.jpg
其中data/dog.jpg是要檢測的圖檔。以下是我的一些檢測結果:
來看幾張難度高一點的:
5.總結
本文以貓狗資料集為例,詳細介紹了如何在Darknet架構下用自己的資料集訓練YOLOv3的過程,希望本文能對不熟悉Darknet和YOLOv3的朋友有所幫助。