首页 > 其他分享 >tensorflow yolov3训练自己的数据集,详细教程

tensorflow yolov3训练自己的数据集,详细教程

时间:2023-03-17 19:00:46浏览次数:51  
标签:教程 yolov3 join data train path test tensorflow os


这个教程是我在自己学习的过程中写的,当作一个笔记,写的比较详细
在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. 1)JPEGImages文件夹

文件夹里包含了训练图片和测试图片,混放在一起

  1. 2)Annatations文件夹

文件夹存放的是xml格式的标签文件,每个xml文件都对应于JPEGImages文件夹的一张图片

  1. 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数据集,那么把它解压,把各个文件夹里面的东西删除,保留文件夹名字。如果没下载,那么就仿照他的文件夹格式,按照这个目录格式建立文件夹:

tensorflow yolov3训练自己的数据集,详细教程_xml


然后分别把标记的图片放入JPEGImages文件夹,标签xml文件放入Annotations文件夹:

tensorflow yolov3训练自己的数据集,详细教程_数据集_02


tensorflow yolov3训练自己的数据集,详细教程_数据集_03


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()

打开控制台,运行该python文件,后跟Annotation的目录即可进行划分:

python .\split.py F:\dateset\hat_data\VOC\test\VOCdevkit\VOC2007

在这里插入图片描述
train为训练集,test为验证集
4,根据划分结果制作训练集
上面代码已经实现了将数据集划分为训练集和验证集,但是tensorflow yolov3作者写的模型要求的数据集格式为:

tensorflow yolov3训练自己的数据集,详细教程_xml_04


所以我们需要写一个小脚本,根据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('\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)

根据这个小脚本就可进行划分为规定的格式,如果数据集的量比较大,可能有点慢,当然你也可以进行手动划分,省略前面几步操作,只要最终目录结构满足作者的格式就行

tensorflow yolov3训练自己的数据集,详细教程_xml_05


5,分别在test和train下面运行split.py脚本

python .\split.py F:\dateset\hat_data\VOC\train\VOCdevkit\VOC2007
python .\split.py F:\dateset\hat_data\VOC\test\VOCdevkit\VOC2007

二,制作标准数据集txt文件

作者在github上声明,训练需要两个文件,如下所示:

dataset.txt:

xxx/xxx.jpg 18.19,6.32,424.13,421.83,20 323.86,2.65,640.0,421.94,20 
xxx/xxx.jpg 48,240,195,371,11 8,12,352,498,14
image_path x_min, y_min, x_max, y_max, class_id x_min, y_min ,..., class_id
make sure that x_max < width and y_max < height

class.names:

person
bicycle
car
...
toothbrush

1,生成dataset.txt
其实前几步都是为这两步做准备,通过目录下的 scripts/voc_annotation.py就可以生成dataset.txt文件,但是需要改一些代码参数:
只需更改 classes为自己的类别

classes = ['hat','person']


default 更改为你自己的看注释

#default 更改为你自己数据集VOC的目录
parser.add_argument("--data_path", default="F:/dateset/hat_data/VOC")
#default 更改为voc_train.txt的存放的位置
parser.add_argument("--train_annotation", default="../data/dataset/voc_train.txt")
parser.add_argument("--test_annotation", default="../data/dataset/voc_test.txt")
flags = parser.parse_args()

if os.path.exists(flags.train_annotation):os.remove(flags.train_annotation)
if os.path.exists(flags.test_annotation):os.remove(flags.test_annotation)

#更改训练集和测试集的相对路径
num1 = convert_voc_annotation(os.path.join(flags.data_path, 'train/VOCdevkit/VOC2007'), 'trainval', flags.train_annotation, False)
num3 = convert_voc_annotation(os.path.join(flags.data_path, 'test/VOCdevkit/VOC2007'), 'trainval', flags.test_annotation, False)

其他默认即可:
更改后的代码:

import os
import argparse
import xml.etree.ElementTree as ET

def convert_voc_annotation(data_path, data_type, anno_path, use_difficult_bbox=True):

#更改为你自己的类别
classes = ['hat','person']
img_inds_file = os.path.join(data_path, 'ImageSets', 'Main', data_type + '.txt')
with open(img_inds_file, 'r') as f:
txt = f.readlines()
image_inds = [line.strip() for line in txt]

with open(anno_path, 'a') as f:
for image_ind in image_inds:
image_path = os.path.join(data_path, 'JPEGImages', image_ind + '.jpg')
annotation = image_path
label_path = os.path.join(data_path, 'Annotations', image_ind + '.xml')
root = ET.parse(label_path).getroot()
objects = root.findall('object')
for obj in objects:
difficult = obj.find('difficult').text.strip()
if (not use_difficult_bbox) and(int(difficult) == 1):
continue
bbox = obj.find('bndbox')
class_ind = classes.index(obj.find('name').text.lower().strip())
xmin = bbox.find('xmin').text.strip()
xmax = bbox.find('xmax').text.strip()
ymin = bbox.find('ymin').text.strip()
ymax = bbox.find('ymax').text.strip()
annotation += ' ' + ','.join([xmin, ymin, xmax, ymax, str(class_ind)])
print(annotation)
f.write(annotation + "\n")
return len(image_inds)


if __name__ == '__main__':
parser = argparse.ArgumentParser()
#default 更改为你自己数据集VOC的目录
parser.add_argument("--data_path", default="F:/dateset/hat_data/VOC")
#default 更改为voc_train.txt的存放的位置
parser.add_argument("--train_annotation", default="../data/dataset/voc_train.txt")
parser.add_argument("--test_annotation", default="../data/dataset/voc_test.txt")
flags = parser.parse_args()

if os.path.exists(flags.train_annotation):os.remove(flags.train_annotation)
if os.path.exists(flags.test_annotation):os.remove(flags.test_annotation)

#更改训练集和测试集的相对路径
num1 = convert_voc_annotation(os.path.join(flags.data_path, 'train/VOCdevkit/VOC2007'), 'trainval', flags.train_annotation, False)
num3 = convert_voc_annotation(os.path.join(flags.data_path, 'test/VOCdevkit/VOC2007'), 'trainval', flags.test_annotation, False)
print('=> The number of image for train is: %d\tThe number of image for test is:%d' %(num1 , num3))

更改后运行该python文件:

tensorflow yolov3训练自己的数据集,详细教程_python_06


tensorflow yolov3训练自己的数据集,详细教程_python_07


这就生成了dataset.txt

2,更改voc.names的类别

tensorflow yolov3训练自己的数据集,详细教程_数据集_08


修改为自己的类别:

tensorflow yolov3训练自己的数据集,详细教程_数据集_09


3,修改配置文件

编辑您的文件./core/config.py以进行一些必要的配置

_C.YOLO.CLASSES                = "./data/classes/voc.names"
__C.TRAIN.ANNOT_PATH = "./data/dataset/voc_train.txt"
__C.TEST.ANNOT_PATH = "./data/dataset/voc_test.txt"

到这里已经配置完成,已经可以训练了

三,训练数据

1)从头开始训练:

