配置YOLOv7训练自己是数据集【踩坑记录】

随手记录一下YOLOv7的配置。环境:
window 10 专业版
Python3.8
Pytorch2.1

参考资料

1、HIT-UAV-Infrared-Thermal-Dataset
2、WongKinYiu/yolov7
3、【小白教学】如何用YOLOv7训练自己的数据集
4、目标检测中数据集格式之间的相互转换–coco、voc、yolo
5、YoloV7实战:手把手教你使用Yolov7进行物体检测(附数据集)
6、【特训营第三期】无人机高空红外检测
7、YOLOv7保姆级教程(个人踩坑无数)----训练自己的数据集

1、第一次踩坑【未解决】

1.1、数据集准备

使用开源的HIT-UAV数据集。有四种格式的数据,使用normal_xml文件下的,这个是voc格式的数据

1.2、配置YOLO

  • 创建文件夹datasets,统一管理数据集
  • 创建文件夹weights,存放模型参数

1.2.1、配置网络参数

复制文件..\yolov7-main\cfg\training\yolov7.yaml,重命名为yolov7-HITUAV.yaml,修改分类的种类:
在这里插入图片描述

1.2.2、修改数据集配置

复制文件..\yolov7-main\data\coco.yaml,重命名为..\yolov7-main\data\HITUAV.yaml,针对数据集进行修改:
在这里插入图片描述

1.2.3、配置训练参数

官网下载预训练模型yolov7_training.pt,放到文件夹weights中。

train.py文件中,针对上面的配置,设定相关的参数:
在这里插入图片描述
就这样运行训练,会报错的:
在这里插入图片描述
需要把.yaml文件中的中文删除掉,不能留有中文,不然会报错。
就算是这样修改了,也是跑不起来的:
在这里插入图片描述

2、第二次踩坑【已解决】

找到了这篇博客:YOLOv7保姆级教程(个人踩坑无数)----训练自己的数据集,作者讲的很好,解决了我很多疑问和问题,推荐看!!

网络参数用上面修改的,不用修改了。

2.1、修改数据集配置

复制文件..\yolov7-main\data\coco.yaml,重命名为..\yolov7-main\data\HITUAV.yaml,针对数据集进行修改:

# COCO 2017 dataset http://cocodataset.org

# download command/URL (optional)
# download: bash ./scripts/get_coco.sh

train: ./datasets/HITUAV/VOC/TrainVal_train.txt #
val: ./datasets/HITUAV/VOC/TrainVal_val.txt #
test: ./datasets/HITUAV/VOC/Test_test.txt #
# number of classes
nc: 5
# class names
names: ["Person", "Car", "Bicycle", "OtherVehicle", "DontCare"] #

2.2、配置数据集

原来的数据集文件有:
在这里插入图片描述
Annotations为数据集的xml文件,ImageStes中再创建一个Main文件夹,JPEGImages为数据集的图片,接下来需要将xml文件划分,再转为txt文件——YOLOv7保姆级教程(个人踩坑无数)----训练自己的数据集

2.2.1、划分训练集、测试集

编写python脚本,对数据进行划分:

# 参考https://blog.csdn.net/weixin_55749226/article/details/128480595
import os
from os import listdir, getcwd
import random
 
# xmlfilepath = r'./datasets/HITUAV/VOC/Annotations/'  # xml文件的路径
# saveBasePath = r'./datasets/HITUAV/VOC/ImageSets/'  # 生成的txt文件的保存路径
wd = getcwd()
xmlfilepath = wd + '/Annotations/'  # xml文件的路径
saveBasePath = wd + '/ImageSets/'  # 生成的txt文件的保存路径
# xmlfilepath = r'G:/YOLOv7/yolov7-main/datasets/HITUAV/VOC/Annotations/'  # xml文件的路径
# saveBasePath = r'G:/YOLOv7/yolov7-main/datasets/HITUAV/VOC/ImageSets/'  # 生成的txt文件的保存路径

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("traub suze", tr)
ftrainval = open(os.path.join(saveBasePath, 'Main/trainval.txt'), 'w')
ftest = open(os.path.join(saveBasePath, 'Main/test.txt'), 'w')
ftrain = open(os.path.join(saveBasePath, 'Main/train.txt'), 'w')
fval = open(os.path.join(saveBasePath, 'Main/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()

运行结果:
在这里插入图片描述

2.2.2、生成对应的文件

创建一个voc_label.py文件:

# 参考:https://blog.csdn.net/weixin_55749226/article/details/128480595
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import  shutil
 
sets=[('TrainVal', 'train'), ('TrainVal', 'val'), ('Test', 'test')]
 
# classes =["mask_weared_incorrect","with_mask","without_mask"]
classes =["Person","Car","Bicycle","OtherVehicle","DontCare"] #需要分别标注的类别
 
def convert(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(year, image_set, image_id):
    in_file = open('Annotations/%s.xml'%( image_id))
    out_file = open('labels/%s_%s/%s.txt'%(year, image_set, image_id), 'w',encoding='utf-8')
    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')
 
def copy_images(year,image_set, image_id):
    in_file = 'JPEGImages/%s.jpg'%(image_id)
    out_flie = 'images/%s_%s/%s.jpg'%(year, image_set, image_id)
    shutil.copy(in_file, out_flie)
 
wd = getcwd()
 
for year, image_set in sets:
    if not os.path.exists('labels/%s_%s'%(year, image_set)):
        os.makedirs('labels/%s_%s'%(year, image_set))
    if not os.path.exists('images/%s_%s'%(year, image_set)):
        os.makedirs('images/%s_%s'%(year, image_set))
    image_ids = open('ImageSets/Main/%s.txt'%( image_set)).read().strip().split()
    list_file = open('%s_%s.txt'%(year, image_set), 'w')
    for image_id in image_ids:
        list_file.write('%s/images/%s_%s/%s.jpg\n'%(wd, year, image_set, image_id))
        convert_annotation(year, image_set, image_id)
        copy_images(year, image_set, image_id)
 
    list_file.close() 

运行后,文件变为了:
在这里插入图片描述
其中,文件imageslabels很重要,训练的时候会默认搜索这两个文件找数据,如果没有,会报错。

其他的使用上面的设置就行。

3、训练

要注意:
batchsize需要根据显卡来配置,本人使用RTX1060 6GB,设为8才不会爆显存!

运行结果:
在这里插入图片描述
算是成功运行了。

下一步需要根据自己的数据进行打标,再说吧。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值