YOLOV7训练数据集(pycharm)

参考文章:YoloV6实战:手把手教你使用Yolov6进行物体检测(附数据集)_yolov6用自己的模型检测_AI浩的博客-CSDN博客

YOLO | 用YOLOv7训练自己的数据集(超详细版)_yolo训练集_夏天|여름이다的博客-CSDN博客

一、环境配置

1、下载yolov7

git clone https://github.com/WongKinYiu/yolov7

2、添加环境

打开pycharm,在文件->设置中->python解释器->添加解释器,

在yolov7文件下找到venv/bin/python.exe,选择添加

 3、安装要求的库

根据提示一键安装,或者终端输入:

cd yolov7
pip install -r requirements.txt
pip install opencv-python-headless

下载YOLOV7的权重

wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt

下载YOLOV7的训练权重

wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7_training.pt

新建一个权重文件夹,把上述文件移到权重文件夹下

    mkdir weights
    cp yolov7.pt weights/
    cp yolov7_training.pt weights/ 

参数说明:

    --weights weight/yolov7.pt   # 这个参数是把已经训练好的模型路径传进去,就是刚刚下载的文件
    --source inference/images   # 传进去要预测的图片

二、数据处理

1、获取数据集

找到一个公开数据集进行测试,数据集是Labelme标注的数据集,下载地址:

https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/14003627

 下载后解压到yolov7文件夹中

2、生成数据标签

思路:

第一步 使用train_test_split方法切分出训练集、验证集和测试集。
第二步 调用change_2_yolo5方法将json里面的数据转为yolov5格式的txt数据,返回训练集、验证集和测试集的图片list。
第三步 创建数据集文件夹,然后将图片和txt文件copy到对应的目录下面。

新建脚本make_yolo_data.py,插入代码:

import os
import shutil
import numpy as np
import json
from glob import glob
import cv2
from sklearn.model_selection import train_test_split
from os import getcwd


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 change_2_yolo5(files, txt_Name):
    imag_name = []
    for json_file_ in files:
        json_filename = labelme_path + json_file_ + ".json"
        out_file = open('%s/%s.txt' % (labelme_path, json_file_), 'w')
        json_file = json.load(open(json_filename, "r", encoding="utf-8"))
        # image_path = labelme_path + json_file['imagePath']
        imag_name.append(json_file['imagePath'])
        height, width, channels = cv2.imread(labelme_path + json_file_ + ".jpg").shape
        for multi in json_file["shapes"]:
            points = np.array(multi["points"])
            xmin = min(points[:, 0]) if min(points[:, 0]) > 0 else 0
            xmax = max(points[:, 0]) if max(points[:, 0]) > 0 else 0
            ymin = min(points[:, 1]) if min(points[:, 1]) > 0 else 0
            ymax = max(points[:, 1]) if max(points[:, 1]) > 0 else 0
            label = multi["label"]
            if xmax <= xmin:
                pass
            elif ymax <= ymin:
                pass
            else:
                cls_id = classes.index(label)
                b = (float(xmin), float(xmax), float(ymin), float(ymax))
                bb = convert((width, height), b)
                out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
                # print(json_filename, xmin, ymin, xmax, ymax, cls_id)
    return imag_name


def image_txt_copy(files, scr_path, dst_img_path, dst_txt_path):
    """
    :param files: 图片名字组成的list
    :param scr_path: 图片的路径
    :param dst_img_path: 图片复制到的路径
    :param dst_txt_path: 图片对应的txt复制到的路径
    :return:
    """
    for file in files:
        img_path = scr_path + file
        shutil.copy(img_path, dst_img_path + file)
        scr_txt_path = scr_path + file.split('.')[0] + '.txt'
        shutil.copy(scr_txt_path, dst_txt_path + file.split('.')[0] + '.txt')


