YOLOV5目标检测---完整训练模型安全帽佩戴情况检测(3)

在这里插入图片描述


前言

这篇文章介绍了如何完整的训练自己的模型,并介绍相关的推理过程和识别过程,使用的数据集是安全帽数据集,只有带安全帽和不带安全帽两类,在学习这篇文章之前可以先学习一下图片标注和数据集划分,传送站如下:

  1. labelimg图片标注工具
  2. YOLO数据集格式转化与划分

1、yolo源码下载以及相关环境配置

1.1源码下载

登录到github网站搜索yolov5,找到星级最高的的仓库,也可以点击该链接跳转:https://github.com/ultralytics/yolov5/tree/v7.0
在这里插入图片描述
在左上角可以选择yolov5版本,这里我建议使用v5.0版本,因为后面我在修改相关参数的时候都是基于5.0版本进行修改的,选择之后直接点击code,会出现下拉框,选择Download zip可以将代码和相关文件打包下载。
在这里插入图片描述

1.2预训练权重下载

打开上面跳转链接之后,将安装包下载完毕可以将网站下拉,找到yolov5已经训练好的权重,后面训练需要使用,我们用的最多的就是yolov5s,我后面训练模型用的也是在yolov5s.pt的基础上进行训练的。通过下面这张表格可以看见他们训练图片的大小、精度、速度、以及所占内存大小,如果需要高精度的化可以使用yolov5x。
在这里插入图片描述
下图是不同权重的在GPU上面的速度对比效果图:
在这里插入图片描述

1.3各级目录以及文件介绍

将下载好的zip压缩包解压之后用pycharm打开,yolov5项目结构如下图:
在这里插入图片描述
项目文件夹以及代码文件简单介绍:(后续出详细介绍,这里只需要知道每个文件是做什么的)


1.data文件夹
主要是存放一些超参数的配置文件(yaml文件)是用来配置训练集和测试集还有验证集的路径的,其中还包括目标检测的种类数和种类的名称;还有一些官方提供测试的图片。如果是训练自己的数据集的话,那么就需要修改其中的yaml文件,yaml文件中记录的是训练所用到数据集的路径地址,以及类别名称和类别数量,data文件目录如下图。(训练的话该文件夹内容需要修改)在这里插入图片描述
我们训练自己数据集的时候需要修改yaml文件中的内容,我这里是将coco128.yaml复制之后进行修改,修改内容如下:在这里插入图片描述

  • train:训练数据集相对路径
  • val:测试数据集相对路径
  • nc:训练的种类数据
  • names:训练类别名称
    注意:千万不要在yaml中使用中文注释,不然会报错!!!

2.models文件夹
这个文件夹面主要是一些网络构建的配置文件和函数,其中包含了该项目网络的不同的版本,分别以l,m,s,x结尾,我们在使用不同权重训练模型的时候,需要选择对应的yaml文件,他们的检测测度分别都是从快到慢,但是精确度分别是从低到高文件目录如下:在这里插入图片描述
因为我在训练的时候加载的是yolov5s.yaml,所以这里我们需要修改该文件中的内容(建议大家复制该文件之后重新命名),我这里命名为hat-yolov5s.yaml,这个文件需要修改部分内容,因为我们只有2个类别,所以将nc设置为2(原文件应该是nc=80).
在这里插入图片描述
在这里插入图片描述


3.runs文件夹
这个文件我们在下载源文件的时候是不存在的,当我们运行detect.py或者train.py文件的时候就会生成该文件夹,该文件夹储存的是训练过程数据和推理结果,目录结构如下:
在这里插入图片描述
train文件夹保存的是训练结果,包括训练好的权重、训练参数、损失函数曲线等内容。
detect文件夹保存的是识别好的数据文件,包括图片、视频。


4.utils文件夹
这个文件夹存放的是训练过程中所用到的工具函数,像损失函数loss,metrics函数,plots函数等等,训练过程中不需要修改此部分内容。
在这里插入图片描述


