数据,backbone,预训练的权重在文末
1. 制作数据集
转载自: https://blog.csdn.net/u012505617/article/details/79955140#t0
-
创建相应的文件夹
在yolo代码里的scripts/目录下创建VOC_person文件夹,在其文件夹下创建Annotations、ImageSets、JPEGImages文件夹,在ImageSets文件夹下建立Main文件夹。这里顺便说下这三个文件夹的作用:- Annotations – Annotations文件夹中存放的是xml格式的标签文件,每一个xml文件都对应于JPEGImages文件夹中的一张图片;
-
ImageSets – ImageSets存放的是每一种类型的challenge对应的图像数据。在ImageSets下有Main文件夹,存放的是图像物体识别的数据,总共分为20类;
-
JPEGImages – JPEGImages文件夹中包含了PASCAL VOC所提供的所有的图片信息,包括了训练图片和测试图片。
-
拷贝相应的文件
取VOC2007/ImageSets/Main/文件夹里的person_test.txt,person_trainval.txt,person_train.txt person_val.txt 这四个文件到VOC_person/ImageSets/Main/目录下;
拷贝VOC2007/Annotations/ 目录下的所有的文件到VOC_person/Annotations/ 目录下;
拷贝VOC2007/JPEGImages/ 目录下的所有的文件到VOC_person/JPEGImages/ 目录下; -
筛选文件与修改标注格式
1)打开yolo代码下的scripts目录,拷贝voc_label.py文件并重命名为person_voc_label.py 文件:
cp voc_label.py person_voc_label.py
2)直接copy下面的代码到person_voc_label.py
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
sets=['train', 'val', 'test']
classes = ["person"]
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
def convert_annotation(image_id):
in_file = open('%s/%s.xml'%(annotation_path, image_id))
out_file = open('%s/%s.txt'%(out_path, image_id), 'w')
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult)==1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
wd = getcwd()
out_path = './voc_person/labels'
label_path = './voc_person/ImageSets/Main'
image_path = os.path.realpath('./voc_person/JPEGImages')
annotation_path = './voc_person/Annotations'
for image_set in sets:
if not os.path.exists(out_path):
os.makedirs(out_path)
image_ids = open('%s/person_%s.txt'%(label_path, image_set)).read().strip().split()
list_file = open('%s/person_%s.txt'%(out_path, image_set), 'w')
for index, image_id in enumerate(image_ids):
if image_id == '1':
list_file.write('%s/%s.jpg\n'%(image_path, image_ids[index-1]))
convert_annotation(image_ids[index-1])
list_file.close()
os.system("cat ./voc_person/labels/person_train.txt ./voc_person/labels/person_val.txt > my_person_train.txt")
2. 修改yolov3配置文件
转载自: https://blog.csdn.net/qq_32747775/article/details/87919465
-
修改data/voc.names文件,只保留person一行,其余行删除。
-
修改cfg/voc.date文件,注意修改$path的路径
classes= 1
train = $path/my_person_train.txt # 训练用txt位置
valid = $path/person_test.txt # 测试用txt位置
names = data/voc.names
backup = backup # 保存的模型所在位置
- 修改cfg/yolov3-voc.cfg文件:
找到 [yolo] 层,共3处。需要修改的:
- yolo层上的convolutional层的filters,有3处
- yolo层中的classes值,有3处
[convolutional]
size=1
stride=1
pad=1
filters=18 # 修改,参考后面的说明
activation=linear
[yolo]
mask = 3,4,5
anchors = 10,14, 23,27, 37,58, 81,82, 135,169, 344,319
classes=1 # 修改
num=6
jitter=.3
ignore_thresh = .7
truth_thresh = 1
random=0
需要改变filters为 3*(classes+1+4),原因为:https://github.com/pjreddie/darknet/issues/582,同时修改下面的classes的种类。
3. 训练
-
下载预训练的backbone权重
wget https://pjreddie.com/media/files/darknet53.conv.74
-
开始训练:
./darknet detector train cfg/voc.data cfg/yolov3-voc.cfg yolov3-tiny.conv.15
4. 测试
修改cfg/yolov3-voc_person.cfg 文件,把Training的batch, subdivisions屏蔽掉,使用Testing的batch, subdivisions 都为1
# Training
#batch=32
#subdivisions=2
# Testing
batch=1
subdivisions=1
- 检测图片
./darknet detect cfg/yolov3-voc.cfg backup/yolov3-voc_person.backup data/person.jpg
5. 数据,预训练模型
下载地址:BaiDu,提取码: nnrd