[yolo实战]YOLOv5模型训练:口罩检测模型训练与部署全流程

前言

口罩检测是计算机视觉在公共卫生领域的典型应用,本文将详细介绍如何基于 YOLOv5 框架搭建一个口罩检测模型,实现 "戴口罩" 和 "不戴口罩" 两类目标的实时检测。全程采用 GPU 加速训练,针对口罩这类小目标优化模型参数,适合入门者学习参考。

【如果你对人工智能的学习有兴趣可以看看我的其他博客,对新手很友好!!!】

【本猿定期无偿分享学习成果,欢迎关注一起学习!!!】

 【实现效果】

 一、环境搭建

1.1 创建虚拟环境 

使用 Anaconda 创建专属虚拟环境,避免依赖冲突:

conda create -n yolov5 python=3.9 -y

 创建完成后激活环境:

conda activate yolov5

1.2 安装 GPU 版本 PyTorch

这个需要对应自己的GPU的cuda进行,详情请看:

纯干货,无废话CUDA、cuDNN、 PyTorch 环境搭建教程_cuda+cudnn+pytorch-CSDN博客

1.3 配置 YOLOv5 依赖

1.克隆 YOLOv5 仓库或下载源码到本地

 推荐直接去github上下载zip,网址如下:
GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite

https://github.com/ultralytics/yolov5

2.打开 PyCharm,选择已创建的yolov5虚拟环境

 

3.编辑requirements.txt文件

删除以下两行(避免覆盖已安装的 GPU 版本 PyTorch): 

注意我们已经手动下载了gpu版本的cuda,所以说就需要去把yolo5依赖中的torch删掉,因为自动下载会下载cpu版本的torch而且会覆盖我们的gpu版本。 

4.在 PyCharm 终端执行依赖安装: 

注意必须要到 requirements.txt路径下

pip install -r requirements.txt

 

二、项目结构与文件准备

在 YOLOv5 文件夹下创建train目录,组织结构如下:

  

其中 VOC.yaml和yolov5m.yaml都是yolov5源码中有的,我们拿来修改一下就能用

data下面的VOC.yaml

以及基于model下面的yolov5m.yaml,因为数据集只有几千张,所以说我使用速度和精度中等的m

三、配置文件修改

 3.1 数据集配置(VOC.yaml)

修改VOC.yaml文件,适配口罩检测数据集: 

 【注意路径需要自己修改】

# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# 口罩检测数据集配置(精确匹配你的路径)
path: D:\yoloStudy\yolov5-master\train\data
train: train\images
val: val\images
test: test\images

# 类别配置(与标注一致)
nc: 3
names: ['with_mask', 'mask_weared_incorrect', 'without_mask']

download: |
  pass  # 无需自动下载

3.2 模型配置(yolov5m.yaml)

基于yolov5m.yaml修改,适配口罩检测场景: 

1.修改类别数量: 

nc: 2  # 将类别数从默认的80改为2

2.优化锚框尺寸
口罩属于小目标,调整锚框为更适合小目标的尺寸: 

anchors:
  - [5, 8, 10, 15, 12, 20]    # 小尺度锚框
  - [18, 25, 25, 35, 30, 45]  # 中尺度锚框
  - [40, 55, 50, 70, 65, 90]  # 大尺度锚框

 3.源码:

# Ultralytics 🚀 AGPL-3.0 License - https://ultralytics.com/license

# Parameters
nc: 3 # number of classes
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple
anchors:
  - [5, 8, 10, 15, 12, 20]  # 更小的锚框,适配口罩
  - [18, 25, 25, 35, 30, 45]
  - [40, 55, 50, 70, 65, 90]

