這個教程是我在自己學習的過程中寫的,當作一個筆記,寫的比較詳細
在github上下載yolov3的tensorflow1.0版本:
https://github.com/YunYang1994/tensorflow-yolov3
在19年12月,發現網上訓練的教程大部分似乎已經過時了,因為作者對開源代碼進行了部分修改
其實在作者的readme上已經寫了訓練的方法,但是不是那么詳細,於是記錄下
由於本人水平有限,如果文章有不當之處還望評論區指出
一,制作訓練集
1,打標簽
訓練集需要實驗labelimg工具進行制作,這里的數據集格式采用的是voc格式:
labelimg下載地址
實驗labelimg打好標簽后會生成兩個文件夾:
Annotations —存放標記的圖片
JPEGImages —存放xml格式的標簽
這里不做多余的解釋
2,按照voc數據集格式建立文件夾
因為作者給的模型是訓練VOC數據集的模型,所以訓練我們自己的數據集的時候也需要改為VOC格式的,VOC格式解析:
第一步:首先了解VOC2007數據集的格式
- 1)JPEGImages文件夾
文件夾里包含了訓練圖片和測試圖片,混放在一起
- 2)Annatations文件夾
文件夾存放的是xml格式的標簽文件,每個xml文件都對應於JPEGImages文件夾的一張圖片
- 3)ImageSets文件夾
Action存放的是人的動作,我們暫時不用
Layout存放的人體部位的數據。我們暫時不用
Main存放的是圖像物體識別的數據,分為20類,當然我們自己制作就不一定了,如果你有精力,Main里面有test.txt , train.txt, val.txt ,trainval.txt.這四個文件我們后面會生成
train中存放的是訓練使用的數據,每一個class的train數據都有5717個。
val中存放的是驗證結果使用的數據,每一個class的val數據都有5823個。
trainval為訓練和驗證的圖片文件的文件名列表 。
Segmentation存放的是可用於分割的數據
如果你下載了VOC2007數據集,那么把它解壓,把各個文件夾里面的東西刪除,保留文件夾名字。如果沒下載,那么就仿照他的文件夾格式,按照這個目錄格式建立文件夾:
然后分別把標記的圖片放入JPEGImages文件夾,標簽xml文件放入Annotations文件夾:
3,划分訓練集和測試集
訓練時要有測試集和訓練集,通過划分放在
VOCdevkit\VOC2008\ImageSets\Main
文件夾下,這里可以使用一段python代碼按照9:1進行隨機划分:
在VOC2008文件夾建立split.py
import os import random import sys if len(sys.argv) < 2: print("no directory specified, please input target directory") exit() root_path = sys.argv[1] xmlfilepath = root_path + '/Annotations' txtsavepath = root_path + '/ImageSets/Main' if not os.path.exists(root_path): print("cannot find such directory: " + root_path) exit() if not os.path.exists(txtsavepath): os.makedirs(txtsavepath) trainval_percent = 0.9 train_percent = 0.8 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) print("train and val size:", tv) print("train size:", tr) ftrainval = open(txtsavepath + '/trainval.txt', 'w') ftest = open(txtsavepath + '/test.txt', 'w') ftrain = open(txtsavepath + '/train.txt', 'w') fval = open(txtsavepath + '/val.txt', 'w') for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else: fval.write(name) else: ftest.write(name) ftrainval.close() ftrain.close() fval.close() ftest.close()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
打開控制台,運行該python文件,后跟Annotation的目錄即可進行划分:
python .\split.py F:\dateset\hat_data\VOC\test\VOCdevkit\VOC2007
- 1
在這里插入圖片描述
train為訓練集,test為驗證集
4,根據划分結果制作訓練集
上面代碼已經實現了將數據集划分為訓練集和驗證集,但是tensorflow yolov3作者寫的模型要求的數據集格式為:
所以我們需要寫一個小腳本,根據train.txt 和test.txt將數據集進行更改
import os from shutil import copyfile #根據tarin.txt和test.txt將數據集分為標准數據集 train_text_path = 'F:/dateset/hat_data/VOCdevkit/VOC2007/ImageSets/Main/train.txt' test_text_path = 'F:/dateset/hat_data/VOCdevkit/VOC2007/ImageSets/Main/test.txt' #圖片存放地址 image_path = 'F:/dateset/hat_data/VOCdevkit/VOC2007/JPEGImages' #xml文件存放地址 xml_path = 'F:/dateset/hat_data/VOCdevkit/VOC2007/Annotations' #輸出的目錄 outdir = 'F:/dateset/hat_data' #創建各級文件夾 test_xml_out = os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/Annotations') os.makedirs(test_xml_out) os.makedirs(os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/ImageSets/Layout')) os.makedirs(os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/ImageSets/Main')) os.makedirs(os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/ImageSets/Segmentation')) test_img_out = os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/JPEGImages') os.makedirs(test_img_out) os.makedirs(os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/SegmentationClass')) os.makedirs(os.path.join(outdir,'VOC/test/VOCdevkit/VOC2007/SegmentationObject')) train_xml_out = os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/Annotations') os.makedirs(train_xml_out) os.makedirs(os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/ImageSets/Layout')) os.makedirs(os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/ImageSets/Main')) os.makedirs(os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/ImageSets/Segmentation')) train_img_out = os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/JPEGImages') os.makedirs(train_img_out) os.makedirs(os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/SegmentationClass')) os.makedirs(os.path.join(outdir,'VOC/train/VOCdevkit/VOC2007/SegmentationObject')) with open(train_text_path) as f: lines = f.readlines() for i in lines: img_save_path = os.path.join(train_img_out,i.rstrip('\n')+'.jpg') xml_save_path = os.path.join(train_xml_out, i.rstrip('\n') + '.xml') copyfile(os.path.join(image_path,i.rstrip('\n')+'.jpg'),img_save_path) copyfile(os.path.join(xml_path, i.rstrip('\n') + '.xml'), xml_save_path) print(i) with open(test_text_path) as f: lines = f.readlines() for i in lines: img_save_path = os.path.join(test_img_out, i.rstrip('\n') + '.jpg') xml_save_path = os.path.join(test_xml_out, i.rstrip