赞
踩
官方地址下载源码 YoloV5
下载官方模型,官方提供预训练模型,下载地址为谷歌云盘
实验数据集共有2059张具有标签的火焰图片。
数据集下载地址
其中Annotations文件里存放的是带标注的xml文件,Image中存放的是火焰图片。
使用脚本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中的内容如下:
此时,我们准备好了训练所需要的训练集,下一步需要对模型进行配置。
可以修改data文件夹下的.yaml文件,由于是焰火检测,可以新建一个fire.yaml文件,内容如下:
train: ../data/train.txt
val: ../data/test.txt
# number of classes
nc: 1
# class names
names: ['fire']
nc为检测物体的种类个数,例如只检测火焰一种类型,nc=1
修改./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) ]
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')
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。