# YOLOv5 v6.0 backbone
backbone:
  # [from, number, module, args]
  [
    [-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
    [-1, 1, Conv, [128, 3, 2]], # 1-P2/4
    [-1, 3, C3, [128]],
    [-1, 1, Conv, [256, 3, 2]], # 3-P3/8
    [-1, 6, C3, [256]],
    [-1, 1, Conv, [512, 3, 2]], # 5-P4/16
    [-1, 9, C3, [512]],
    [-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
    [-1, 3, C3, [1024]],
    [-1, 1, SPPF, [1024, 5]], # 9
  ]

# YOLOv5 v6.0 head
head: [
    [-1, 1, Conv, [512, 1, 1]],
    [-1, 1, nn.Upsample, [None, 2, "nearest"]],
    [[-1, 6], 1, Concat, [1]], # cat backbone P4
    [-1, 3, C3, [512, False]], # 13

    [-1, 1, Conv, [256, 1, 1]],
    [-1, 1, nn.Upsample, [None, 2, "nearest"]],
    [[-1, 4], 1, Concat, [1]], # cat backbone P3
    [-1, 3, C3, [256, False]], # 17 (P3/8-small)

    [-1, 1, Conv, [256, 3, 2]],
    [[-1, 14], 1, Concat, [1]], # cat head P4
    [-1, 3, C3, [512, False]], # 20 (P4/16-medium)

    [-1, 1, Conv, [512, 3, 2]],
    [[-1, 10], 1, Concat, [1]], # cat head P5
    [-1, 3, C3, [1024, False]], # 23 (P5/32-large)

    [[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
  ]

四、模型训练

4.1 训练脚本(my_train.py)

创建my_train.py,配置训练参数:

import subprocess
import sys
import os

def train_yolov5():
    # 配置参数
    data_yaml = "VOC.yaml"        # 数据集配置文件路径
    model_yaml = "yolov5m.yaml"   # 模型配置文件路径
    epochs = 100                  # 训练轮次
    batch = 8                     # 批次大小(根据GPU显存调整)
    imgsz = 480                   # 输入图片尺寸
    device = "0"                  # GPU设备编号(单卡默认为0)
    name = "yolov5m_mask_train"   # 训练结果保存名称
    resume = False                # 是否从断点继续训练

    # 构建训练命令
    command = [
        sys.executable,
        os.path.abspath("../train.py"),  # 指向YOLOv5官方训练脚本
        "--data", data_yaml,
        "--cfg", model_yaml,
        "--epochs", str(epochs),
        "--batch", str(batch),
        "--imgsz", str(imgsz),
        "--device", device,
        "--name", name,
        "--workers", "4",
    ]
    if resume:
        command.append("--resume")

    # 执行训练命令
    try:
        subprocess.run(
            command,
            check=True,
            encoding='utf-8'
        )
    except subprocess.CalledProcessError as e:
        print(f"训练失败,返回码: {e.returncode}")
    except FileNotFoundError:
        print("错误:未找到train.py,请检查路径")
    except Exception as e:
        print(f"未知错误: {str(e)}")

if __name__ == "__main__":
    train_yolov5()

4.2 开始训练

在 PyCharm 中运行my_train.py即可开始训练,训练过程中会实时显示损失值、准确率等指标。训练结果默认保存在runs/train/目录下,包含训练日志、模型权重、评估指标等。

 

五、模型测试与推理 

5.1 项目推理目录结构

yolov5主目录下创建推理相关文件夹,结构如下: 

关键文件说明:

  • test/:放入任意格式(jpg、png 等)的测试图,比如从实际场景抓拍的人像图。

  • best.pt:训练完成后,从 runs/train/[训练任务名]/weights/ 路径下复制 best.pt(最优权重)到此处 。

  • detect.py:自定义脚本,负责调用 YOLOv5 官方检测逻辑,简化结果整理流程。

5.2 推理脚本逐行解析

以下是完整的检测脚本代码,并附带详细注释说明:

import warnings
import os
import glob
import subprocess
import shutil

# 忽略不必要的警告信息,使输出更简洁
warnings.filterwarnings("ignore")

# 路径配置 - 可根据实际情况修改
image_dir = "./test"               # 测试图片文件夹路径
save_dir = "./out"                 # 结果保存路径
detect_script_path = "../detect.py"# YOLOv5官方检测脚本路径(注意相对位置)

# 1. 验证测试图片目录是否存在
if not os.path.isdir(image_dir):
    # 如果目录不存在则抛出错误并终止程序
    raise NotADirectoryError(f"无效目录: {image_dir}")

# 2. 验证YOLOv5官方detect.py是否存在
if not os.path.isfile(detect_script_path):
    raise FileNotFoundError(f"未找到detect.py: {detect_script_path}")
    # 常见问题:此处路径错误,需确认detect.py在YOLOv5源码中的实际位置

# 3. 检查测试目录中是否有图片文件
has_images = False
# 支持常见图片格式:jpg/jpeg/png/bmp
for ext in ['jpg', 'jpeg', 'png', 'bmp']:
    # 查找对应格式的文件
    if glob.glob(f"{image_dir}/*.{ext}"):
        has_images = True
        break

if not has_images:
    raise ValueError(f"未找到图片: {image_dir}")
    # 解决办法:在test目录中放入至少一张图片

# 4. 创建结果保存目录(如果不存在)
os.makedirs(save_dir, exist_ok=True)
# exist_ok=True表示目录存在时不会报错

# 5. 构建调用YOLOv5官方检测脚本的命令
command = [
    "python", detect_script_path,       # 指定Python解释器和官方脚本
    "--source", image_dir,              # 测试图片来源目录
    "--weights", "best.pt",             # 训练好的模型权重
    "--conf", "0.25",                   # 置信度阈值(可调,0.25表示只保留置信度>25%的结果)
    "--project", save_dir,              # 结果保存主目录
    "--name", "",                       # 不创建额外子目录(默认会创建exp文件夹)
    "--exist-ok"                        # 允许目录存在,避免重复运行时报错
]

try:
    # 6. 执行检测命令
    print("开始目标检测...")
    result = subprocess.run(
        command,
        check=True,                     # 命令执行失败时抛出异常
        capture_output=True,            # 捕获命令输出
        text=True                       # 输出为文本格式而非字节
    )

    # 7. 打印检测过程的输出信息
    print("检测完成")
    print(result.stdout)

    # 8. 整理结果目录(解决官方脚本默认创建exp子目录的问题)
    # 查找所有以exp开头的目录
    exp_dirs = glob.glob(os.path.join(save_dir, "exp*"))
    if exp_dirs:
        # 按创建时间排序,取最新的exp目录
        latest_exp_dir = sorted(exp_dirs)[-1]
        # 将exp目录中的所有文件移动到out目录
        for file in glob.glob(os.path.join(latest_exp_dir, "*")):
            shutil.move(file, save_dir)
        # 删除空的exp目录
        os.rmdir(latest_exp_dir)
        print(f"已将结果移动到: {save_dir}")
    else:
        print(f"结果保存至: {save_dir}")

# 异常处理
except subprocess.CalledProcessError as e:
    # 命令执行出错(如参数错误、模型文件损坏等)
    print(f"检测过程出错: {e.stderr}")
except Exception as e:
    # 其他未知错误
    print(f"发生错误: {str(e)}")

5.3 开始测试

运行detect.py即可开始测试,完成后打开out文件夹下查看结果,例:

 

六、数据集获取

在kaggle上下载数据集或自己搜集数据集,下面是链接 

Face Mask Detection

感谢你的观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值