darknet yolo v2 訓練自己的資料
darknet訓練自己的資料,官方提供了一個訓練VOC的例子,我們參照這個例子,來訓練我們自己的資料。
1. 準備資料集
首先我們應該準備好我們自己的資料集用於訓練。要訓練一個自己的網路,我們需要有訓練集和測試集。在這裡,我們建立兩個資料夾train和val用於存放這兩類資料。接下來,我們要做的是生成資料的標記檔案,也就是目標在圖片中的類別以及位置資訊。
1.1 生成標記檔案
生成yolo的標記檔案應該遵循以下兩個規則:
- 每個原影象都對應著一個標記檔案,而且檔名都相同,比如圖片的名字是1.jpg,那麼對應這張圖片的標記檔名稱應該為1.txt。
- 每個標記檔案中,內容應該是這樣的<object-class> <x> <y> <width> <height>,其中<x> <y> <width> <height>是相對於影象寬高的比例。
知道了這兩個規則之後,我們就可以定義我們的標記檔案了。這裡我已經有了VOC格式標記的XML檔案,那麼接下來我們使用python來生成YOLO格式的標記檔案,程式碼如下:
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join TrainLabel_Dir = '/home/ubuntu/data/labels' #XML所在目錄 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) if not os.path.exists('labels/'): #生成的label放在label目錄下 os.makedirs('labels/') for rootDir,dirs,files in os.walk(TrainLabel_Dir): for file in files: file_name = file.split('.')[0] out_file = open('labels/%s.txt'%(file_name),'w') in_file = open("%s/%s"%(rootDir,file)) 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'): 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("0" + " " + " ".join([str(a) for a in bb]) + '\n') #我這裡只有一類,所以類別只是0. out_file.close()
這樣我們就生成了YOLO格式的標記檔案了。如果按照上面的python程式碼,生成的標記檔案在當前路徑的label目錄下。
用此方法分別生成train和val的標記檔案
1.2 生成原圖片絕對路徑檔案
在YOLO的訓練中,還需要一個txt檔案來記錄所有待訓練圖片的絕對路徑。即train資料夾下所有圖片的絕對路徑,python程式碼如下:
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join TrainDir = '/home/ubuntu/data/train' #訓練檔案所在目錄 out_file = open('train.txt','w') #生成的txt檔案 for root,dirs,files in os.walk(TrainDir): for file in files: out_file.write('%s/%s\n'%(root,file)) out_file.close()
用此方法分別生成train和val的txt檔案。
1.3 將原圖片和標記檔案放在一起
YOLO是直接通過替換原圖片絕對路徑的字尾名來找到對應標記檔案的。比如原圖片的絕對路徑為/home/ubuntu/data/train/1.jpg。則YOLO將會直接認為其對應的標記檔案路徑為/home/ubuntu/data/train/1.txt。所以,我們將之前1.1生成的標記檔案放到對應的原圖片目錄下。
2. 修改檔案
2.1 建立names檔案
在YOLO主目錄的data資料夾下,建立一個.names檔案,檔名任意。比如mydata.names。在該檔案中寫入所有類別的名稱,每一類佔一行。比如我這裡只檢測行人這一類,那麼只在第一行寫上"person"即可。
2.2 修改data檔案
接下來我們要做的是修改YOLO的cfg檔案。在darknet的主目錄下,進入cfg目錄,找到voc.data開啟,修改其中的內容
classes= 1 #訓練資料的類別數目,我這裡只有一類,所以這裡是1
train = <path-to-voc>/train.txt #上面1.2步驟生成的train檔案路徑
valid = <path-to-voc>2007_test.txt #上面1.2步驟生成的val檔案路徑
names = data/voc.names #上面2.1步驟建立的names檔案路徑
backup = backup #這是訓練得到的model的存放目錄,建議自己修改。
2.3 修改cfg檔案
如果你想應用yolo_voc.cfg網路來訓練你的資料,那麼你需要修改這個檔案中的一些內容。
- [region]層中classes改成你的類別數,我這裡只檢測行人,所以我改成了classes=1.
- [region]層上方的[convolution]層中,filters的數量改成(classes+coords+1)*NUM。我這裡改成了(1+4+1)*5=30.具體可以參考https://groups.google.com/forum/#!topic/darknet/B4rSpOo84yg
2.4 修改src/yolo.c檔案
- 第13行改成 char *voc_names[] = {"person"}; //如果你是一類的話,就改成這樣,如果你有多類,自己根據需求改。
- 第322行draw_detections函式中,最後一個引數由20改成你的類別數,我這裡是1。
- 第354行demo函式中,倒數第三個引數由20改成你的類別數,我這裡是1.
- 第17行改成 char *train_images = "<path-to-voc>/train.txt"; //上面1.2步驟生成的train檔案路徑
- 第18行改成 char *backup_directory = "/home/Ubuntu/Downloads/darknet-master/backup/"; //這個路徑自己指定。
- 第121行改成 char *base = "/home/Ubuntu/Downloads/darknet-master/results/comp4_det_test_"; //這個路徑自己指定。
- 第123行改成 list *plist = get_paths("<path-to-voc>/val.txt"); //上面1.2步驟生成的val檔案路徑
- 第209行改成 char *base = "/home/Ubuntu/Downloads/darknet-master/results/comp4_det_test_"; //這個路徑自己指定
- 第210行改成 list *plist = get_paths("<path-to-voc>/val.txt"); //上面1.2步驟生成的val檔案路徑
2.5 修改src/yolo_kernels.cu檔案
第62行draw_detections函式最後一個引數由20改成你的類別數,我這裡是1.
2.6 修改src/detector.c檔案
第368行改成 list *plist = get_paths("<path-to-voc>/train.txt"); #上面1.2步驟生成的train檔案路徑
第539行option_find_int函式的最後一個引數由20改成1.
2.7 重新編譯darknet yolo
cd <darknet_root>
make clean
make -j16
3. 訓練
所有的步驟都已經準備好了。最後就是訓練了。為了加快訓練速度,我們可以下載官方提供的預訓練模型。下載地址為
curl -O http://pjreddie.com/media/files/darknet19_448.conv.23
最後,我們cd到darknet的主目錄,輸入下面的指令來進行訓練
./darknet detector train cfg/voc.data cfg/yolo-voc.cfg darknet19_448.conv.23
這其中voc.data就是2.2中修改後的data檔案,yolo-voc.cfg是網路結構檔案,darknet19_448.conv.23是下載的預訓練模型。
整個的訓練時間比較長,慢慢等吧。。。。。