5.detect.py
推理文件,使用该代码可以对图片以及视频进行推理检测,同时也可以调用摄像头进行检测。在训练过程中一般只需要修改前面两行内容,主要代码结构如下:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default='yolov5s.pt', help='model.pt path(s)')
    # 需要加载权重文件地址,这里用我们已经训练好的权重,为了便于理解这里我填的是yolov5官网已经训练好的权重
    parser.add_argument('--source', type=str, default='data/images', help='source')  # file/folder, 0 for webcam
    # 测试数据文件(图片或视频)的保存路径 默认data/images
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    # inference size (height, width) 输入图片的大小 默认640(pixels)
    parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
    # object置信度阈值 默认0.25
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    #  做nms的iou阈值 默认0.45
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    # 设置代码执行的设备,也就是选择用显卡进行推理或者cpu进行推理,可以选择第几块显卡或者cpu
    parser.add_argument('--view-img', action='store_true', help='display results',default=True)
    # 是否展示预测之后的图片或视频(如何设置为True的话,可以看到推理过程) 默认False直接看到推理之后的结果
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    # 是否将预测的框坐标以txt文件格式保存 默认False
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    # 是否保存预测每个目标的置信度到预测tx文件中 默认False
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    # 是否不要保存预测后的图片  默认False 就是默认要保存预测后的图片
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    # 在nms中是否是只保留某些特定的类 默认是None 就是所有类只要满足条件都可以保留
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    # 进行nms是否也除去不同类别之间的框 默认False
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    # 预测是否也要采用数据增强 TTA 默认False
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    # 当前测试结果放在哪个主文件夹下 默认runs/detect
    parser.add_argument('--name', default='exp', help='save results to project/name')
    # 当前测试结果放在run/detect下的文件名  默认是exp  =>  run/detect/exp
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    # 是否存在当前文件 默认False 一般是 no exist-ok 连用  所以一般都要重新创建文件夹
    opt = parser.parse_args()
    print(opt)
    check_requirements(exclude=('pycocotools', 'thop'))

6.train.py
用来训练自己的数据集的函数。功能结构如下:

  • 读取配置文件:train.py通过argparse库读取配置文件中的各种训练参数,例如batch_size、epoch、learning_rate等等,以及模型配置文件的路径、权重文件的路径等。
  • 构建模型结构:train.py中定义了create_model函数,用于根据模型配置文件中的参数构建模型结构。在构建模型结构时,train.py会加载之前训练过的模型权重,如果没有预训练的权重文件,则随机初始化权重。
  • 数据加载和预处理:train.py中定义了create_dataloader函数,用于加载训练数据和测试数据,并对其进行预处理。其中,预处理过程包括图像尺寸调整、图像增强、标签转换等操作。
  • 训练和验证过程:train.py中定义了train函数,用于进行模型的训练和验证过程。训练过程中,train.py会对训练数据进行多次迭代,每个迭代周期称为一个epoch。在每个epoch结束时,train.py会对模型在验证集上的表现进行评估,并输出相应的指标,例如平均精度(mAP)、召回率(recall)等等。
  • 模型保存和日志输出:train.py会定期保存训练过程中得到的最佳模型权重,并将训练和验证过程中的各种指标输出到日志文件中。在训练结束后,train.py还会输出最终的测试指标,并保存最终的模型权重文件。

主要参数代码如下:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', type=str, default='runs/train/exp/weights/best.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='yolov5s.pt', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/hat.yaml', help='data.yaml path')
    parser.add_argument('--hyp', type=str, default='data/hyp.scratch.yaml', help='hyperparameters path')
    parser.add_argument('--epochs', type=int, default=100)
    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] image sizes')
    parser.add_argument('--rect', action='store_true', help='rectangular training')
    parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')
    parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')
    parser.add_argument('--notest', action='store_true', help='only test final epoch')
    parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')
    parser.add_argument('--evolve', action='store_true', help='evolve hyperparameters')
    parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')
    parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')
    parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')
    parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')
    parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')
    parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')
    parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')
    parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')
    parser.add_argument('--project', default='runs/train', help='save to project/name')
    parser.add_argument('--entity', default=None, help='W&B entity')
    parser.add_argument('--name', default='exp', help='save to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--quad', action='store_true', help='quad dataloader')
    parser.add_argument('--linear-lr', action='store_true', help='linear LR')
    parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')
    parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')
    parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')
    parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')
    parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')
    opt = parser.parse_args()

参数解读:
这行代码定义了一个 argparse.ArgumentParser 对象,用于解析命令行参数。argparse 是 Python 自带的一个命令行解析库,可以方便地将命令行参数解析成 Python 对象,并提供帮助信息等功能。
argparse解析了以下参数:

  • weights:指定预训练模型的权重文件路径,例如 yolov5s.pt(这里我使用的是yolov5s.pt权重)。
  • cfg:指定模型的配置文件路径,例如 models/yolov5s.yaml。
  • data:指定训练数据集路径,例如 data coco.yaml(这里用的是我自己的数据路径data/hat.yaml)。
  • epochs:指定训练的 epoch 数,例如 epochs 300。
  • batch-size:指定每个 batch 的大小,例如 batch-size 16,表示一次性往显卡里面放16张图片进行训练。
  • img-size:指定输入图片的大小,例如 img-size 640 表示输入图片的大小为 640x640。
  • rect :指定在训练过程中是否进行图像矫正,例如 rect 表示进行图像矫正。
  • resume:指定是否从之前的训练中断处继续训练,例如 resume 表示从中断处继续训练。
  • nosave 不保存模型 默认False(保存)。
  • noautoanchor 不自动调整anchor, 默认False, 自动调整anchor。
  • evolve:指定是否进行超参数优化,例如 evolve 表示进行超参数优化。
  • name:指定保存模型的名称,例如 name my_model 表示保存模型为 my_model.pt。
  • workers:指定用于加载数据的进程数,例如 workers 8 表示使用 8 个进程来加载数据,但是一般电脑都无法使用默认的8个进程进行训练,这里需要改成4个