if __name__ == '__main__':
    classes = ["aircraft", "oiltank"]
    # 1.标签路径
    labelme_path = "datasets/LabelmeData/"
    isUseTest = True  # 是否创建test集
    # 3.获取待处理文件
    files = glob(labelme_path + "*.json")
    files = [i.replace("\\", "/").split("/")[-1].split(".json")[0] for i in files]
    trainval_files, test_files = train_test_split(files, test_size=0.1, random_state=55)
    # split
    train_files, val_files = train_test_split(trainval_files, test_size=0.1, random_state=55)
    train_name_list = change_2_yolo5(train_files, "train")
    print(train_name_list)
    val_name_list = change_2_yolo5(val_files, "val")
    test_name_list = change_2_yolo5(test_files, "test")
    # 创建数据集文件夹。
    file_List = ["train", "val", "test"]
    for file in file_List:
        if not os.path.exists('./datasets/images/%s' % file):
            os.makedirs('./datasets/images/%s' % file)
        if not os.path.exists('./datasets/labels/%s' % file):
            os.makedirs('./datasets/labels/%s' % file)
    image_txt_copy(train_name_list, labelme_path, './datasets/images/train/', './datasets/labels/train/')
    image_txt_copy(val_name_list, labelme_path, './datasets/images/val/', './datasets/labels/val/')
    image_txt_copy(test_name_list, labelme_path, './datasets/images/test/', './datasets/labels/test/')

记得在主函数中修改路径,将最后面的路径替换为自己想要保存的路径

生成结果如下,同时将数据集进行了分割

三、训练

1、制作自己的配置文件

一个是yolov7-mydataset.yaml,位置在项目yolov7/cfg/training下,然后复制yolov7.yaml,粘贴改为yolov7-mydataset.yaml,然后修改类别数,就得到一个新的属于自己的配置文件。

nc为类别数,改为自己的,如下面38改为自己的类别数即可。

# parameters
nc: 38 # number of classes
depth_multiple: 1.0  # model depth multiple
width_multiple: 1.0  # layer channel multiple

另外一个是mydataset.yaml,新建位置在项目yolov7/data下,复制一个yaml文件粘贴,重命名为mydataset.yaml,更改内容如下

# Please insure that your custom_dataset are put in same parent dir with YOLOv6_DIR
train: ./datasets/images/train # train images
val: ./datasets/images/val # val images
test: ./datasets/images/test # test images (optional)

# whether it is coco dataset, only coco dataset should be set to True.
is_coco: False
# Classes
nc: 2  # number of classes
names: ['aircraft', 'oiltank']  # class names

2、修改train.py

--weights: 预训练路径,填写'' 表示不使用预训练权重
--cfg    : 参数路径(./cfg/training中新建的yolov7-mydataset.yaml文件)
--data   : 数据集路径(./data中新建的mydayaset.yaml文件)
--epochs : 训练轮数
--batch-size : batch大小
--device : 训练设备,cpu-->用cpu训练,0-->用GPU训练,0,1,2,3-->用多核GPU训练
--workers: maximum number of dataloader workers
--name   : save to project/name

在train.py中向下找到参数位置,修改这几处参数,

parser.add_argument('--cfg', type=str, default='cfg/training/yolov7-mydatasets.yaml', help='model.yaml path')
parser.add_argument('--data', type=str, default='data/mydataset.yaml', help='data.yaml path')
parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')

运行,等待训练完成。

在runs->train->exp下面可以查看结果,为训练及验证结果。

四、测试

1、修改test.py配置参数

打开test.py,修改参数

注意runs/train/exp4/weights/best.pt为训练后生成的,改为自己的地址

 parser = argparse.ArgumentParser(prog='test.py')
    parser.add_argument('--weights', nargs='+', type=str, default='runs/train/exp4/weights/best.pt', help='model.pt path(s)')
    parser.add_argument('--data', type=str, default='data/mydataset.yaml', help='*.data path')

    parser.add_argument('--task', default='test', help='train, val, test, speed or study')
    parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')

其中,weights为刚才训练文件夹里的,data同训练

weights:训练权重的路径。
source:测试图片的路径,我这里把测试图片放在tools/images文件夹下面。
img-size:和训练的图片保持一致。
conf-thres:置信度的最小值。
iou-thres:IoU的值。
max-det:单张图片检测到目标不能超过该值。

 2、结果展示

预测试的图片:

生成的结果:

实验结束

五、问题分析

1、路径问题(已解决)

有些路径必须写全,从/home开始,否则运行不出来。

2、gpu训练(待解决)

配置了cuda等环境,但是仍然显示false,无法使用gpu训练。

替换方案:采用cpu进行训练,缺点是非常慢,需要缩小迭代次数。

仍需解决。

猜你喜欢

转载自blog.csdn.net/zhuanzhuxuexi/article/details/132042186