ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

YOLOv5手势识别入门:2000张标注数据训练到部署全流程解析

YOLOv5手势识别入门:2000张标注数据训练到部署全流程解析 简介这套YOLOv5手势识别资料包面向目标检测与深度学习实践者聚焦人机交互场景中10种常见手势如数字、字母、比心等的识别适合用于算法学习、毕业设计或小型手势控制系统开发。包内数据为2000张已标注图像标签采用YOLO标准txt格式并预置3组训练好的pt权重模型、6个yaml配置文件和图形化界面代码下载后即可直接推理或继续训练。资源共71个文件以jpg/png图像作为数据集、pt模型权重和yaml配置作为推理与训练核心csv记录与txt说明辅助使用压缩包总大小约276.93MB结构清晰、易于按需取用。配套的B站视频教程从环境搭建到模型调用逐步讲解能显著降低入门门槛。目前已有21410人学习下载是兼顾完整数据、现成模型与教程的实用型手势识别资源。1. 2000 张标注数据做 YOLOv5 手势识别这套方案到底值不值得上车先泼一盆冷水手势识别不是什么高不可攀的算法题用 YOLOv5 训练自己的数据集2000 张标注好的图片完全够起步比很多人以为的“至少上万张”要现实得多。这套方案的价值在于把数据、代码、模型三样东西凑齐了你不用从零去爬图、打标签、调环境拿到手就能把 training 跑起来适合三类人一是要做毕业设计或课程项目需要一个能演示、能讲清楚原理的完整闭环二是产线上要做“手势控制设备”之类的小需求先验证可行性再决定要不要上更重的模型三是刚接触目标检测想用 YOLOv5 练手但被环境配置和数据集格式劝退过的初学者。但这里有个关键前提——2000 张标注数据并不意味着你一定能训出好模型。数据集的标注质量、类别分布、拍摄场景和你的应用场景是否一致直接决定最终效果。接下来的内容我会从数据体检、环境搭建、训练参数到踩坑排查把这套方案拆到能照着复现的程度。2. 手势数据集到手先别急着训目录结构、标注格式与质量体检2.1 数据集的标准布局images、labels 与 train/val 划分我拿到数据集的第一件事不是打开图片看而是看目录结构。YOLOv5 训练自己的数据集目录布局有硬性要求不满足的话 train.py 第一步就会报错。标准布局是 images 和 labels 两个大目录下各自分出 train 和 val 子目录对应图片和标注文件必须在子目录里一一对应gesture_dataset/ ├── images/ │ ├── train/ # 约 1600 张 │ └── val/ # 约 400 张 ├── labels/ │ ├── train/ # 与 images/train 同名的 txt │ └── val/ # 与 images/val 同名的 txt └── gesture.yaml # 数据集配置文件每一张图片对应一个同名 txt 文件。比如hand_001.jpg对应hand_001.txt这个 txt 里每一行代表一个标注框格式是五列class_id x_center y_center width height其中 x_center、y_center、width、height 都是相对图片宽高的归一化数值范围 0~1。class_id是整数从 0 开始对应 yaml 文件里 names 列表的下标。常见的 2000 张手势数据集一般标注 5 类左右比如拳头、手掌、拇指、比心、OK 这些基础手势。gesture.yaml 内容大致长这样train: gesture_dataset/images/train val: gesture_dataset/images/val nc: 5 names: [fist, palm, thumb, love, ok]这段配置的含义很直接train 和 val 指向图片目录的绝对路径或相对路径nc 告诉 YOLOv5 你要分几类names 是类别名称列表。注意 names 的顺序必须和 txt 标注里的 class_id 一一对应否则训练过程不报错但推理出来的类别名全是乱的。我就见过有人把[palm, fist]写反mAP 看起来很高实际每个框都张冠李戴。2.2 标注质量体检用脚本筛出漏标、错标和比例失调很多人拿到数据直接开训等到 loss 不降才开始怀疑数据有问题。我的习惯是先写一个体检脚本把标注文件的统计信息打出来这一步花五分钟能省后面好几天的排错时间。需要重点检查三件事类别样本数是否均衡、标注框大小分布、有没有中心坐标越界或宽高为 0 的坏标注。下面这个脚本可以快速统计类别数量和框尺寸分布import os from collections import Counter label_dir gesture_dataset/labels/train class_counter Counter() box_area_list [] for file in os.listdir(label_dir): if not file.endswith(.txt): continue with open(os.path.join(label_dir, file), r) as f: for line in f: parts line.strip().split() if len(parts) ! 5: print(fbad line in {file}: {line.strip()}) continue cls int(parts[0]) w float(parts[3]) h float(parts[4]) # 归一化后的宽高面积占比 w*h class_counter[cls] 1 box_area_list.append(w * h) print(类别分布:, class_counter) print(框面积占比 均值: {:.3f}, 最小: {:.3f}, 最大: {:.3f}.format( sum(box_area_list)/len(box_area_list), min(box_area_list), max(box_area_list)))逻辑说明遍历 labels/train 下所有 txt解析每一行标注统计类别 ID 出现次数同时计算每个框在整张图中的面积占比。这个脚本不依赖任何第三方库用标准库就能跑。重点看两个输出类别分布如果某个类只有几十个样本而其他类有几百个训练时这个类很容易被模型忽略框面积占比如果绝大多数都小于 0.05说明手势在画面中占的比例很小YOLOv5 的默认锚框对它不友好后面要重点调。参数说明box_area_list里存的是归一化后的面积占比。如果发现大量小框训练时建议把输入分辨率从 640 提升到 768 或者把 anchors 的尺度调小不要让模型去学习它根本看不清的小目标。2.3 用 10 行代码把数据集转成 YOLOv5 要的布局如果你手上的数据是 Roboflow 导出的 VOC XML 格式或者 COCO JSON 格式需要先转成 YOLOv5 的 txt 格式。VOC XML 转 YOLO 的代码不复杂核心公式就两个x_center (xmin xmax) / 2 / img_widthwidth (xmax - xmin) / img_widthy 方向同理。import xml.etree.ElementTree as ET import os def voc_to_yolo(xml_path, out_txt, class_map): tree ET.parse(xml_path) root tree.getroot() img_w int(root.find(size/width).text) img_h int(root.find(size/height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in class_map: continue cls_id class_map[name] box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) x_center ((xmin xmax) / 2) / img_w y_center ((ymin ymax) / 2) / img_h w (xmax - xmin) / img_w h (ymax - ymin) / img_h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {w:.6f} {h:.6f}\n) with open(out_txt, w) as f: f.writelines(lines) class_map {fist: 0, palm: 1, thumb: 2, love: 3, ok: 4} # 遍历 VOC 目录逐文件转换 for xml_file in os.listdir(voc_annotations): if xml_file.endswith(.xml): voc_to_yolo( os.path.join(voc_annotations, xml_file), os.path.join(labels, xml_file.replace(.xml, .txt)), class_map, )逻辑说明函数 voc_to_yolo 读取一个 XML 文件从 size 节点拿图片宽高遍历所有 object 节点用 class_map 把类别名映射成 ID再按 VOC 的 bndbox 坐标换算成 YOLO 的归一化中心点坐标和宽高。循环部分批量处理整个目录。参数说明class_map里的映射关系必须和后续 gesture.yaml 里的 names 顺序保持一致。还有个常见坑VOC 坐标可能超出图片边界标注软件手抖导致转换后 x_center 或 w 会出现大于 1 的值训练时 YOLOv5 会把这个框忽略但不是报错表现为某个类别一直学不好。转换后建议再跑一遍 2.2 的体检脚本把越界行直接过滤掉。3. YOLOv5 环境配置与最小训练命令从空环境到第一次出 loss 曲线3.1 环境配置Python、PyTorch 与 CUDA 的版本搭配YOLOv5 环境配置是新手最容易翻车的环节翻车点集中在 PyTorch 和 CUDA 版本不匹配。我的建议是先确定显卡驱动支持的 CUDA 版本再装对应版本的 PyTorch最后才装 requirements.txt顺序不能反。# 查看显卡驱动支持的 CUDA 版本 nvidia-smi如果输出显示 CUDA Version 12.1那就可以放心装 cu121 版本的 PyTorch。我一般用 pip 安装而不是 conda因为 conda 解依赖太慢而且容易把 Python 版本带偏python -m venv yolov5_env source yolov5_env/bin/activate # Windows 下用 yolov5_env\Scripts\activate pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121逻辑说明先建虚拟环境再装 PyTorch。用--index-url指定 CUDA 对应版本的下载源避免 pip 默认装到 CPU 版本的 torch。这一步装完可以用下面命令验证 GPU 是否可用python -c import torch; print(torch.cuda.is_available(), torch.__version__)输出True 2.x.0cu121就说明环境没问题。如果输出 False大概率是 torch 装成了 CPU 版或者 CUDA 驱动版本太低。不需要重装系统退一个 PyTorch 版本通常是有效的比如把 cu121 换成 cu118。3.2 拉取代码与预训练权重目录结构要心里有数环境就绪后clone YOLOv5 官方仓库然后装依赖。这个仓库本身就是一个完整的训练框架train.py、detect.py、export.py 都在根目录models 目录下是网络结构定义data 目录下是内置数据集配置utils 目录封装了损失计算、增强、日志这些功能。git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txt依赖装完先别急着训练去下载 yolov5s.pt 预训练权重放到 yolov5 目录下。用预训练权重做迁移学习是这套方案能「2000 张就够用」的核心原因——COCO 上预训练过的模型已经学会了通用的边缘、纹理、色块特征我们的手势数据集只需要在这些特征之上微调而不是从零学。3.3 最小训练命令第一次跑通比追求精度更重要第一次训练的目标是让整个链路跑通看到 loss 曲线在下降而不是追求多高的 mAP。所以参数不要开太猛python train.py --data gesture_dataset/gesture.yaml \ --weights yolov5s.pt \ --img 640 \ --batch 16 \ --epochs 50 \ --workers 4 \ --project runs/hand_train参数说明--data指向数据集 yaml--weights用 yolov5s.pt这是速度和精度的平衡点显存不够可以换 yolov5n.pt--img 640是输入分辨率YOLOv5 会按 32 的倍数做 padding--batch 16是批次大小8GB 显存跑 yolov5s 用 16 是安全值--epochs 50是训练轮数2000 张数据 50 轮大致能看到收敛趋势--workers 4是数据加载线程数--project指定训练日志和权重输出目录不设的话默认写在 runs/train 下。训练启动后终端会打印每轮的 box_loss、cls_loss、mAP 等指标同时在runs/hand_train/exp目录下生成 results.png这个图是整个训练过程最重要的体检报告。第一次跑通后你会发现真正耗时间的不是写代码而是等收敛和调参数。4. YOLOv5 手势识别的 6 个必调参数mAP 是从这些超参数里省出来的4.1 超参数是黑匣子先理解锚框、输入尺寸和学习率的关系YOLOv5 的超参数像一个黑匣子很多人只知道抄别人的配置却不理解为什么这么设。其实核心就三件事模型看多大图、每个位置能匹配到多大的目标、每次参数更新迈多大的步子。这三件事分别对应--img、--anchors和--lr。--img决定了输入分辨率。640 是默认值但如果你 2.2 节体检时发现手势框面积占比偏小比如大部分框不到画面的 1/20那么 640 分辨率下每个手势只有几十个像素特征根本提不出来。这时候把--img 768或--img 896可能是最直接的提升手段。副作用是显存占用和训练时间都会上升新手容易忽略这个权衡。锚框是个更隐蔽的变量。YOLOv5 默认会根据你的数据集自动重新计算锚框开启方式是在 yaml 里写anchors参数或者用--noautoanchor关闭。我一般让 YOLOv5 自动算它会在训练前先跑一遍 k-means 聚类统计你所有标注框的尺寸分布然后生成 9 组锚框尺寸。如果你发现训练日志里有autoanchor: 0.98 anchors/target OK这条信息说明锚框和数据集匹配得很好如果数值明显低于 1就要考虑是不是标注框太极端比如全部是细长条框。4.2 六个必调参数epochs、batch、img、lr 与它们的推荐范围下面这六组参数是我在多次手势识别训练里反复调过的直接给出推荐范围和理由参数推荐范围说明--epochs100~2002000 张数据 100 轮以内基本收敛超过 200 轮大概率过拟合--batch8~32显存 8GB 用 8~16batch 太大会让 loss 震荡幅度变大--img640~768手势占画面小就调大但 960 以上性价比陡降--lr00.001~0.01默认 0.01迁移学习时 0.001 更稳--cos-lr开启余弦退火能避免后期 loss 平台期--patience20~50验证集 mAP 不再提升时提前停止省时间以 lr0 为例这个参数是 SGD 的初始学习率。YOLOv5 默认值 0.01 是针对从零训练或大规模数据设计的我们只有 2000 张权重还是 COCO 预训练来的此时学习率保持 0.01 很容易把已经学好的通用特征冲掉。我通常会降到 0.001~0.003配合余弦退火收敛曲线会平滑很多。batch 的设置经验是显存能塞得下就尽量往 16 以上拉batch 太小会让 BatchNorm 的统计量不稳定导致每次验证集 mAP 忽高忽低。但如果显存只有 6GB硬上 32 会直接 OOM。这时候有两个后悔药一是把--img从 640 降到 512二是切换到 yolov5s 的轻量版 yolov5n而不是死磕 batch 大小。4.3 训练中断怎么办断点续训与最优权重选择训练是个长活跑一半断电、显存被别的进程抢走、或者你想换一组学习率重新来过都很常见。YOLOv5 的续训机制很简单用--resume参数指向上次的权重文件即可python train.py --resume runs/hand_train/exp/weights/last.pt逻辑说明last.pt保存的是最近一个 epoch 的完整状态包括优化器状态、学习率调度器位置和当前 epoch 数所以 resume 后会从断点继续不会从头开始。很多人不知道的是--resume只需要给权重路径训练参数会自动从上次的配置里读取不需要重新写一遍全部参数。最后选权重有个小讲究YOLOv5 训练完会产生best.pt和last.pt。best.pt 是验证集 mAP 最高的那一轮last.pt 是最后一轮。如果 best 出现在第 83 轮而 last 在第 100 轮我一般选 best.pt 做推理除非最后一轮的 mAP 和 best 差不多——因为训练末期的权重往往开始在训练集上过拟合了泛化能力反而下降。5. 训练手语模型最容易翻车的 5 个坑从现象到解决的排查笔记5.1 现象一训练就报 CUDA out of memory现象train.py 刚跑几个 step 就报RuntimeError: CUDA out of memory。原因batch、img、模型大小和显存四者的乘积超过了显存容量。8GB 显存跑 yolov5s batch 32 img 640几乎必炸。解决按顺序调整三个参数。先降 batch 到 16还炸就降 img 到 512再炸就换 yolov5n.pt。我自己的底线是宁可小 batch 跑 100 轮也不为了面子硬撑大 batch 导致中途 OOM 整个训练白干。另外检查一下是不是训练时其他进程占了显存nvidia-smi看一眼把不用的进程杀掉。5.2 现象loss 一直在高位震荡不收敛现象训练了 30 轮box_loss 还在 0.08 上下抖验证集 mAP 一直没有上升趋势。原因最常见的是学习率太大或太小其次是标签和图片有大量错配最后是类别极度不平衡。解决先用学习率的“前后对比法”排查。把 lr0 降一个数量级从 0.01 改到 0.001训 10 轮看 loss 是否开始平稳下降。如果还是不行回到 2.2 节的体检脚本检查是不是某个类别的 sample 数量过少模型根本没学到这个类的特征。该类的数量低于 50 张时考虑补充数据或者把几个相似手势合并成一类。5.3 现象训练完在测试图上什么都检测不到现象detect.py 跑一张测试图输出为空什么框都没有。原因三种可能性最大——置信度阈值设太高、测试图片和数据集的拍摄角度/光照差异太大、类别名和 label 错位。解决先把--conf-thres降到 0.1 试试如果 0.1 能出框说明模型学到了东西只是阈值卡太严。如果降到 0.1 还是空说明测试图对模型来说完全是陌生场景。这时候检查训练集里手的尺度——如果训练集全是近景特写给一张全身照模型当然认不出来。这也是我在 2.2 节强调框面积分布的原因数据集的尺度分布决定了模型的适用边界。5.4 现象训练集 mAP 很高换批数据就崩现象验证集 mAP 到 0.95模型权重换到另一批同场景图片上检测框全乱。原因这是典型的过拟合2000 张数据量本身不多如果拍摄背景单一、人物单一、光照固定模型学到的是「这个背景下的手」不是「手」。解决开启更强的数据增强YOLOv5 的 hyp.scratch.yaml 里有hsv_h、hsv_s、degrees、flipud这些增强参数。把degrees从 0 改成 15hsv_s从 0.7 提到 0.9让模型见过更多角度和色彩变化。更治本的办法是采集更多不同背景和不同人的数据至少保证训练集里有多于三个人、两种背景。5.5 现象训练时 mAP 正常推理时一张图要跑好几秒现象GPU 上训练正常部署到 CPU 或者边缘设备上单帧推理延迟高到没法用。原因weights 是 FP32 精度且模型尺寸较大CPU 推理既吃计算量又吃内存带宽。解决用 export.py 导出成 FP16 或 INT8 的 ONNX 模型推理速度能明显提升。这也是把 YOLOv5 部署到树莓派 5 这类边缘设备前的常见做法——先导出 ONNX再接 NCNN 或 OpenVINO 做进一步的硬件适配。新手容易忽略的问题是导出后要检查输出格式变化ONNX 的输出是(1, 25200, 5n)的原始预测张量得自己写 NMS 后处理不是拿来直接就有框。6. 用训练好的模型做实时手势识别推理验证与边缘设备部署技巧训练完成后第一件事是用训练时没见过的图片或视频验证别直接上摄像头否则翻车了都不知道是模型问题还是采集问题。用下面的命令对测试视频做离线推理python detect.py --weights runs/hand_train/exp/weights/best.pt \ --source test_video.mp4 \ --conf-thres 0.4 \ --project runs/detect_test参数说明--source可以是图片路径、视频路径、摄像头设备号 0也可以是目录。--conf-thres是置信度阈值0.4 是个比较稳的起点低于 0.4 误检变多高于 0.6 容易漏检。跑完后输出带框的视频或图片我习惯逐帧扫一遍重点看连续帧里类别标签是否抖动——如果一会在 fist 一会在 palm说明模型对中间过渡状态不稳定需要补一些过渡姿态的样本。实时摄像头推理可以用--source 0启动但如果帧率太低先确认是不是在 CPU 上跑。有一种更实操的做法是把检测脚本拆成「读帧-推理-画框-显示」四步把推理部分单独计时定位时间花在哪一段。我见过很多人以为模型慢实际上是 OpenCV 的读帧和显示缓存拖了后腿。边缘设备部署是我的另一个习惯。树莓派 5 上部署自己训练的 YOLOv5 模型常用路径是先导出 ONNX再转成 NCNN 格式避开 PyTorch 推理的高内存占用。导出命令如下python export.py --weights runs/hand_train/exp/weights/best.pt \ --include onnx \ --opset 12导出后用 NCNN 的 onnx2ncnn 工具转换再到板子上做推理。部署阶段我会把输入分辨率固定到 640因为 NCNN 对动态分辨率支持不好运行时再做一次等比缩放填充这一层适配往往要写不少代码但做一次后面就能复用。最后说一个我自己的教训手势识别这种任务准确率看着高不如稳定类别抖动、框跳动在演示场景里比精度低更尴尬。所以我的习惯是——小模型先把全流程跑通再回头加数据提精度而不是一开始就上大模型。这套 YOLOV5 手势识别方案数据、代码、模型都给你配齐了剩下的是你愿不愿意花一周时间把它吃透。希望帮到你。本文还有配套的精品资源点击获取
返回列表