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.000513 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=13 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裏面的兩個路徑改成你自己的,訓練吧,小夥子
YOLO3訓練widerface數據集