文章目录

  • 前言
  • 一、YOLOv7 项目下载实现
  • 1.1 YOLOv7 项目下载
  • 1.2 添加 Python interpreter
  • 1.3 直接运行 detect.py
  • 1.4 检测摄像头
  • 1.5 连接手机摄像头
  • 二、自制数据集训练模型
  • 2.1 运行 train.py
  • 2.2 数据集图片和标签
  • 2.3 yaml 文件修改
  • 2.4 修改并运行 train.py
  • 三、v5、v7、v8的训练结果 result
  • 3.1 v5 与 v8 的 result.csv 含义相同
  • 3.2 YOLOv7 的 result.txt
  • 3.3 map、loss绘图
  • 3.4 utils/metrics.py
  • 3.4.1 PR_curve.csv
  • 3.4.2 F1_curve.csv
  • 3.5 PR、F1 绘图
  • 总结



前言

YOLOv7 实现目标检测,环境配置参考 YOLO v5 实现目标检测


一、YOLOv7 项目下载实现

1.1 YOLOv7 项目下载

  • 下载源码,并保存至本地,将本地的 yolov7 项目解压至 Pycharm 特定的 Project 项目中并导入,进入 File 下的 Settings 进行 python 解释器设置

1.2 添加 Python interpreter

  • 选择 Settings 中的 Project yolov7-main 下的 Python interpreter,

1.3 直接运行 detect.py

  • 直接运行 detect.py,会出现以下报错:
  • 解决方法:
  • 下载权重文件放在主目录下,即 yolov7-main 文件夹下,这里选的是 yolov7.pt,重新运行,运行结果保存到 runs\detect\exp2 中;

1.4 检测摄像头

  • 开启摄像头检测,将代码改成 default=‘0’,便可开启自带摄像头
  • 将代码改成 default=‘1’,便可开启 USB 摄像头,进行动态的实时检测

1.5 连接手机摄像头

需确保手机和电脑在同一局域网下(即连接的是同一个 WIFI)

  • 下载 IP 摄像头 Lite
  • python 动目标检测 python 目标检测 训练_目标检测

  • 点击打开 IP 摄像头 Lite
  • python 动目标检测 python 目标检测 训练_python 动目标检测_02

  • 点击打开 IP 摄像头服务器
# 修改 detect.py 代码,运行即可
parser.add_argument('--source', type=str, default='http://admin:admin@172.16.20.120:8081', help='file/dir/URL/glob/screen/0(webcam)')

python 动目标检测 python 目标检测 训练_目标检测_03

  • 报错原因:上述修改未加上用户名和密码 admin:admin@

二、自制数据集训练模型

2.1 运行 train.py

python 动目标检测 python 目标检测 训练_YOLO_04


python 动目标检测 python 目标检测 训练_人工智能_05

2.2 数据集图片和标签

  • 新建文件夹 train_data,在该文件夹下新建 images、labels 两个文件夹
  • 分别在这里两个文件夹下新建 train 文件夹
  • 将采集的图片(采用手机拍照或者走网上搜索你所需要的数据集)放入 train_data/images/train 文件夹,此时 train_dat/labels/train 文件夹是空的

2.3 yaml 文件修改

  • 新建 cat.yaml ,并对其内容进行修改;

2.4 修改并运行 train.py

python 动目标检测 python 目标检测 训练_YOLO_06


python 动目标检测 python 目标检测 训练_目标检测_07

with open(opt.data, encoding='utf-8') as f:

python 动目标检测 python 目标检测 训练_目标检测_08


python 动目标检测 python 目标检测 训练_人工智能_09

三、v5、v7、v8的训练结果 result

  • v5、v8 都是 csv 格式的,v7 是 txt 格式的

3.1 v5 与 v8 的 result.csv 含义相同

  • YOLOv5
  • YOLOv8

3.2 YOLOv7 的 result.txt

0/2       3.3G       0.05079          0.01787           0.01426         0.08291               16                 640               0.02997    0.1136    0.01745     0.003438          0.07951      0.02253        0.01505
训练轮数   GPU消耗     train/box_loss   train/obj_loss    train/cls_loss  train/total_loss     本轮中数据中目标数量   输入图片大小         P          R         mAP@.5     mAP@.5:.95        val/Box_loss  val/obj_loss   val/cls_loss

python 动目标检测 python 目标检测 训练_python 动目标检测_10


python 动目标检测 python 目标检测 训练_YOLO_11

3.3 map、loss绘图

python 动目标检测 python 目标检测 训练_人工智能_12

  • plt.savefig(“mAP50.png”, dpi=600) # dpi 可设为300/600/900,表示存为更高清的矢量图
  • data = pd.read_csv(res_path, usecols=[6]).values.ravel() 表示读取 csv 文件后,只取下标为6的一列的值 values,并将值 ravel() 展平为一维数组(如果想要绘制 result.csv/result.txt 中的其他值,直接改为对应的下标即可。例如想要绘制 train/box_loss,则绘制 map50 中的6改为1,10改为2)
  • plt.plot(x, data, label=modelname, linewidth=‘1’) # 线条粗细设为1
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

