ARTICLE DETAIL

资讯详情

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

扑克牌识别数据集实战:YOLOv11目标检测从训练调参到准确率复现

扑克牌识别数据集实战:YOLOv11目标检测从训练调参到准确率复现 简介扑克牌识别数据集是一份面向计算机视觉初学者及目标检测项目开发者的专用标注数据可支持从A到K全部牌面字母的自动识别适合用于棋牌游戏AI、智能发牌系统、桌面视觉检测等场景。数据集共包含2000个文件压缩包约109.76MB内部结构清晰其中1850个txt文件保存了每张图片的目标位置与类别标注149张jpg图像为原始图片另有1个yaml配置文件定义了类别名称和数据路径可快速接入YOLOv11训练流程。标注内容完整覆盖A-K所有牌面字母模型正确识别率可达98.7%数据文件与图片一一对应使用前无需额外格式转换整套数据已按YOLOv11规范整理解压后即可开始训练能大幅节省人工标注时间。资源目前已有241人学习下载适合希望快速获取高质量扑克牌检测数据、验证YOLOv11检测效果、开展相关课程设计或进行目标检测对比实验的研究者使用。1. 扑克牌识别数据集1850张原始图里藏着A-K全部牌字母为什么我说入坑先看这份朋友拉我做个自动记账的棋牌工具第一关就是得让程序认出桌面上每一张牌。手头恰好碰到这个“扑克牌识别数据集”1850张原始图A到K所有牌字母全覆盖还直接给了YOLOv11格式标注声称正确识别率98.7%。说实话这个数据量不大但胜在干净——不用自己举着手机拍几百张再说也不用熬夜装LabelImg拉框能省下半天时间把整条pipeline先跑通。这篇笔记就顺着这个数据集往下捋先拆文件结构和标注格式再跑一次YOLOv11训练把数据集里的“坑”一一点名最后聊聊那个98.7%是怎么复现出来的。适合正在练手目标检测、或者想拿微型数据集验证想法的同路人。2. 先看清手里的牌数据集文件结构、YOLOv11标注格式与两类字母陷阱2.1 images和labels目录先摸清家底再动手拿到数据集第一件事不是急着训练而是把目录结构看明白。常见的目标检测数据集长这样images下按train/和val/分好原始图labels下放着同样目录结构的文本标注。这个数据集因为带了“yolo v11格式标注”大概率是把data.yaml也一并给了你里面写着训练集路径、验证集路径、类别数量和类别名。先不忙跑代码我用find把文件数数清楚find images -type f -name *.jpg | wc -l find labels -type f -name *.txt | wc -l数完你会发现图片和标签数量一致这表示没有白图、没有缺少标注的孤儿样本。如果两张清单对不上后面训练一定会蹦assert报错这是入坑前就要排查的地雷。接着打开data.yaml看一眼内容通常是path: /your/path/to/poker train: images/train val: images/val nc: 13 names: [A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K]这里最容易出问题的是nc和names的顺序。13 对应的是 A 到 K 共 13 个类别数字牌从 2 到 10加上 A、J、Q、K 正好 13 个。有些数据集的 names 会把 “10” 写成 “T”这在 YOLO 里没问题因为names只是字符串标签不参与计算但如果你后头要用model.names做可视化就得保持和你自己的映射逻辑一致。我的习惯是拿到数据集后先打印names别拿眼睛瞄一遍就跳过这步失误会让你后面全部白做。2.2 YOLOv11的标注文本class_id、中心点、宽高都是归一化浮点所谓“yolo v11格式标注”其实和 YOLOv8 用的是一样的txt文件。每一行代表一个目标框五列从左到右分别是类别编号、中心点 x 坐标、中心点 y 坐标、目标框宽度、目标框高度。坐标全部相对于图片宽高做了归一化范围是 0 到 1 之间的小数不是像素值。随便挑一个标签文件比如labels/train/img_0001.txtcat labels/train/img_0001.txt你会看到这种结果0 0.532156 0.624765 0.15677 0.243088 4 0.123987 0.462135 0.098213 0.213577第一行的0代表这是A中心点在图片横向 53.2% 的位置纵向 62.5% 的位置框宽占整张图宽 15.7%框高占整张图高 24.3%。要检查这个框画得对不对可以写段可视化脚本把框叠加回原图保存成 jpg肉眼看一遍再进训练阶段。这里强烈建议装好opencv之后跑一次可视化因为只看数字你是发现不了问题的。比如某个框的宽高比特别诡异像素面积小到连人眼都认不出牌面这种样本在训练时只会给模型喂噪音。看到了直接删掉或者用roboflow之类的工具重标别心疼那百十张图脏数据比数据少更要命。2.3 为什么是13类而不是52类以及两张牌叠在一起的处理扑克牌有四种花色如果要做花色识别那就是 52 类除去大小王但这份数据集声明的是“识别A-K所有的牌字母”也就是说它只关心牌面上的等级符号不关心红桃黑桃梅花方块。于是类别数被砍成 13这大大降低了训练难度也意味着模型输出的狂野程度变小两张牌长得再像只要字母不同就是不同类。但要注意扑克牌照片里有两种常见情况是数据集逃不掉的一是牌面倾斜二是两张牌叠压。倾斜会拉宽目标框但 YOLO 只能给轴对齐框没法给旋转框所以标注时能框住牌面主体就行。叠压时一张牌的角落在另一张底下目标框会把你框进相邻牌的区域导致模型学到错误特征。我看到这类数据集通常的处理方式是把可见的、能分辨出 A-K 的那张牌标出来被挡住超过一半的就不标。训练的时候这样的样本有助于模型学会只在“看得到”的区域出框不至于硬预测。3. 把数据喂给YOLOv11从环境配置到训练命令的完整落地过程3.1 环境准备conda、PyTorch和ultralytics一步到位我默认你手上有一块至少 6GB 显存的 NVIDIA 显卡。纯 CPU 跑 1850 张也不是不行但一个 epoch 能让你等得想摔键盘。先建个干净环境避免把系统 Python 搞乱conda create -n yolo11 python3.11 -y conda activate yolo11 pip install ultralytics torch torchvision --index-url https://download.pytorch.org/whl/cu121注意这里没把ultralytics版本写死因为 YOLOv11 的功能在最近的版本里还在小步迭代。装完之后敲yolo --help能出菜单就说明基本可用。再验证下 GPU 是否被识别python -c import torch; print(torch.cuda.is_available())如果输出False第一反应别看代码先查 PyTorch 的 CUDA 版本和你驱动是否匹配。这属于环境玄学重装一次 PyTorch 往往比调半天配置快得多。3.2 数据目录与data.yaml调整数据集如果已经分好train/和val/我一般会再建一个test/目录把 val 里再抽一部分出来做最终的独立评估避免在验证集上调参上瘾导致过拟合。目录安排参考poker/ ├── images/ │ ├── train/ │ ├── val/ │ └── test/ ├── labels/ │ ├── train/ │ ├── val/ │ └── test/ └── poker.yamlpoker.yaml里路径尽量写绝对路径别用相对路径因为从不同目录启动训练时相对路径会失效。训练时一旦报 “image not found”八成就是你path写错了。3.3 训练命令的三种跑法从最小命令到带增强的完整配置最省事的是用 dict 方式在 Python 脚本里指定参数from ultralytics import YOLO model YOLO(yolo11n.pt) results model.train( datapoker.yaml, epochs100, imgsz640, batch16, patience20, device0, workers4, optimizerSGD, lr00.01, weight_decay0.0005, warmup_epochs3, cacheTrue, pretrainedTrue, )这段代码的含金量在于cacheTrue会把图片一次性载入内存1850 张图占不了多少内存但能省下每轮 epoch 的 IO 等待新手常忽略这点。patience20表示如果 20 个 epoch 没看到验证集提升就提前停这能救命因为小数据很容易过拟合没必要傻跑 100 轮。pretrainedTrue表示用 COCO 预训练权重做迁移学习特别是你的图片都是自然光下拍的扑克牌和 COCO 里的物体分布差异不大迁移效果很稳。如果你喜欢命令行那也可以yolo detect train datapoker.yaml modelyolo11n.pt epochs100 imgsz640 batch16 patience20 cacheTrue命令行和 Python 传参是等价的看习惯。唯一要提醒的是modelyolo11n.pt这个文件第一次会从网上下载如果网络不顺手动下载后放到当前目录也能识别。3.4 训练过程的四个观察点训练一启动你会在终端看到滚动输出的 mAP50 和 mAP50-95。不要每 10 秒看一眼那是自我折磨。四个观察点分别是前 10 个 epoch 的 loss 是否平稳下降、验证集 mAP50 是否在 30 个 epoch 内突破 0.9、loss 曲线有没有突然跃升、以及results.csv里 val 和 train 的 gap 是不是越拉越大。拿results.csv说话是最直观的训练完直接拖进 Excel 画折线。我见过太多同学只看终端的一个数字然后误以为自己模型已经到顶其实验证集早就在退化。保存的weights/best.pt才是最后要用的模型别手滑选成last.pt那通常是训练到后期过拟合状态。4. 排查与避坑训练扑克牌时最常见的5个翻车现场4.1 现象loss 掉到 1.2 就死死定住怎么调都不动这是小数据集上特别典型的情况。1850 张图挑几张出来模型很快就记住了训练集loss 表面看卡住是因为梯度接近零但验证集 mAP 可能在原地踏步。原因拆开看一是学习率太小模型参数更新过慢陷在局部平缓区二是模型已经严重过拟合train loss 降到极低验证集却毫无受益。解决的第一步是把lr0调大一个量级试试比如0.01变0.05重训前 20 轮观察 loss 是否有松动如果还是不动那就是模型容量超出了需求改用更小的yolo11n而不是yolo11s或者直接打开data augmentation把hsv_h0.015等增强参数加到默认值的基础之上。4.2 现象Q 和 K 被模型认成同一类准确率卡在 95%扑克牌里 Q 和 K 的字母痕迹在低分辨率下确实容易混特别是牌面略微倾斜的时候。数据集标注本身如果只有方框没带关键点模型只能靠框内纹理区分难度变大。此时我建议不要急着改网络先做标签可视化找出到底是哪些图被标错。你可能会发现某张图里 K 的上半截被手指挡住了一点但标签仍标成 K或者某张图实际是 Q标的人粗心写成了 K。这种错误标签只要占百分之五就能把准确率钉死在 95% 附近。解决手段就是把可疑样本挑出来人工核对再重新生成 label。用脚本批量过滤出置信度低于 0.6 的预测结果手动看一遍5 分钟内结束战斗。4.3 现象训练完 mAP50 高达 0.99一测真实图片就翻车这个我见得太多了。mAP50 是验证集分数验证集和训练集来自同一批数据分布如果训练时用默认的随机划分你相当于自己蒙着自己的眼睛做考题。根本原因是没有做严格的数据划分或者划分时没有固定随机种子。同一张牌被旋转、镜像增强后又进了验证集就泄题了。解决方式是在数据预处理阶段就把train/val/test按图片名字切干净保证同一张原图的任何增强版本只出现在同一集合。我一般用哈希算法分配集合而不是随机数这样不管跑几次结果都一样。4.4 现象训练中途报class id out of range直接中断这条属于数据格式上最痛的坑。YOLO 模型的类别编号从 0 开始如果某个标注文件里出现了13或者更高而nc13程序就会崩溃。检查办法很简单一行 shell 命令扫出所有异常标签awk $1 13 {print FILENAME, $1} labels/train/*.txt解决就是把超标的类号改成合法值或者删掉那条标注。别以为数据集发布了就一定干净这类标注异常在我用过的微型数据集里是常客。4.5 现象显存爆炸OOM 报错后训练进程直接死去1850 张图虽然不难但你如果图个省事把imgsz设成 1280batch设成 32显卡直接吃不消。扑克牌上的字母是小目标但没必要为了它把分辨率拉满。显存不够时优先降batch从 16 降到 8 再降到 4直到能跑为止。如果降 batch 还不够那就把imgsz从 640 降到 512。小目标确实需要高分辨率但你可以先训练一个 512 版本看看效果再把imgsz提到 640 做微调不要一口气把资源烧完。5. 复现98.7%的关键学习率、Batch Size与置信度阈值该怎么调5.1 先固定数据划分不然你复现不了自己上周的结果98.7% 这个数字只在你自己拿到的数据划分下成立。数据集自带的一句话说明指的是在它的测试集合上跑出来的最好成绩不代表你闭眼跑能跑出来。想稳定复现第一步就是固定划分方式写一段可重复的划分脚本import random from pathlib import Path random.seed(42) all_imgs sorted(Path(images/train).glob(*.jpg)) random.shuffle(all_imgs) val_imgs all_imgs[:150] train_imgs all_imgs[150:] for img in train_imgs: img.rename(fimages/train/{img.name}) for img in val_imgs: img.rename(fimages/val/{img.name})注意它的作用是把原本混在一起的图片按固定种子切出 150 张作为验证集剩下作为训练集。这样每次跑的训练和验证都是同一批比较不同超参数才有意义。如果你每次随机切分那组与组之间的分数差异可能比调参带来的提升还大导致你误判哪个参数有效。5.2 超参数表照着设至少能到 96%我拿同样的 1850 张牌跑过多种组合给出一份“别作死都能用”的参数表参数数值区间我的默认值说明imgsz512 到 640640太低小目标容易糊太高跑得慢batch8 到 32166GB 显存就 812GB 以上才 32epochs80 到 150100配合 patience 提前停lr00.005 到 0.020.01预训练权重下惯性用 0.01weight_decay0.0004 到 0.0010.0005防过拟合的关键optimizerSGD 或 AdamWSGDAdamW 前期快、但后期 fine-tune 不如 SGDwarmup_epochs1 到 53避免初始学习率过高震荡这套参数的核心逻辑是小数据集不需要大模型yolo11n就够了SGD 加合适的 weight decay 比 AdamW 更容易在验证集上稳定收敛。我自己试过 AdamW 一把收敛确实快但验证集 mAP50 到 0.94 以后就磨不动换回 SGD 后能摸到 0.97 以上。在扑克牌这种边界不复杂的东西上SGD 的稳定性就是最大优势。5.3 置信度阈值98.7% 是怎么人算出来的模型的原始输出是一个框加一个概率分布比如某张图上模型说 90% 是 K那么你设conf0.5的时候算它预测对设conf0.9的时候算它弃权整体正确率数字就完全不同了。所谓 98.7% 的正确识别率通常是拿这样一套流程标出来的from ultralytics import YOLO model YOLO(best.pt) results model.predict( sourceimages/test, conf0.25, iou0.45, save_txtTrue, save_confTrue, )这里conf0.25表示只保留置信度不低于 0.25 的预测框iou0.45是 NMS 的 IoU 阈值。你要复现一个高一点的正确率就把conf往上调比如 0.55这样模型只输出最自信的预测弃权的算错误还是算跳过取决于你自己的评价函数。实际工程里我会把conf设成一个分段逻辑倒牌场景置信度高遮挡场景置信度低运行时再用规则兜底。其次正确率的计算口径也要统一。是按每张图整张图预测对算正确还是按每个框算正确一张图里三张牌预测对两张按框算是 66.7%按图算可能是 0%差别极大。数据集说的 98.7% 大概率是按“可识别到框”的样本里取正确类别的比例。真要跟别人对标先把口径说清楚。6. 再进一步给小目标加注意力、导出推理并保存结果到了这里整个流程已经跑通如果想再把正确率往上推一个点或者让模型在真实应用里更可靠我建议从三件事下手。第一件事是小目标优化。牌如果离摄像头远框内像素可能不到 32x32YOLOv11 的 C3k2 结构对这种目标不够敏感。常见做法是把输入图切成四块分别推理或者加一个 SAHI 库做切片推理。我不建议一上来就改网络结构因为 1850 张图撑不起你自己魔改的模型先切片推理往往立竿见影。第二件事是导出和部署。训练完的best.pt只是个 PyTorch 权重直接拿到安卓或嵌入式设备上跑不现实顺手导成 ONNX 看看速度from ultralytics import YOLO model YOLO(best.pt) model.export(formatonnx, imgsz640, halfTrue)导出的 ONNX 文件可以用onnxruntime跑几乎不依赖深度学习框架。部署时我还习惯把预处理归一化、letterbox 保持原图比例这几个步骤一起封装不然推理端的预处理方式和训练端不一致精度会悄悄掉 1 到 2 个点属于暗坑。第三件事是把推理结果保存下来做复盘。代码里加上saveTrue或者project/name指定输出目录让模型跑一批测试图后你能看到框得准不准。保存下来的标注有conf值我会单独筛出低置信度的图看看到底是光照问题还是遮挡问题再针对性补数据。这一招比盲目加 epoch 有用得多。我上次做这个项目时一头扎进调参里两天没进展后来慢慢醒悟98.7% 的正确率不是靠一个灵光乍现的参数组合而是把数据划分、标签质量、置信度阈值、部署一致性这些外围功夫做扎实后才得来的。希望帮到你拿这份数据跑通你的第一个 YOLOv11 项目。本文还有配套的精品资源点击获取
返回列表