YOLOV5训练自己的数据集时,train里面的图片有七千多张,为什么这显示的只是验证集的981张图片
这一行本来就是专门显示验证集的,不懂的话建议查一下训练过程的参数说明不要自己猜测。
【相关推荐】
现在开始训练自己的网络:
由于很多用户使用像LabelImg这样的工具来生成xml格式注释,所以在VOC dataset上添加了一个演示脚本来进行转换,转换成我们需要的格式。如下:
0 xxx/xxx/a.jpg 1920 1080 0 453 369 473 391 1 588 245 608 268
1 xxx/xxx/b.jpg 1920 1080 1 466 403 485 422 2 793 300 809 320
详细的代码在misc/parse_voc_xml.py
1.在misc/ 下建立voc_names.txt,文本中写入自己的目标的名字,如下图所示:
2.由于运行自己的数据集,所以对parse_voc_xml.py代码进行了修改:
首先由于我的xml文件中并没有图片的Size信息,所以height = tree.findtext("./size/height")和width = tree.findtext("./size/width")这两句代码需要改了,手动改成自己图片的大小,注意的是要写成字符串类型。
其次,原数据集是对voc07和voc12进行拼凑作为训练测试等,我是利用自己的数据集,所以需要修改一下
# coding: utf-8
import xml.etree.ElementTree as ET
import os
names_dict = {}
cnt = 0
f = open('./voc_names.txt', 'r').readlines()
for line in f:
line = line.strip()
names_dict[line] = cnt
cnt += 1
#原来的代码是将voc2007和voc2012整合到了一起,并且把验证集用来做测试集了,我认为不对,进行了修改
#我按照自己的数据集修改了代码,得到val、test、train
voc_07 = '/home/dlut/网络/bolt_1_YOLOv3_TensorFlow/bolt/VOC2018'
# voc_07 = '/data/VOCdevkit/VOC2007'
# voc_12 = '/data/VOCdevkit/VOC2012'
# anno_path = [os.path.join(voc_07, 'Annotations'), os.path.join(voc_12, 'Annotations')]
# img_path = [os.path.join(voc_07, 'JPEGImages'), os.path.join(voc_12, 'JPEGImages')]
anno_path = [os.path.join(voc_07, 'Annotations')]
img_path = [os.path.join(voc_07, 'JPEGImages')]
#trainval_path = [os.path.join(voc_07, 'ImageSets/Main/trainval.txt')]
train_path = [os.path.join(voc_07, 'ImageSets/Main/train.txt')]
# os.path.join(voc_12, 'ImageSets/Main/trainval.txt')]
test_path = [os.path.join(voc_07, 'ImageSets/Main/test.txt')]
val_path = [os.path.join(voc_07, 'ImageSets/Main/val.txt')] #自己添加了验证集
#原来的代码没有验证集,自己添加了验证集
def parse_xml(path):
tree = ET.parse(path)
img_name = path.split('/')[-1][:-4]
#height = tree.findtext("./size/height")
#width = tree.findtext("./size/width")
height = '960'
width = '960' #由于我的xml文件中没有Size这一项,所以图片的宽度高度自己手动写了一下
#注意要为字符串,以前写960报错,改了'960'字符串以后才可以
objects = [img_name, width, height]
for obj in tree.findall('object'):
difficult = obj.find('difficult').text
if difficult == '1':
continue
name = obj.find('name').text
bbox = obj.find('bndbox')
xmin = bbox.find('xmin').text
ymin = bbox.find('ymin').text
xmax = bbox.find('xmax').text
ymax = bbox.find('ymax').text
name = str(names_dict[name])
objects.extend([name, xmin, ymin, xmax, ymax])
if len(objects) > 1:
return objects
else:
return None
test_cnt = 0
def gen_test_txt(txt_path):
global test_cnt
f = open(txt_path, 'w')
for i, path in enumerate(test_path):
img_names = open(path, 'r').readlines()
for img_name in img_names:
img_name = img_name.strip()
xml_path = anno_path[i] + '/' + img_name + '.xml'
objects = parse_xml(xml_path)
if objects:
objects[0] = img_path[i] + '/' + img_name + '.jpg'
if os.path.exists(objects[0]):
objects.insert(0, str(test_cnt))
test_cnt += 1
objects = ' '.join(objects) + '\n'
f.write(objects)
f.close()
train_cnt = 0
def gen_train_txt(txt_path):
global train_cnt
f = open(txt_path, 'w')
for i, path in enumerate(train_path):
img_names = open(path, 'r').readlines()
for img_name in img_names:
img_name = img_name.strip()
xml_path = anno_path[i] + '/' + img_name + '.xml'
objects = parse_xml(xml_path)
if objects:
objects[0] = img_path[i] + '/' + img_name + '.jpg'
if os.path.exists(objects[0]):
objects.insert(0, str(train_cnt))
train_cnt += 1
objects = ' '.join(objects) + '\n'
f.write(objects)
f.close()
val_cnt=0
##############################自己写的函数##############################
def gen_val_txt(txt_path):
global val_cnt
f = open(txt_path, 'w')
for i, path in enumerate(val_path):
img_names = open(path, 'r').readlines()
for img_name in img_names:
img_name = img_name.strip()
xml_path = anno_path[i] + '/' + img_name + '.xml'
objects = parse_xml(xml_path)
if objects:
objects[0] = img_path[i] + '/' + img_name + '.jpg'
if os.path.exists(objects[0]):
objects.insert(0, str(val_cnt))
val_cnt += 1
objects = ' '.join(objects) + '\n'
f.write(objects)
f.close()
gen_train_txt('train.txt')
gen_test_txt('test.txt')
gen_val_txt('val.txt')
结果展示:
3.把misc下的刚才生成的train.txt文件放在和get_kmeans.py同一文件夹下。
4.运行get_kmeans.py脚本。
将得到的数字,放在data文件下的yolo_anchors.txt的文本中,如图:
5.原来的目标名称在coco.names中,现在训练自己的数据集,目标存放在voc_names.txt中,所以把voc_names.txt放在data目录下,同时可以删除coco.names。并把刚才生成的train test val等放在data/my_data文件下。
6.修改args中的代码:
首先将带有coco.names的修改为voc_names.txt,class_name_path = './data/voc_names.txt'
然后其余的学习率,epoch,优化器选择…等等参数由自己进行确定。
另外,需要将刚才生成的val.txt、train.txt、以及test.txt放在data/mydata目录下。
7.开始训练吧,打开train.py加入两行代码:import os
和os.environ["CUDA_VISIBLE_DEVICES"] = "0"
这两行表示利用GPU进行训练。
然后就可以运行train.py,进行训练了。如图: