Yolov7训练自己的数据集全流程

一、项目介绍

使用Yolov7做目标检测是常见的选择,目前YOLO系列已有yolov8,是一种即为流行的目标检测算法,相较于传统的目标检测算法,YOLO系列算法具有实时性,同时具有更快的检测速度和较高的精度。YOLOv7的主要创新如下:1. 单阶段检测:YOLOv7采用单个神经网络模型,直接在整个图像上进行目标检测,无需使用候选区域提取或多级分类器。2. 实时性能:YOLOv7能够以非常快的速度进行目标检测,适用于实时应用场景。3. 多尺度特征融合:YOLOv7通过使用不同尺度的特征图进行目标检测,能够更好地捕捉不同尺度的目标。4. Anchor Boxes:YOLOv7使用Anchor Boxes来预测目标的边界框,可以更好地适应不同形状和尺寸的目标。5. 高精度检测:YOLOv7在保持实时性能的同时,也具备较高的目标检测精度。

接下来是使用YOLOv7训练自己的数据集的全流程:1、下载源码 2、数据准备 3、修改配置文件参数 4、模型训练  5、模型预测。我会一步步为大家介绍。

二、具体步骤

1、下载源码:

官方源码github地址如下: https://github.com/WongKinYiu/yolov7    下载好压缩包后再用pycharm创建好工程,解压缩,这样就得到我们的源码。接下来,你需要仔细地根据requirements.txt配置好环境。我的做法是:用anaconda先创建一个虚拟环境,例如我想创建一个python3.6的虚拟环境,就可以在工程目录下打开cmd,然后输入conda create -n myenv python=3.6,这样就创建完成一个名为myenv的虚拟环境。我们每次需要激活它才能使用:conda activate myenv。

然后,输入conda install --file requirements.txt,这样就可以安装所有依赖项。当然,你可能会遇到安装超时问题,这时需要你把不能正常安装的依赖项用whl的方法安装,打开download.pytorch.org/whl/torch_stable.html网站,查找需要的依赖项下载到本地,在cmd中输入pip install 文件名.whl可以安装。需要注意的是,有些依赖项的不同版本可能会相互冲突,这样会产生一些常见的问题:

1、cuda,pytorch,torchvision版本之间相互不兼容,怎么办?:第一、你需要在pytorch官方或其他方法确认你的cuda所兼容的pytorch,torchvision版本,手动下载纠正。第二、pytorch,torchvision会存在cpu版本和gpu版本,我们一般需要下载的是前缀有cu+数字的版本。第三、你也可以通过换源的方法加速你的下载速度。

2、cuda需要提前安装,查看适合的cuda版本:cmd,然后nvidia-smi,这样可以查看兼容的CUDA版本,访问以下链接:https://developer.nvidia.com/cuda-gpus,在CUDA-GPUs部分的搜索框中,输入您的GPU型号,并从下拉列表中选择相应的型号。在结果页面中,找到与你的GPU型号兼容的CUDA版本,下载。

2、数据准备(打标签):

YOLOv7需要的数据集结构:

--Annotations
  --00001.xml
  --00002.xml
  .....
--JPEGImages
  --00001.jpg
  --00002.jpg

需要准备一定数量的各类别的图片,还需要安装labelimg,你只需在终端输入pip install labelimg即可安装,之后输入labelimg打开,长下面这样的:

点击open dir是寻找要打标签的文件夹,即JPEGImages,然后选择生成xml的文件夹,即Annotations,再选择view ->​Auto save mode开启自动保存。按w键拖动框柱要框柱的类别,这个相当于标签,即模型学习的答案,所以标签的质量会影响到模型的效果。全部标注好之后可以查看Annotations是否生成所有的xml。打标签环节结束。

3、修改配置文件参数

打开data文件夹,这里有官方的voc.yaml文件,你需要自己创建一个类似的.yaml文件,按情况修改以下参数:nc(类别数),names(类别名),然后根据JPEGImages和Annotations的信息进行voc_to_yolo的转换,创建一个python脚本,具体代码:

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
import random
from shutil import copyfile

classes = ["one","two",]

TRAIN_RATIO = 50


def clear_hidden_files(path):
    dir_list = os.listdir(path)
    for i in dir_list:
        abspath = os.path.join(os.path.abspath(path), i)
        if os.path.isfile(abspath):
            if i.startswith("._"):
                os.remove(abspath)
        else:
            clear_hidden_files(abspath)


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(image_id):
    in_file = open('VOCdevkit/VOC2007/Annotations/%s.xml' % image_id)
    out_file = open('VOCdevkit/VOC2007/YOLOLabels/%s.txt' % 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:
            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')
    in_file.close()
    out_file.close()


wd = os.getcwd()
wd = os.getcwd()
data_base_dir = os.path.join(wd, "VOCdevkit/")
if not os.path.isdir(data_base_dir):
    os.mkdir(data_base_dir)
work_sapce_dir = os.path.join(data_base_dir, "VOC2007/")
if not os.path.isdir(work_sapce_dir):
    os.mkdir(work_sapce_dir)
annotation_dir = os.path.join(work_sapce_dir, "Annotations/")
if not os.path.isdir(annotation_dir):
    os.mkdir(annotation_dir)
clear_hidden_files(annotation_dir)
image_dir = os.path.join(work_sapce_dir, "JPEGImages/")
if not os.path.isdir(image_dir):
    os.mkdir(image_dir)
clear_hidden_files(image_dir)
yolo_labels_dir = os.path.join(work_sapce_dir, "YOLOLabels/")
if not os.path.isdir(yolo_labels_dir):
    os.mkdir(yolo_labels_dir)
clear_hidden_files(yolo_labels_dir)
yolov5_images_dir = os.path.join(data_base_dir, "images/")
if not os.path.isdir(yolov5_images_dir):
    os.mkdir(yolov5_images_dir)
clear_hidden_files(yolov5_images_dir)
yolov5_labels_dir = os.path.join(data_base_dir, "labels/")
if not os.path.isdir(yolov5_labels_dir):
    os.mkdir(yolov5_labels_dir)
clear_hidden_files(yolov5_labels_dir)
yolov5_images_train_dir = os.path.join(yolov5_images_dir, "train/")
if not os.path.isdir(yolov5_images_train_dir):
    os.mkdir(yolov5_images_train_dir)
clear_hidden_files(yolov5_images_train_dir)
yolov5_images_test_dir = os.path.join(yolov5_images_dir, "val/")
if not os.path.isdir(yolov5_images_test_dir):
    os.mkdir(yolov5_images_test_dir)
clear_hidden_files(yolov5_images_test_dir)
yolov5_labels_train_dir = os.path.join(yolov5_labels_dir, "train/")
if not os.path.isdir(yolov5_labels_train_dir):
    os.mkdir(yolov5_labels_train_dir)
clear_hidden_files(yolov5_labels_train_dir)
yolov5_labels_test_dir = os.path.join(yolov5_labels_dir, "val/")
if not os.path.isdir(yolov5_labels_test_dir):
    os.mkdir(yolov5_labels_test_dir)
clear_hidden_files(yolov5_labels_test_dir)

train_file = open(os.path.join(wd, "yolov7_train.txt"), 'w')
test_file = open(os.path.join(wd, "yolov7_val.txt"), 'w')
train_file.close()
test_file.close()
train_file = open(os.path.join(wd, "yolov7_train.txt"), 'a')
test_file = open(os.path.join(wd, "yolov7_val.txt"), 'a')
list_imgs = os.listdir(image_dir)  # list image files
prob = random.randint(1, 100)
print("Probability: %d" % prob)
for i in range(0, len(list_imgs)):
    path = os.path.join(image_dir, list_imgs[i])
    if os.path.isfile(path):
        image_path = image_dir + list_imgs[i]
        voc_path = list_imgs[i]
        (nameWithoutExtention, extention) = os.path.splitext(os.path.basename(image_path))
        (voc_nameWithoutExtention, voc_extention) = os.path.splitext(os.path.basename(voc_path))
        annotation_name = nameWithoutExtention + '.xml'
        annotation_path = os.path.join(annotation_dir, annotation_name)
        label_name = nameWithoutExtention + '.txt'
        label_path = os.path.join(yolo_labels_dir, label_name)
    prob = random.randint(1, 100)
    print("Probability: %d" % prob)
    if (prob < TRAIN_RATIO):  # train dataset
        if os.path.exists(annotation_path):
            train_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention)  # convert label
            copyfile(image_path, yolov5_images_train_dir + voc_path)
            copyfile(label_path, yolov5_labels_train_dir + label_name)
    else:  # test dataset
        if os.path.exists(annotation_path):
            test_file.write(image_path + '\n')
            convert_annotation(nameWithoutExtention)  # convert label
            copyfile(image_path, yolov5_images_test_dir + voc_path)
            copyfile(label_path, yolov5_labels_test_dir + label_name)
train_file.close()
test_file.close()

你只需要修改类别数即可。运行之后会在VOCdevkit里生成images和labels文件夹。这时你要找到之前创建的.yaml文件,修改train和val的路径,改成images里的train和val。此环节结束。

4、训练环节

接下来看看train,py,从522行(左右)起是主程序,修改weights为‘yolov7.pt’,如果你没有这个文件,可以到github去下载(上述),修改data为你的.yaml文件,修改epochs,batchsize,img-size,device,workers为你想要参数(不改也可以),然后运行。训练好的模型在runs/train

5、detect

打开detect.py,将训练好的.pth文件放到weights,souce选择预测模式(图片、视频、摄像头),其他的不用改。

这样,你就能用自己的数据集得到需要的目标检测模型!!!

以上为全部内容。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值