tensorflow yolov3訓練自己的資料集,詳細教程
這個教程是我在自己學習的過程中寫的,當作一個筆記,寫的比較詳細
在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