$ python train.py
$ tensorboard --logdir ./data

tensorflow yolov3训练自己的数据集,详细教程_数据集_10


(2)从COCO配置训练(推荐):

$ cd checkpoint
$ wget https://github.com/YunYang1994/tensorflow-yolov3/releases/download/v1.0/yolov3_coco.tar.gz
$ tar -xvf yolov3_coco.tar.gz
$ cd ..
$ python convert_weight.py --train_from_coco
$ python train.py

2.2评估VOC数据集

$ python evaluate.py
$ cd mAP
$ python main.py -na


标签:教程,yolov3,join,data,train,path,test,tensorflow,os
From: https://blog.51cto.com/u_13625033/6127861

相关文章

  • Photoshop 2023 v24.2.0中文版更新,最新PS 2023激活版下载及安装教程
    Photoshop2023是一款由AdobeSystems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。使用其众多的编修与绘图工具,可以有效地进行图片编辑工作。ps......
  • github注册以及安装教程
    github注册以及安装教程首先,我们了解一下github.gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git作为唯一的版本库格式进行托管,故名gitHub。github于......
  • 群晖7.1.1最新版本 使用ESXi虚拟机安装教程
    1、在电脑上新建一个文件夹(我在E盘建立dsm7这个文件夹),需要注意:不可以用中文或者特殊符号。下载好引导文件,全部下载完成后,然后点到下图红框处,把当前这个路径复制一下;  ......
  • tensorflow.keras.datasets 中关于imdb.load_data的使用说明
    python深度学习在加载数据时(num_words=10000)所代表的意义首先写一段深度学习加载数据集的代码:fromkeras.datasetsimportreuters(train_data,train_labels),(test_dat......
  • deepfacelab教程之软件版本选择
    AI换脸软件出来很多年了,基于deepfake衍生出来很多,比如FaceSwap,FakeAPP,再到今天要说的DeepFaceLab。目前国内用的较多的还是最后一款,DeepFaceLab,我们以下简称DFL因为是集......
  • 会声会影2023安装、激活教程
    安装前准备:1、会声会影2023的安装需要在有网络接的状态下进行。请您确保安装过程中有一个良好的网络环境,并且在安装过程中,不能断网。2、安装之前退出、关闭电脑管家以及杀毒......
  • 会声会影Video Studio 2023旗舰版怎么安装、激活教程
    会声会影(VideoStudio)2023旗舰版是加拿大Corel公司制作的一款功能强大的视频编辑软件、大型视频制作软件、专业视频剪辑软件。会声会影专业视频编辑处理软件,可以用于剪辑&......
  • 人工智能python3+tensorflow人脸识别_使用 face-api.js 在你的浏览器中做人脸识别(基于
    我很兴奋地告诉你,终于可以在浏览器中运行人脸识别了!这篇文章我将介绍face-api.js,这个类库构建于tensorflow.js之上。它实现了多个CNNs(卷积神经网络)以解决人脸检测、......
  • python爬虫基础教程
    爬虫介绍爬虫就是程序,是从互联网中,各个网站上爬取数据(能浏览到的网页才可以爬),做数据清洗,入库爬虫本质:模拟http请求,获取数据,入库网站/app>抓包我们日......
  • go微服务开发:go-zero入门教程(二)
    以下内容,参考了go-zero官方文档,是对官方文档的进阶指南章节的梳理汇总。go-zero的进阶指南,请参考 https://go-zero.dev/cn/docs/advance/business-dev 通过本文,你将学......