YOLO3訓練widerface數據集


因為YOLO3速度精度都很棒,所以想訓練一下人臉模型,廢話不多,進入正題

1寫所有的配置文件

1.1 YOLO3-face.cfg

個人感覺YOLO的配置文件騎士和caffe差不多

在cfg/YOLO3.cfg的文件上改,生成自己的cfg/yolo3-face.cfg

 1 [net]
 2 # Testing
 3 # batch=1
 4 # subdivisions=1
 5 # Training
 6 batch=64
 7 subdivisions=16
 8 width=416
 9 height=416
10 channels=3
11 momentum=0.9
12 decay=0.0005
13 angle=0
14 saturation = 1.5
15 exposure = 1.5
16 hue=.1

其中:

batch=64                          每batch個樣本更新一次參數。

subdivisions=16               如果內存不夠大,將batch分割為subdivisions個子batch,每個子batch的大小為batch/subdivisions。

訓練的話把上面注釋掉,測試就把訓練部分的注釋掉

學習率啥的就不改了,自己看着學吧

到配置文件底部更改最后的conv層參數

 1 [convolutional]
 2 batch_normalize=1
 3 filters=128
 4 size=1
 5 stride=1
 6 pad=1
 7 activation=leaky
 8 
 9 [convolutional]
10 batch_normalize=1
11 size=3
12 stride=1
13 pad=1
14 filters=256
15 activation=leaky
16 
17 [convolutional]
18 size=1
19 stride=1
20 pad=1
21 filters=18
22 activation=linear
23 
24 [yolo]
25 mask = 0,1,2
26 anchors = 10,13,  16,30,  33,23,  30,61,  62,45,  59,119,  116,90,  156,198,  373,326
27 classes=1
28 num=9
29 jitter=.3
30 ignore_thresh = .5
31 truth_thresh = 1
32 random=1

多截取了一點,只要改最后一部分就可以,(友情提醒,YOLO里面這個模塊有三處,都改,估計為了收斂用的輔助)

filter=3*(4+1+classes)

classes=1

這里我的是人臉檢測,so classes=1

下面的anchors懶得改了,理論上像我檢測的人臉一般都是偏正方形,像(16,30)這種是沒什么必要的

1.2 widerface.data

在cfg/voc.data基礎上改

1 classes= 1
2 train  = /home/liuzg/yolo/darknet3/darknet/Pkj_face_scripts/train.txt
3 valid  = /home/liuzg/yolo/darknet3/darknet/Pkj_face_scripts/test.txt
4 names = data/widerface.names
5 backup = backup

train和valid就是yolo需要的訓練集和交叉訓練集所需要的目錄,后面講生成方法

1.3 widerface.names

data/widerface.names 照抄coco.names格式,我這里檢測人臉,整個文件只有一行face

 

2 數據集處理方法

記住你的唯一核心目的就是要生成上面1.2里面那兩個txt文件,下面講的所有方法都是輔助,你拿什么生成那兩個文件和YOLO訓練沒有半毛錢關系

1 下載widerface數據集

2 轉化成VOC格式

我是按這位老兄的腳本搞得,新手拿這個上路其實還是有點坑的,先拿這個講

https://blog.csdn.net/minstyrain/article/details/77986262

為什么講他坑呢,因為他腳本里面第122行(可能我自己改過了,反正附近吧)

1 filename=filename.replace("/","_")  

他把文件路徑名里面的路徑給換了,后來也知道他為什么要換了,但是會有其他坑,所以記住核心目的就行,腳本不行,后面配合部分人工簡單操作湊合過吧,go on

運行腳本后你得到了一個類似於VOC格式的數據集

3 接下來看官網 https://pjreddie.com/darknet/yolo/

官網大神已經給你寫好腳本了,把VOC格式轉化成YOLO格式

wget https://pjreddie.com/media/files/voc_label.py

python voc_label.py

當然我前面說了我們的是類VOC格式,所以還是要改滴,講不清,直接貼代碼吧,反正也就是各種路徑找不到的問題,還有上面轉VOC格式的時候,

那老哥好像還把一部分不好的數據給刪了,所以並不是所有widerface數據都在VOC格式里面

 1 import xml.etree.ElementTree as ET
 2 import pickle
 3 import os
 4 import re
 5 from os import listdir, getcwd
 6 from os.path import join
 7 
 8 sets=[('trainval'), ('test')]
 9 
10 classes = ["face"]
11 
12 
13 def convert(size, box):
14     dw = 1./(size[0])
15     dh = 1./(size[1])
16     x = (box[0] + box[1])/2.0 - 1
17     y = (box[2] + box[3])/2.0 - 1
18     w = box[1] - box[0]
19     h = box[3] - box[2]
20     x = x*dw
21     w = w*dw
22     y = y*dh
23     h = h*dh
24     return (x,y,w,h)
25 
26 def convert_annotation(image_id):
27     image_id_chage=image_id.replace('/','_')    
28     dirname=image_id[:image_id.find('/')]
29     if not os.path.exists('wider-faces/labels/%s/'%(dirname)):
30         os.makedirs('wider-faces/labels/%s/'%(dirname))
31     in_file = open('wider-faces/Annotations/%s.xml'%(image_id_chage))
32     out_file = open('wider-faces/labels/%s.txt'%(image_id), 'w')
33     tree=ET.parse(in_file)
34     root = tree.getroot()
35     size = root.find('size')
36     w = int(size.find('width').text)
37     h = int(size.find('height').text)
38 
39     for obj in root.iter('object'):
40         difficult = obj.find('difficult').text
41         cls = obj.find('name').text
42         if cls not in classes or int(difficult)==1:
43             continue
44         cls_id = classes.index(cls)
45         xmlbox = obj.find('bndbox')
46         b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
47         bb = convert((w,h), b)
48         out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
49 
50 wd = getcwd()
51 
52 for image_set in sets:
53     if not os.path.exists('wider-faces/labels/'):
54         os.makedirs('wider-faces/labels/')
55     image_ids = open('wider-faces/ImageSets/Main/%s.txt'%(image_set)).read().strip().split()
56     list_file = open('%s.txt'%(image_set), 'w')
57     for image_id in image_ids:
58         if not os.path.exists('wider-faces/Annotations/%s.xml'%(image_id)):
59             continue
60         image_id=image_id[:image_id.find(re.findall("\d",image_id)[0],4)-1]+'/'+image_id[image_id.find(re.findall("\d",image_id)[0],4):]
61         list_file.write('%s/wider-faces/WIDER_%s/images/%s.jpg\n'%(wd, image_set, image_id))
62         convert_annotation(image_id)
63     list_file.close()
64 
65 os.system("cat trainval.txt > train.txt")
66 os.system("cat trainval.txt test.txt > train.all.txt")

估計我的要直接用也難,講一下要改的地方吧

官網大神分三類,訓練集,交叉集,測試集,我這里只有訓練集trainval,交叉集test,不要問我為什么名字不對應,我自己也被搞了半天,煩死了

convert_annatation函數就是把VOC的標記坐標格式轉成YOLO認識的格式,中間我多了一個image_id_change就是因為上面那老哥把"/"換成"_"了,各種路徑找不到

最后呢還需要一點人工操作

把widerface/labels復制拷貝到WINDER_trainval和WINDER_test下面,ok,到此為止,假設你一切順利的話就可以訓練了

3 官網下個預訓練模型,把上面配置文件1.2里面的兩個路徑改成你自己的,訓練吧,小伙子




 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM