YOLOv5口罩检测实战:从2000张标注数据集到模型训练与评估全流程

📅 2026/8/27 5:45:13
YOLOv5口罩检测实战:从2000张标注数据集到模型训练与评估全流程
简介目标检测是计算机视觉领域的核心任务之一其目标是在图像中定位并分类多个物体。YOLO系列算法凭借端到端的网络结构和优异的实时性成为工程应用中广泛采用的检测框架。YOLOv5作为其中的经典版本在速度和精度上取得了良好平衡尤其适合中小规模数据集上的快速迭代。在公共安全与健康管理场景中口罩检测是典型落地需求能够自动识别行人是否规范佩戴口罩对防控工作具有实际价值。实现一个可用的口罩检测模型关键在于数据质量与训练策略标注规范、类别平衡、数据增强的合理设置直接影响最终效果。本文围绕YOLOv5口罩检测项目提供了一套包含2000张标注数据集、完整训练代码和预训练模型的解决方案从数据准备、环境配置到模型评估与调优系统梳理全流程中的关键细节与常见陷阱帮助初学者快速构建一个指标可靠、可演示的检测系统。 做计算机视觉方向的大作业十个里有八个绕不开口罩检测这个题目。原因很简单任务明确、数据好找、效果可视化强做完往那一放老师一眼就能看出“这是能干活的检测器”而不是那种跑个MNIST分类就交差的凑数项目。但真正动手做的人多了拉开差距的反而不是“能不能跑通”而是数据处理得干不干净、训练参数调得合不合理、最后结果能不能讲清楚。这篇就围绕“YOLOV5口罩检测数据集代码模型 2000张标注好的数据”这条线把从数据到训练再到评估的完整链路拆开讲一遍尤其是那些报告里不写、老师也不会教你的坑我尽量都给你翻出来。这套东西适合谁看很简单正在做YOLOv5口罩检测大作业的学生、想快速复现一个目标检测项目的初学者、以及手里已经有一套数据但训练效果死活提不上去的朋友。不用你从零懂目标检测原理只需要照着思路走基本能把一个能答辩、能演示、指标拿得出手的口罩检测项目落出来。1. 整体设计与思路拆解1.1 为什么是YOLOv5而不是其他模型先回答一个被问烂了的问题选型上来就上YOLOv5到底图什么大作业场景跟工业落地不一样你的核心诉求是“在有限时间内、有限算力下拿到一个稳定可复现的好结果”。YOLOv5恰恰是这个场景里最稳妥的选择。对比一下几个常见路线就明白了方案优点在大作业里的缺点Faster R-CNN精度高、原理经典训练慢、代码量大、部署麻烦SSD速度快、结构简单小目标效果一般环境配置有历史包袱YOLOv5教程全网最多、速度精度均衡、社区生态成熟原理相对复杂但不用自己实现YOLOv8新特性多官方文档和踩坑帖相对没v5多改代码时容易迷路说得直白一点选YOLOv5是因为“你遇到的任何报错都能在搜索引擎里找到解决方案”。这在大作业排期里比什么都重要。我记得之前有个朋友用YOLOv8跑到一半遇到个自定义数据集类别数对不上的问题查了半天最后发现是Ultralytics新版改了yaml格式浪费了整整一个晚上。用YOLOv5就不会有这烦恼社区积累太厚了。还有一个不那么明显的理由YOLOv5的训练和推理脚本分离得很清楚train.py只管训练detect.py只管推理val.py只管评估。这个结构对你写大作业报告非常友好——你可以直接对着源码的调用逻辑去写你的“系统设计”章节而不是自己封装一堆类然后费劲解释。1.2 口罩检测任务的难点到底在哪很多同学以为口罩检测就是一个“二分类的目标检测”把数据集丢进去训练就完事了。实际做一遍你就会发现口罩检测这个任务有几个隐蔽的难点第一是检测目标小。正常的人脸在画面中占比不算大口罩区域更是只占人脸的一部分。如果摄像头角度再远一点口罩可能就只有二三十个像素。YOLOv5对32倍下采样后的小目标响应本来就偏弱所以数据集里必须保证有足够多的“人脸在画面中占比小”的样本否则训练出来的模型在真实场景里会漏检。第二是遮挡和重叠。课堂上、地铁里前排同学的头会挡住后排同学的脸训练数据里如果全是单张干净的正面人脸模型看到密集场景直接就懵了。这个需要数据集本身够“脏”最好包含部分人群聚集、侧脸、低头等复杂样本。第三是类别不平衡。如果数据集里“未佩戴口罩”的样本只有几十张而“佩戴口罩”的样本有一千多张模型会倾向于把所有目标都判成戴口罩因为这样整体的loss最小。处理方式一般有两个一是把未佩戴类别用困难样本挖掘补一补二是调整类别权重。大作业里面最简单粗暴的做法是控制两类样本数量比例不要超过5:1。第四是“口罩佩戴不规范”这个中间态。数据集里经常会有鼻子露出口罩、口罩挂在下巴上这种标签很难定的情况。这类样本标注标准不统一会让模型训练时梯度互相打架。所以标注规范里一定要提前定义清楚只要口罩完全遮住口鼻就算with_mask否则算without_mask。别搞三分类大作业没必要给自己加戏。1.3 2000张标注数据的定位与价值先说结论2000张数据对于大作业来说是一个“足够做出效果”的量级前提是你用对了预训练权重。有人可能觉得数据量越多越好这其实是个误区。在COCO上预训练过的yolov5s.pt已经学到了通用的物体纹理、边缘、形状特征。你训练口罩检测时并不是从零学什么是“脸”只是在预训练特征的基础上做迁移适配。所以哪怕只有2000张图模型也能收敛到不错的效果。我自己实测过一张2080Ti上用2000张口罩数据约5000个标注目标训练100个epochmAP0.5能达到0.85以上完全不虚。但2000张数据的短板也很明显鲁棒性有限。换一个不同光线、不同摄像头视角的场景掉点会比较厉害。所以补齐这块短板靠的是数据增强而不是盲目去网上再多找几百张图。后面我会专门讲增强怎么做才能既涨点又不破坏标签。1.4 高分项目的“模块化”思路现在很多同学的项目其实不是跑不通而是“只跑通了一个脚本”。你要拿高分就得让老师看到你对整个项目有系统性的设计。我自己比较推荐的高分结构是数据处理模块原始图片标签文件划分脚本数据可视化脚本。这部分能展示你“对数据有敬畏心”。模型训练模块YOLOv5的官方train.py已经够用但你要能解释清楚改动了哪些参数、为什么改。模型评估模块除了loss曲线还要会看PR曲线、混淆矩阵、mAP指标。可视化与演示模块用detect.py跑一段视频或者摄像头实时画面这是答辩现场的“杀手级”演示。报告模块把上述过程整理成文档重点写清楚“遇到的问题排查思路最终方案”。把这五个模块里任何一个做得足够细都能在答辩时撑起三分钟以上的深度提问时间。尤其第三个和第四个老师看到你能对着PR曲线讲出“这个凸起说明置信度阈值在0.3左右时误检率开始上升”基本就是高分预定。2. 数据集准备与标注细节2.1 YOLO标注格式通俗解释拿到手的2000张标注数据大概率是YOLO格式的txt文件每张图片对应一个同名txt。里面的每一行代表一个目标框格式是class_id x_center y_center width height注意这四个坐标值全部是归一化的取值范围在0到1之间不是像素坐标。x_center和y_center是框中心点相对于图片宽高的比例width和height是框宽高相对于图片宽高的比例。比如一个标注框的中心在图片正中间宽高占图片的一半那么对应的txt内容就是0 0.5 0.5 0.5 0.5为什么用归一化坐标因为这样不同分辨率的图片共用同一套标签训练时不管输入是640x640还是1280x640标签都不需要跟着改。这个设计是整个YOLO系列能“全尺寸训练”的基石。类别id从0开始计数。如果只有两类那0是with_mask戴了口罩1是without_mask没戴口罩。具体哪个是0哪个是1以你自己写的data.yaml为准但一定要保持一致不然训练出的模型预测结果会和标签对不上检查半天才发现是id写反了。2.2 标准目录结构YOLOv5训练时默认从datasets目录读取数据目录结构长这样datasets/ └── mask/ ├── images/ │ ├── train/ │ │ ├── 0001.jpg │ │ └── ... │ └── val/ │ ├── 1001.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── 0001.txt │ │ └── ... │ └── val/ │ └── 1001.txt └── data.yaml这里有几个容易踩的雷第一图片和标签的名字必须完全一致只差后缀名比如0001.jpg对应0001.txt大小写也要一致。第二训练集里每个txt文件里至少得有一行有效标签如果某个txt是空的训练时日志会显示“WARNING: corrupt或不完整”虽然不报错但会影响数据加载率。第三不要用中文路径。YOLOv5的OpenCV和matplotlib对中文路径支持很差轻则画不出图重则直接崩溃。老师给的或者网上下载的数据集有时候图片在images目录标签却混在一个压缩包里吐出来就散落到各层目录。别偷懒一定要统一归到上面这个结构里来否则后面所有环节都会跟着乱。2.3 数据划分怎么做官方推荐的比例是训练集:验证集 9:1或者8:2。对大作业来说2000张图训练集1600张、验证集400张比较合适足够让mAP曲线平滑且不抖动。如果验证集太小比如只剩50张指标波动会非常大同一个模型这次跑0.88下次跑0.81答辩时不好看。划分的时候要注意不要直接random.shuffle之后按前90%后10%切因为连续拍摄的图片往往内容高度相似如果同一场景的截图被同时分进训练集和验证集就会出现轻微的数据泄露导致验证指标虚高。这不是大问题但是答辩时如果老师刨根问题容易被问住。稳妥的做法是先把所有图片按场景分组再按组划分。分享一个我写给自己用的简易划分脚本逻辑很清晰import os import shutil import random random.seed(42) img_train_src path/to/all_images img_train_dst datasets/mask/images/train img_val_dst datasets/mask/images/val label_train_src path/to/all_labels label_train_dst datasets/mask/labels/train label_val_dst datasets/mask/labels/val os.makedirs(img_train_dst, exist_okTrue) os.makedirs(img_val_dst, exist_okTrue) os.makedirs(label_train_dst, exist_okTrue) os.makedirs(label_val_dst, exist_okTrue) files os.listdir(img_train_src) random.shuffle(files) val_count int(len(files) * 0.2) for idx, f in enumerate(files): img_src os.path.join(img_train_src, f) label_src os.path.join(label_train_src, f.replace(.jpg, .txt)) if idx val_count: shutil.copy(img_src, img_val_dst) shutil.copy(label_src, label_val_dst) else: shutil.copy(img_src, img_train_dst) shutil.copy(label_src, label_train_dst) print(ftrain: {len(files) - val_count}, val: {val_count})这个脚本虽然简陋但胜在直观。实际用的时候记得把path/to改成你自己的路径。2.4 标注数据质量自查三板斧拿到“2000张标注好的数据”第一件事不是开训而是自查。我总结了三板斧每一步都很便宜但能省下后面大量排查时间。第一斧人工看图。用OpenCV写个脚本把每张图片和它的标注框画出来输出成一张大图或者视频人眼扫一遍重点看有没有框的位置明显不对、框类型明显标反。这一步不需要全查抽10%就够发现大部分系统性问题。第二斧统计标签分布。统计每个类别的目标数量、每张图的目标数量、bbox宽高的分布写一段简单的Python就行import os from collections import Counter label_dir datasets/mask/labels/train cls_counter Counter() box_width [] for f in os.listdir(label_dir): with open(os.path.join(label_dir, f), r) as fp: for line in fp: parts line.strip().split() cls_counter[parts[0]] 1 box_width.append(float(parts[3])) print(cls_counter) print(f平均框宽: {sum(box_width) / len(box_width):.4f})统计完你就能回答“两类数量平不平衡”“目标是大脸还是小脸”这两个问题。第三斧检查标签边界。YOLO格式要求归一化坐标不会超过[0,1]但手工标注经常有超出边界的情况——比如被裁切的半张人脸标注框中心点还在图内但框宽延伸到图外导致width超过1。这种情况虽然训练时YOLOv5会自动过滤但大量出现会降低效率最好提前用fix标签脚本统一裁剪。提示标签格式错误是大作业里最隐蔽的坑。很多时候loss不降、mAP为0第一嫌疑就是标签文件里混了CRLF换行符、多余空格或者NaN。2.5 数据增强的使用边界YOLOv5内置了非常强的数据增强Mosaic马赛克拼接、MixUp、HSV色域变换、随机翻转、随机缩放等。对大作业来说跑训练不用自己手动增强YOLOv5在训练时就自动做了。但你需要知道每个增强什么时候会帮倒忙水平翻转对口罩检测非常友好因为人脸是对称的几乎每轮都会翻。垂直翻转不建议开因为现实中很少出现倒着的人脸开了容易制造无效样本。Mosaic增强能显著提升小目标检测能力但如果你只有2000张图建议把mosaic的概率从默认的1.0降到0.5左右不然训练数据高度“马赛克化”模型学到的上下文会很不自然。HSV增强里的色相变化要小一点口罩颜色可以变但人脸肤色变化太夸张会让模型学到错误的颜色关联。这里真正想提醒的是不要额外叠加第二种数据增强库。我见过有人用imgaug先离线做一遍增强把数据集从2000张扩到8000张再喂给YOLOv5。结果是训练慢了三倍mAP反而掉了两个点。因为YOLOv5内部的增强已经覆盖了大部分有效变换离线增强很容易产生大量高度相似的图片相当于变相降低了数据多样性。3. 环境搭建与训练实操3.1 YOLOv5安装步骤与避坑YOLOv5的安装流程在GitHub仓库里有官方文档但很多人第一次搭的时候还是会在几个地方卡住尤其是pip版本和依赖冲突。这里给一套我自己屡试不爽的安装步骤# 1. 克隆官方仓库不需要git clone太深直接默认即可 git clone https://github.com/ultralytics/yolov5 cd yolov5 # 2. 创建独立虚拟环境强烈建议别直接装到base环境 python -m venv venv source venv/bin/activate # 3. 安装依赖这里会装CPU版torch之后需要手动换GPU版 pip install -r requirements.txt # 4. 卸载自动装的CPU torch换装CUDA版以CUDA 11.8为例 pip uninstall -y torch torchvision torchaudio pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 5. 验证环境 python -c import torch; print(torch.cuda.is_available())一个常见的问题是requirements.txt里可能把你的numpy拉到一个新版本和系统里其他包冲突。如果你在导入yolov5时遇到AttributeError: module numpy has no attribute int这类报错基本就是numpy版本太新了YOLOv5老版本代码不兼容。处理方式是回退numpypip install numpy1.26.4YOLOv5的官方仓库更新很频繁2023年底之后签入的新版本对代码做了大量重构。如果你用最新的仓库遇到奇怪的报错可以直接切回一个历史稳定tag比如v6.0、v7.0。大作业场景下稳定大于一切建议用固定tag训练。注意如果你电脑只有CPU没有NVIDIA显卡就别硬跑YOLOv5训练了CPU训练2000张图会慢到怀疑人生。可以考虑Google Colab免费GPU或者用云GPU按小时租一台训练完下载权重成本很低。3.2 编写data.yaml配置文件数据准备好之后需要在YOLOv5仓库目录下写一个mask.yaml内容格式如下# 训练集和验证集图片路径 train: ../datasets/mask/images/train val: ../datasets/mask/images/val # 类别数 nc: 2 # 类别名称注意顺序必须和txt里class_id一一对应 names: [with_mask, without_mask]这里有个细节train和val的路径是相对于yolov5仓库根目录的。如果你把数据集放在yolov5同级目录下的datasets里那这个../datasets/mask/images/train就是对的。如果你放在别的路径一定改成绝对路径否则训练时会在加载数据阶段报AssertionError: train: No images in ...排查起来很痛苦。命名方面如果你的数据集原本是单类只有口罩或者有“mask_weared_incorrect”这类第三类这里就按实际类别数改。总之yaml和txt里的id必须是同一套编码表。3.3 训练命令与参数选择一切就绪后的训练命令长这样python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data mask.yaml \ --weights yolov5s.pt \ --project runs/train \ --name mask_exp我一个个参数讲一下考虑的维度--img 640这是训练时推理的输入分辨率。YOLOv5内部会把图片resize到640x640。分辨率越高小目标检测越准但显存占用和训练时间也越高。大作业用640是基准线显存充足可以试1280但没必要。--batch 16批大小。取决于显卡显存。2080Ti 11G跑batch 16没问题4G显存就降到8或4。batch不是越大越好太大的batch在训练后期容易陷入尖锐极小值泛化能力变差。--epochs 100对大作业来说100个epoch足够了一般到50-70个epoch就已经收敛。--weights yolov5s.pt预训练权重自动从GitHub Release下载。如果之前下载过放到weights目录里代码会自动复用不用重复下载。--project和--name控制结果输出目录建议显式指定不然后面你会面对一堆exp/exp2/exp3不知道哪个是最新。训练开始后终端会输出每一轮epoch的指标类似Epoch GPU_mem box_loss obj_loss cls_loss Instances Size 90/100 7.28G 0.02123 0.03211 0.001245 156 640GPU_mem是单卡显存占用box_loss是定位损失obj_loss是目标置信度损失cls_loss是分类损失。观察这几个值的趋势比看总loss还是实在训练正常时三者都应该在波动中缓慢下降。如果其中某个指标训练到后期突然升高往往说明学习率过大或数据有误。训练完结果会保存在runs/train/mask_exp下面。weights/best.pt是验证集上mAP最高的权重weights/last.pt是最后一个epoch的权重。后续推理和测试都用best.pt不要用last.pt。3.4 训练中断恢复和显存不足处理训练到一半断掉是家常便饭有两种处理方式。如果只是临时中断程序退出前会自动保存last.pt你只需要加一个--resume参数重跑python train.py --resume runs/train/mask_exp/weights/last.pt它会从断点位置继续优化器状态、学习率、epoch数都会自动读取非常方便。如果中断是因为CUDA out of memory按以下顺序调整参数先是把--batch从16降到8如果还不行就把--img从640降到416。还有一个隐藏技巧是加--cache ram或--cache disk把图片预加载到内存或磁盘减少IO压力虽然不能直接省显存但能缩短每个epoch的时间。技巧如果你的显卡只有4G显存还硬要跑640分辨率可以试试把--workers调低到2必要时加--rect参数它会把一批图片按相同宽高比分组有效减少padding浪费的显存。3.5 超参数怎么调YOLOv5提供了一份默认超参数文件data/hyps/hyp.scratch-low.yaml。大作业阶段不用动太多但有两个参数值得关注。一个是lr0初始学习率默认0.01。如果你发现loss降得很慢可以把它改成0.02试试如果loss剧烈震荡就降到0.005。一个是mosaic马赛克增强概率默认1.0刚才说过2000张数据量建议调到0.5~0.8。个人经验是大作业少调参固定一套稳定配置跑出结果远比来回调参卡在“差一点”上更有性价比。训练的时间花在分析结果、优化数据上收益高得多。4. 模型评估与测试4.1 关键指标解读训练完成后YOLOv5会在验证集上跑一次评估生成一个results.txt和若干张图表。这里面的几个关键指标必须能看懂Precision精确率预测为口罩的目标中真正是口罩的比例。精确率越高误检越少。Recall召回率所有真实口罩目标中被模型找出来的比例。召回率越高漏检越少。mAP0.5当IoU阈值设为0.5时所有类别的平均精度均值。这是目标检测里最常用的指标模型在PPT上写这个即可。mAP0.5:0.95在不同IoU阈值0.5到0.95步长0.05下的平均mAP这个指标对框位置精度更敏感小目标多的任务往往数值偏低不用慌。评估脚本可以直接用官方的val.pypython val.py \ --data mask.yaml \ --weights runs/train/mask_exp/weights/best.pt \ --img 640 \ --conf-thres 0.5 \ --iou-thres 0.5跑完会在runs/val/exp下输出混淆矩阵、PR曲线、F1曲线等一系列图。4.2 用detect.py做端到端检测对答辩演示来说val.py的结果毕竟是统计数字最直观的还是把模型跑在真实图片和视频上。命令很简单python detect.py \ --weights runs/train/mask_exp/weights/best.pt \ --source data/images \ --conf-thres 0.5 \ --iou-thres 0.45 \ --save-txt--source可以接图片路径、视频路径、文件夹路径甚至摄像头设备号比如0表示第一个摄像头。--conf-thres是置信度阈值低于这个分数的框会被过滤。大作业演示时建议设成0.3~0.5太低会有一堆乱七八糟的误检框太高又漏检太多。输出文件默认保存到runs/detect/exp图片上会画好框和类别名称。如果你还想把检测结果存成yolo格式的txt加--save-txt参数即可。4.3 答辩加分训练曲线可视化YOLOv5的训练过程其实已经自动生成了results.png里面有10个子图包括train loss、val loss、precision、recall、mAP等随epoch变化的曲线。很多人截个图就完事了其实这里面还能挖出不少“答辩谈资”。比如你看到val/box_loss曲线在训练到80个epoch后开始小幅上升而train/box_loss还在下降这就是典型的过拟合信号。答辩时主动说出来“我观察到第80轮后验证损失不再下降所以模型采用了第75轮的best.pt而不是最后一个epoch的last.pt”这个细节比你说“我调了很多次参数”有说服力得多。进一步可以做的把PR曲线放大看看曲线下的面积主要被哪个区间拖累然后给出“错误样本主要集中在小目标”这类结论。这些都是在报告里可以直接写进“分析与讨论”章节的素材。5. 常见问题与排查技巧实录5.1 训练不收敛或loss为NaN这是最让人崩溃的报错之一。loss变成NaN的原因有很多按概率从高到低排标签文件里有非法字符比如空行、NaN、负坐标。学习率太大导致梯度爆炸。数据里出现了损坏的图片文件比如jpg头损坏但能打开OpenCV读取出来是空数组。显存不足导致部分tensor分配失败但被框架捕获成NaN。排查方法先检查标签有没有非法值再用python -c import cv2, glob; [print(f, cv2.imread(f).shape) for f in glob.glob(**/*.jpg, recursiveTrue)]扫一遍全部图片能不能正常读取。如果都不是再降低学习率到0.001重新训练。5.2 验证集mAP为0训练却正常遇到这种情况95%是标签的类别id和data.yaml里names的顺序不对应。比如你的txt里写的是1代表“戴口罩”但yaml里第0个类别才是“戴口罩”模型学到的0类在验证时被解释成了1类结果自然全错。另一个高发原因是验证集路径配错了。data.yaml里的val如果指到了一个没有标签的目录YOLOv5会静默加载成空验证集训练完评估时直接得到0。建议在训练前用以下命令确认python -c import yaml; print(yaml.safe_load(open(mask.yaml)))同时注意检查val目录下的图片是否真的对应同名的txt标签文件。5.3 检测结果框与目标不贴合模型能检测到目标但框要么偏大要么偏小这通常不是模型问题而是标注本身的问题。回顾一下你的标注如果标注时大量使用矩形框去框“口罩部分下巴”模型学到的回归目标就是“带下巴的框”而不是“口罩的紧密框”。这种情况下即使训练得再好推理时框也会比真实口罩区域大一圈。解决办法是回炉标注规范统一“紧贴口罩边缘”的原则然后重新训练。大作业时间紧张的话可以只修部分明显偏差的label不是必须全改。5.4 漏检多、误检也多怎么判断优化方向漏检召回率低和误检精确率低是两种完全不同的毛病优化方向也不同。先看一眼confusion matrix如果“口罩真实框”那个格子下有很多未检出的数字说明模型没学到这类目标的特征要补正样本或者降低置信度阈值如果“非目标”那行有很多误检框说明背景上下文学歪了要补负样本或者提高置信度阈值。另外有一个很实用的技巧用t-SNE或者直接画特征图可视化看看模型是否区分开了两个类别。YOLOv5的detect.py加--visualize参数就能输出中间层的特征热图虽然视觉上信息量有限但能帮你确认训练是不是真的“学到了东西”。5.5 成绩验收前要做的“保底操作”最后说几个大作业验收前的保底操作。一是把best.pt复制到安全位置防止runs目录被误删。二是准备好一个演示视频不要现场才连摄像头会议室摄像头驱动装不上这种事我见得太多了。三是测试时把置信度阈值调到0.3宁多勿少真的现场误检了还能圆“阈值设定”漏检就完全没得救。我自己带过的项目里很多同学不是模型不好而是倒在了最后一步“不会展示”上。你在答辩现场演示的每一个参数都应该事先跑过一遍你报告里写的每一个指标都应该知道是在什么条件下跑出来的。这个项目的价值不在于是不是2000张、是不是YOLOv5而在于你能不能讲清楚背后的每一个选择为什么这样做。根据我的经验口罩检测这个题目做到最后最大的收获不是“我会用YOLOv5”了而是“我理解了数据到底是怎么影响模型结果的”。这句话写进报告比任何指标都更有分量。本文还有配套的精品资源点击获取