1.4安装项目依赖包

如果想要完整的运行代码,我们需要安装yolov5所需要的依赖包,我们从github上面现在下来的压缩包里面会有一个requirements.txt文件,我们打开pycharm最底下的Terminal输入下面命令:

pip install -r requirements.txt

在这里插入图片描述
安心等待安装包下载完成,如果报错的请自行百度报错原因!!!

2、准备数据集

2.1图片打标签

我们需要对已经下载好的数据集进行打标签,来标注安全帽和人脸的位置,我们有两种打标签工具可以进行选择,第一种是在线打标签工具:https://www.makesense.ai/
第二种是安装本地打标签工具,有需要的可以观看这篇博客:YOLOV5目标检测—labelimg图片标注工具(1)

2.2数据预处理

打好标签的数据集我们需要进行数据集与验证集的划分,我一般是按照8:2进行划分,或者5:1进行划分,我们可以手动进行数据集的划分,也可以使用代码进行随机划分,数据集预处理可以参考这篇博客:YOLOV5目标检测—数据集格式转化与划分(2)
划分好的文件夹格式如下:
在这里插入图片描述
----训练数据集文件夹
-----图片
-------训练集图片
-------验证集图片
-----标签
-------训练集标签
-------验证集标签

3、相关配置修改(重点!!!)

3.1权重的选择

前面我们已经下载好训练需要的权重—yolov5s.pt,将这个权重拷贝到我们的项目文件夹里面,找到train.py代码,将权重路径复制到default里面(这里我们也可以不放权重,default也可以默认为空,但是我们从头开始训练的话可能需要训练我几千轮,所以我在yolov5s的基础上训练300轮就能达到一个不错的精度

parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')

3.2数据集配置文件修改

找到data文件夹,复制coco.yaml文件重新命名为hat.yaml,hat.yaml修改内容如下:
在这里插入图片描述

3.3模型配置文件修改

因为我们是在yolov5s.pt权重的基础上进行训练的,我们需要修改models/yolov5s.yaml中的内容,这里只需要将80类改成2类:
在这里插入图片描述

3.4训练文件train.py相关参数修改

我们只需要将修改后的数据集配置文件和模型配置文件路径替换原来默认路径,修改内容如下:

    parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')
    parser.add_argument('--cfg', type=str, default='models/hat.yaml', help='model.yaml path')
    parser.add_argument('--data', type=str, default='data/hat.yaml', help='data.yaml path')

修改后右键运行就能进行训练了:
在这里插入图片描述
训练之后的权重保存在runs/train/exp/weights中,目录结构如下:
在这里插入图片描述
weights里面会有一个best.pt和一个last.pt,一个是训练最好结果的权重,一个是最后一轮训练得到的权重,我们使用best.pt。

4、训练过程可视化

4.1tensboard使用方法

训练过程中我们想要查看损失值的情况,以及精度的变化,我们可以使用pytorch中自带的可视化工具tensboard,在pycharm下方的Terminal中输入如下命令:

tensorboard --logdir==runs/train

在这里插入图片描述
点击这个网址就能查看我们训练过程相关参数变化:
在这里插入图片描述

5.目标检测推理过程

5.1使用训练权重识别图片

训练之后我们需要将我们训练好的权重路径复制到detect.py代码中的–weights中,同时–source中放我们待测图片路径如下:

parser.add_argument('--weights', nargs='+', type=str, default='weights/best.pt', help='model.pt path(s)')
parser.add_argument('--source', type=str, default='data/hat', help='source')
#这里的default放的是我们待识别图片文件夹路径

右键运行代码就能得到测试结果,检测到的结果保存,在runs/detect/exp
在这里插入图片描述
测试结果如下(这里我用到了图形化界面,后期会整理如何使用pyqt开发图形化界面):
在这里插入图片描述

5.2识别视频

识别视频只需要将–source中的图片路径改成视频路径就ok了,修改如下:

parser.add_argument('--source', type=str, default='1.mp4', help='source')

识别效果:
在这里插入图片描述

5.3调用摄像头识别

调用摄像头只需要将default修改为0,修改如下:

parser.add_argument('--source', type=str, default=0, help='source')

识别效果如下:
在这里插入图片描述

总结—可能报错情况

1.缺少SPPF模块
2.调用摄像头报错
3.yolov5训练时参数workers与batch-size的常见问题
4.训练过程中找不到图片问题

  • 5
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕溪同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值