文章目录[隐藏]
一、YOLOV5 实现检测
1.1 下载源码
官方地址下载源码 YoloV5
1.2 下载模型
下载官方模型,官方提供预训练模型,下载地址为谷歌云盘
二、YOLOV5训练数据集
2.1 火焰数据集
实验数据集共有2059张具有标签的火焰图片。
数据集下载地址
其中Annotations文件里存放的是带标注的xml文件,Image中存放的是火焰图片。
2.2 制作数据集
使用脚本voc_label.py生成labels文件,train.txt以及test.txt。其中labels是从Annotations/xxx.xml中提取的不同图像的标注信息,并采用.txt的形式存储。 train.txt 和 test.txt中分别为训练图像的绝对位置。
voc_label.py
# 缺陷坐标xml转txt
import os
import xml.etree.ElementTree as ET
import os
import random
classes = ["fire"] # 输入类别名称,必须与xml标注名称一致
def convert(size, box):
print(size, box)
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
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):
if not os.path.exists('data/labels/'):
os.makedirs('data/labels/')
in_file = open(r'./data/Annotations/%s' % (image_id), 'rb') # 读取xml文件路径
out_file = open('./data/labels/%s.txt' % (image_id.split('.')[0]), 'w') # 需要保存的txt格式文件路径
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'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls) + 1
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')
image_ids_train = os.listdir('./data/Annotations') # 读取xml文件名索引
for image_id in image_ids_train:
print(image_id)
convert_annotation(image_id)
trainval_percent = 0.1 # 可自行进行调节
train_percent = 1
xmlfilepath = './data/JPEGImages'
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)
ftest = open('./data/test.txt', 'w')
ftrain = open('./data/train.txt', 'w')
for i in list:
name = total_xml[i] + '\n'
if i in trainval:
if i in train:
ftest.write('data/JPEGImages/' + name)
else:
ftrain.write('data/JPEGImages/' + name)
ftrain.close()
ftest.close()
xxx.txt中的内容如下:
此时,我们准备好了训练所需要的训练集,下一步需要对模型进行配置。
2.3 修改文件
2.3.1 修改数据集yaml文件
可以修改data文件夹下的.yaml文件,由于是焰火检测,可以新建一个fire.yaml文件,内容如下:
train: ../data/train.txt
val: ../data/test.txt
# number of classes
nc: 1
# class names
names: ['fire']
nc为检测物体的种类个数,例如只检测火焰一种类型,nc=1
2.3.2 修改网络参数的yaml文件
修改./models/yolov5s.yaml文件,使用哪个模型修改哪个文件即可。其中nc的值要修改为检测物品的种类个数。
# fire parameters
nc: 1 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
# anchors
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Focus, [64, 3]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, BottleneckCSP, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 9, BottleneckCSP, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, BottleneckCSP, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 1, SPP, [1024, [5, 9, 13]]],
[-1, 3, BottleneckCSP, [1024, False]], # 9
]
# YOLOv5 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, BottleneckCSP, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, BottleneckCSP, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, BottleneckCSP, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, BottleneckCSP, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
2.3.3 修改train.py中的训练参数
parser.add_argument('--weights', type=str, default='weights/yolov5s.pt', help='initial weights path') # 预训练模型
parser.add_argument('--cfg', type=str, default='models/yolov5s_fs.yaml', help='model.yaml path') # 2.3.2中配置文件
parser.add_argument('--data', type=str, default='data/fire.yaml', help='data.yaml path') # 数据集信息
parser.add_argument('--epochs', type=int, default=300)
parser.add_argument('--batch_size', type=int, default=16, help='total batch size for all GPUs')
parser.add_argument('--img_size', nargs='+', type=int, default=[640, 640], help='train,test sizes')
2.4 开始训练模型
python3 train.py
训练过程如下图所示:
Tips:本实验在阿里天池服务器下运行,阿里天池只能连续使用8小时,当8小时未训练结束,可以采用如下方式继续训练模型。
在train.py中如下两个参数更改为:
parser.add_argument('--weights', type=str, default='weights/last.pt', help='initial weights path')
parser.add_argument('--resume', nargs='?', const='get_last', default=True, help='resume from given path/last.pt, or most recent run if blank')
或者执行:
python3 train.py --weights ./weights/last.pt --resume==True
训练结果如下图示:
三、训练结果
使用detect.py测试:
parser.add_argument('--weights', type=str, default='weights/last.pt', help='model.pt path')
parser.add_argument('--source', type=str, default='0', help='source') # file/folder, 0 for webcam
parser.add_argument('--output', type=str, default='inference/output', help='output folder') # output folder
python3 detect.py --source ./inference/fire
检测结果:
参考文章:
https://blog.csdn.net/weixin_43871135/article/details/106803636
版权声明:本文为CSDN博主「开普勒醒醒吧」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lioe_1995/article/details/114703597
暂无评论