if __name__ == '__main__':
    # 列出待获取数据内容的文件位置
    # v5、v8都是csv格式的,v7是txt格式的
    result_dict = {
        'YOLOv5m': r'D:\yolov7-main\results.csv',
        'YOLOv7': r'D:\yolov7-main\results1.csv',
        'YOLOv7-tiny': r'D:\yolov7-main\results2.csv',
        'YOLOv7s': r'D:\yolov7-main\runs\train\exp2\results.txt'
    }

    # 绘制map50
    for modelname in result_dict:
        res_path = result_dict[modelname]
        ext = res_path.split('.')[-1]
        if ext == 'csv':
            data = pd.read_csv(res_path, usecols=[6]).values.ravel()    # 6是指map50的下标(每行从0开始向右数)
        else:   # 文件后缀是txt
            with open(res_path, 'r') as f:
                datalist = f.readlines()
                data = []
                for d in datalist:
                    data.append(float(d.strip().split()[10]))   # 10是指map50的下标(每行从0开始向右数)
                data = np.array(data)
        x = range(len(data))
        plt.plot(x, data, label=modelname, linewidth='1')   # 线条粗细设为1

    # 添加x轴和y轴标签
    plt.xlabel('Epochs')
    plt.ylabel('mAP@0.5')
    plt.legend()
    plt.grid()
    # 显示图像
    plt.savefig("mAP50.png", dpi=600)   # dpi可设为300/600/900,表示存为更高清的矢量图
    plt.show()


    # 绘制map50-95
    for modelname in result_dict:
        res_path = result_dict[modelname]
        ext = res_path.split('.')[-1]
        if ext == 'csv':
            data = pd.read_csv(res_path, usecols=[7]).values.ravel()    # 7是指map50-95的下标(每行从0开始向右数)
        else:
            with open(res_path, 'r') as f:
                datalist = f.readlines()
                data = []
                for d in datalist:
                    data.append(float(d.strip().split()[11]))   # 11是指map50-95的下标(每行从0开始向右数)
                data = np.array(data)
        x = range(len(data))
        plt.plot(x, data, label=modelname, linewidth='1')

    # 添加x轴和y轴标签
    plt.xlabel('Epochs')
    plt.ylabel('mAP@0.5:0.95')
    plt.legend()
    plt.grid()
    # 显示图像
    plt.savefig("mAP50-95.png", dpi=600)
    plt.show()

    # 绘制训练的总loss
    for modelname in result_dict:
        res_path = result_dict[modelname]
        ext = res_path.split('.')[-1]
        if ext == 'csv':
            box_loss = pd.read_csv(res_path, usecols=[1]).values.ravel()
            obj_loss = pd.read_csv(res_path, usecols=[2]).values.ravel()
            cls_loss = pd.read_csv(res_path, usecols=[3]).values.ravel()
            data = np.round(box_loss + obj_loss + cls_loss, 5)    # 3个loss相加并且保留小数点后5位(与v7一致)

        else:
            with open(res_path, 'r') as f:
                datalist = f.readlines()
                data = []
                for d in datalist:
                    data.append(float(d.strip().split()[5]))
                data = np.array(data)
        x = range(len(data))
        plt.plot(x, data, label=modelname, linewidth='1')

    # 添加x轴和y轴标签
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.legend()
    plt.grid()
    # 显示图像
    plt.savefig("loss.png", dpi=600)
    plt.show()

3.4 utils/metrics.py

3.4.1 PR_curve.csv

python 动目标检测 python 目标检测 训练_python 动目标检测_13

def plot_pr_curve(px, py, ap, save_dir='pr_curve.png', names=()):
    # Precision-recall curve
    fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)
    py = np.stack(py, axis=1)

    # lwd edit: 将结果保存在csv中
    pr_dict = dict()  # lwd edit
    pr_dict['px'] = px.tolist()  # lwd edit

    if 0 < len(names) < 21:  # display per-class legend if < 21 classes
        for i, y in enumerate(py.T):
            ax.plot(px, y, linewidth=1, label=f'{names[i]} {ap[i, 0]:.3f}')  # plot(recall, precision)
            pr_dict[names[i]] = y.tolist()  # lwd edit
    else:
        ax.plot(px, py, linewidth=1, color='grey')  # plot(recall, precision)

    # ------------------- lwd edit ---------------------- #
    pr_dict['all'] = py.mean(1).tolist()
    import pandas as pd
    dataformat = pd.DataFrame(pr_dict)
    save_csvpath = save_dir.cwd() / (str(save_dir).replace('.png', '.csv'))  # 定义csv文件的保存位置
    dataformat.to_csv(save_csvpath, sep=',')
    # ---------------------------------------------------- #
    ax.plot(px, py.mean(1), linewidth=3, color='blue', label='all classes %.3f mAP@0.5' % ap[:, 0].mean())
    ax.set_xlabel('Recall')
    ax.set_ylabel('Precision')
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left")
    fig.savefig(Path(save_dir), dpi=250)

