基于YOLOv5训练自定义人物识别模型
在智能安防、个性化图像管理和行为分析日益普及的今天,如何让机器“认出某个人”成了许多开发者关注的实际问题。比如,能否让摄像头自动识别公司员工进出?能否从家庭相册中快速找出某个家庭成员的所有照片?这些场景背后都依赖同一个核心技术——目标检测。
而在这类任务中,YOLOv5凭借其出色的推理速度与精度平衡,成为众多开发者的首选工具。更关键的是,借助迁移学习和开源生态,我们完全可以在几天内构建一个能准确识别“特定人物”的定制化模型,无需从零训练。
本文将带你走完这一完整流程:从环境搭建到数据准备、标注、训练,再到最终的推理部署。整个过程基于Ultralytics 提供的 YOLO-V8 镜像环境(别被名字迷惑,它完美支持 YOLOv5),省去繁琐的依赖配置,让你专注核心任务。
要实现一个能识别人物的模型,第一步不是写代码,而是准备好“教材”——高质量的数据集。毕竟,再强大的模型也离不开好数据的喂养。
假设我们要训练一个识别“张三”的模型。首先得收集至少200~500张包含张三的照片。数量不是唯一标准,更重要的是多样性:正面、侧面、背影;室内光、阳光下、逆光;戴帽子、口罩或普通状态;坐姿、行走、半身照……越丰富的场景,模型泛化能力越强。
图像来源可以是公开搜索、视频抽帧,甚至是实地拍摄。如果你有带该人物的监控录像或家庭视频,用ffmpeg抽帧是个高效选择:
ffmpeg -i input.mp4 -r 1 ./frames/frame_%04d.jpg这条命令每秒抽取一帧,生成一系列 JPG 图片,存入指定目录即可作为原始素材。
所有图像建议统一存放至如datasets/person_zhangsan/images/目录下,便于后续管理。
有了图像,下一步就是标注。YOLO系列使用的是归一化的边界框坐标格式,每个图像对应一个.txt文件,内容为:
<class_id> <x_center> <y_center> <width> <height>其中所有值都是相对于图像宽高的比例(0~1)。例如:
0 0.485 0.512 0.320 0.610表示类别0(即“张三”)的目标中心位于图像约中间位置,占据较大区域。
推荐使用LabelImg工具进行标注:
pip install labelimg labelimg启动后记得切换模式为YOLO格式,然后加载图像目录,创建类名zhangsan,开始逐图框选。标注完成后会自动生成同名.txt文件,结构清晰且与 YOLO 兼容。
一个小技巧:如果图像量大,可优先标注最具代表性的样本,确保覆盖各种姿态和光照条件,避免后期因数据偏差导致漏检。
数据标注完毕后,不能一股脑全用来训练。必须划分出独立的验证集,用于评估模型是否真的“学会了”,而不是简单记住了训练样本。
通常按 8:2 或 7:3 的比例拆分训练集和验证集。可以用一段简单的 Python 脚本完成自动化处理:
import os import random from shutil import copyfile image_dir = 'datasets/person_zhangsan/images' label_dir = 'datasets/person_zhangsan/labels' images = [f for f in os.listdir(image_dir) if f.endswith('.jpg') or f.endswith('.png')] random.shuffle(images) split_idx = int(0.8 * len(images)) train_images = images[:split_idx] val_images = images[split_idx:] os.makedirs('datasets/train/images', exist_ok=True) os.makedirs('datasets/train/labels', exist_ok=True) os.makedirs('datasets/val/images', exist_ok=True) os.makedirs('datasets/val/labels', exist_ok=True) for img in train_images: copyfile(f"{image_dir}/{img}", f"datasets/train/images/{img}") label = img.rsplit('.', 1)[0] + '.txt' if os.path.exists(f"{label_dir}/{label}"): copyfile(f"{label_dir}/{label}", f"datasets/train/labels/{label}") for img in val_images: copyfile(f"{image_dir}/{img}", f"datasets/val/images/{img}") label = img.rsplit('.', 1)[0] + '.txt' if os.path.exists(f"{label_dir}/{label}"): copyfile(f"{label_dir}/{label}", f"datasets/val/labels/{label}")最终形成如下结构:
datasets/ ├── train/ │ ├── images/ │ └── labels/ └── val/ ├── images/ └── labels/这个结构是 YOLO 训练脚本默认期望的路径组织方式,保持一致可减少配置错误。
接下来要告诉模型:“你要学什么”。这就需要一个配置文件来定义数据路径和类别信息。
在项目根目录新建data/person_zhangsan.yaml:
train: ../datasets/train/images val: ../datasets/val/images nc: 1 names: ['zhangsan']字段含义很直观:
-train和val指向训练和验证图像的路径(相对路径)
-nc是类别数量,因为我们只识别一个人,所以设为1
-names是类别名称列表,顺序对应标签中的 class_id
注意路径一定要准确指向你实际存放数据的位置,否则训练时会报错找不到文件。
有了数据配置,就可以开始训练了。但先别急着跑,默认参数未必适合你的硬件或任务需求。
YOLOv5 提供多个尺寸的预训练模型,可根据设备性能灵活选择:
| 模型 | 特点 | 推荐场景 |
|---|---|---|
| yolov5s | 小模型,速度快 | 边缘设备、实时检测 |
| yolov5m | 中等大小 | 平衡精度与速度 |
| yolov5l | 大模型 | 高精度需求 |
| yolov5x | 超大模型 | 服务器级部署 |
对于初次尝试,强烈建议使用yolov5s.pt—— 它体积小、加载快、显存占用低,非常适合快速验证流程是否通畅。
训练命令如下:
python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/person_zhangsan.yaml \ --weights yolov5s.pt \ --name zhangsan_v5s_exp关键参数说明:
---img: 输入图像分辨率,默认640,过高会影响速度
---batch: 批次大小,根据 GPU 显存调整(16 是常见起点)
---epochs: 训练轮数,一般50~150足够
---weights: 初始权重,使用预训练模型实现迁移学习,大幅提升收敛效率
---name: 实验名称,方便区分不同训练任务
这里特别强调一点:不要从头训练!使用yolov5s.pt这样的 COCO 预训练权重,能让模型快速掌握通用特征提取能力,只需微调最后几层即可适应新任务,节省大量时间和算力。
一切就绪后,执行训练命令:
python train.py --img 640 --batch 16 --epochs 100 --data data/person_zhangsan.yaml --weights yolov5s.pt控制台将输出类似以下日志:
Epoch gpu_mem box obj cls total targets img_size 1/100 2.1G 0.0563 0.0321 0.0187 0.1071 120 640 2/100 2.1G 0.0541 0.0305 0.0179 0.1025 118 640 ...同时系统会在runs/train/zhangsan_v5s_exp下保存训练产物:
-weights/best.pt: 表现最优的模型权重(按 mAP 排序)
-weights/last.pt: 最终轮次的模型
-results.png: 各项指标随训练变化的趋势图
-confusion_matrix.png: 分类混淆矩阵,查看误检情况
这些可视化结果非常有价值。比如打开results.png,你可以直观看到损失函数是否平稳下降、精确率和召回率是否持续提升。
重点关注几个核心指标:
| 指标 | 含义 | 理想表现 |
|---|---|---|
| Box Loss | 边界框定位误差 | 逐渐下降至接近0 |
| Obj Loss | 目标置信度损失 | 趋于稳定 |
| Class Loss | 分类损失(单类任务此项较低) | 很小 |
| Precision | 准确率(检出的结果有多少是真的) | >0.9 为佳 |
| Recall | 召回率(真实目标有多少被找出来了) | >0.85 较理想 |
| mAP@0.5 | IoU=0.5时的平均精度 | >0.9 表示优秀 |
如果发现 loss 波动剧烈或不下降,可能原因包括:
- 数据标注不准(框太松或偏移)
- 学习率设置过高
- 图像存在异常尺寸或通道问题
此外,还要警惕过拟合——训练集表现越来越好,但验证集 loss 开始上升。此时应考虑增加数据增强强度,或提前停止训练。
训练完成后,最激动人心的时刻来了:看模型能不能真正“认出”那个人。
使用detect.py脚本进行推理测试:
python detect.py --weights runs/train/zhangsan_v5s_exp/weights/best.pt --source test_video.mp4支持多种输入源:
- 单张图片:test.jpg
- 视频文件:video.mp4
- 摄像头:0(本地设备)
- 图像目录:folder/images/
检测结果会自动保存在runs/detect/exp目录中,包含标注了边框和类别的图像或视频片段。
你可能会看到这样的效果:画面中的人物被准确框出,并标记为zhangsan,即使他在走路、转身或部分遮挡,也能稳定追踪。
除了看结果,也可以深入训练输出目录检查细节:
ls runs/train/zhangsan_v5s_exp/里面的内容很有参考价值:
-results.csv: 每一轮的具体指标记录,可用于绘图分析
-opt.yaml: 本次训练所用的超参数配置,便于复现实验
-train_batch*.jpg: 展示数据增强后的样本,确认裁剪、旋转等操作是否合理
-test_batch*.jpg: 验证集上的预测效果图,直接观察模型表现
建议将best.pt导出备份,作为后续部署的基础模型。
整个流程走下来你会发现,现代深度学习框架已经把复杂的技术封装得足够友好。只要你掌握了数据准备、配置管理和训练监控这几个关键环节,就能快速构建出实用的视觉应用。
当然,这只是一个起点。你可以在此基础上做更多拓展:
-多人识别:只需扩展names列表并增加对应标注,nc改为实际人数即可
-双重验证:结合人脸识别模型(如 ArcFace)做二次确认,提高准确性
-API 化服务:用 Flask 或 FastAPI 封装成 REST 接口,供其他系统调用
-边缘部署:导出为 ONNX 格式,在 Jetson Nano、树莓派等设备上运行
YOLO 生态的强大之处就在于它的开放性和灵活性。无论是科研探索还是工业落地,它都能提供坚实支撑。
更重要的是,这类技术正变得越来越平民化。过去需要专业团队几个月才能完成的任务,现在一个人一台GPU服务器,几天就能跑通原型。这种效率的跃迁,正是AI democratization 的真实体现。
如果你正在寻找进入计算机视觉实战的入口,不妨就从训练一个“认识某人”的小模型开始。动手的过程,本身就是最好的学习。