python 动目标检测 python 目标检测 训练_YOLO_14

3.4.2 F1_curve.csv

python 动目标检测 python 目标检测 训练_目标检测_15

def plot_mc_curve(px, py, save_dir='mc_curve.png', names=(), xlabel='Confidence', ylabel='Metric'):
    # Metric-confidence curve
    fig, ax = plt.subplots(1, 1, figsize=(9, 6), tight_layout=True)
    # -----------------lwd edit: 将结果保存在csv中--------------- #
    flag = False # 判断是不是绘制F1_curve曲线
    if str(save_dir).endswith('F1_curve.png'):
        flag = True
        pr_dict = dict()  # lwd edit
        pr_dict['px'] = px.tolist()  # lwd edit
    # --------------------------------------------------------- #
    if 0 < len(names) < 21:  # display per-class legend if < 21 classes
        for i, y in enumerate(py):
            ax.plot(px, y, linewidth=1, label=f'{names[i]}')  # plot(confidence, metric)
            if flag:
                pr_dict[names[i]] = y.tolist()  # lwd edit
    else:
        ax.plot(px, py.T, linewidth=1, color='grey')  # plot(confidence, metric)
    y = py.mean(0)
    ax.plot(px, y, linewidth=3, color='blue', label=f'all classes {y.max():.2f} at {px[y.argmax()]:.3f}')
    # ------------------- lwd edit ---------------------- #
    if flag:
        pr_dict['all'] = y.tolist()
        import pandas as pd
        dataformat = pd.DataFrame(pr_dict)
        save_csvpath = save_dir.cwd() / (str(save_dir).replace('.png', '.csv'))  # 定义csv文件的保存位置
        dataformat.to_csv(save_csvpath, sep=',')
    # ---------------------------------------------------- #
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    plt.legend(bbox_to_anchor=(1.04, 1), loc="upper left")
    fig.savefig(Path(save_dir), dpi=250)

python 动目标检测 python 目标检测 训练_python 动目标检测_16

3.5 PR、F1 绘图

python 动目标检测 python 目标检测 训练_v8_17

import matplotlib.pyplot as plt
import pandas as pd

# 绘制PR
def plot_PR():
    pr_csv_dict = {
        'YOLOv7': r'D:\yolov7-main\runs\train\exp4\PR_curve.csv',
        'YOLOv71': r'D:\yolov7-main\runs\train\exp2\PR_curve.csv',
        'YOLOv72': r'D:\yolov7-main\runs\train\exp4\PR_curve.csv',
        'YOLOv73': r'D:\yolov7-main\runs\train\exp2\PR_curve.csv'
    }

    # 绘制pr
    fig, ax = plt.subplots(1, 1, figsize=(6, 4), tight_layout=True)

    for modelname in pr_csv_dict:
        res_path = pr_csv_dict[modelname]
        x = pd.read_csv(res_path, usecols=[1]).values.ravel()
        data = pd.read_csv(res_path, usecols=[2]).values.ravel()
        ax.plot(x, data, label=modelname, linewidth='2')

    # 添加x轴和y轴标签
    ax.set_xlabel('Recall')
    ax.set_ylabel('Precision')
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    plt.legend(bbox_to_anchor=(1.04, 1), loc='upper left')
    plt.grid()  # 显示网格线
    # 显示图像
    fig.savefig("pr.png", dpi=250)
    plt.show()

# 绘制F1
def plot_F1():
    f1_csv_dict = {
        'YOLOv7': r'D:\yolov7-main\runs\train\exp4\F1_curve.csv',
        'YOLOv71': r'D:\yolov7-main\runs\train\exp2\F1_curve.csv',
        'YOLOv72': r'D:\yolov7-main\runs\train\exp4\F1_curve.csv',
        'YOLOv73': r'D:\yolov7-main\runs\train\exp2\F1_curve.csv'
    }

    fig, ax = plt.subplots(1, 1, figsize=(6, 4), tight_layout=True)

    for modelname in f1_csv_dict:
        res_path = f1_csv_dict[modelname]
        x = pd.read_csv(res_path, usecols=[1]).values.ravel()
        data = pd.read_csv(res_path, usecols=[2]).values.ravel()
        ax.plot(x, data, label=modelname, linewidth='2')

    # 添加x轴和y轴标签
    ax.set_xlabel('Confidence')
    ax.set_ylabel('F1')
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    plt.legend(bbox_to_anchor=(1.04, 1), loc='upper left')
    plt.grid()  # 显示网格线
    # 显示图像
    fig.savefig("F1.png", dpi=250)
    plt.show()

if __name__ == '__main__':
    plot_PR()   # 绘制PR
    plot_F1()   # 绘制F1

总结

以上就是 YOLOv7 的环境配置、运行与训练过程及其中可能出现的问题与解决办法。