YOLO 实战:用 10 张照片训练专属目标检测模型(附标注工具+数据集)
YOLO 实战:用 10 张照片训练专属目标检测模型(附标注工具+数据集)
标签:YOLO 目标检测 深度学习 计算机视觉 实战教程
只有 10 张照片、没有 GPU、不懂深度学习,能不能训练一个"认识我家猫/我家水杯"的目标检测模型?本期用一条最直白的路告诉你:能! 从手机拍图 → 框选标注 → 一行命令训练 → 拍照就能识别,全程复制粘贴即可跑通。
一、开篇痛点场景故事
先讲三个真实到扎心的场景,看看你有没有中招。
场景 1:想认自家的猫,现成模型却"六亲不认"
小月养了一只布偶猫,名字叫"年糕"。她兴冲冲装了某大厂的识别 App,结果 App 只认识"猫"这个大类,分不清年糕和别人家的橘猫。小月想要的是:“画面里有没有年糕?它在哪?” 而不是"这是一只猫"。通用模型永远认不出"你家的那只",因为公开数据集里根本没有年糕的照片。
场景 2:想检测流水线上的"自家的螺丝",以为要几百张图
阿强在工厂做质检,产线上有一种异形螺丝,市面上的预训练模型根本不认识。领导说"上 AI",阿强上网一查,教程全是"COCO 80 类"“准备 1000 张图”“至少一块 3090”。他算了算预算,默默把方案压了下去——以为门槛高,其实只是没找对方法。
场景 3:以为训练模型必须会写代码、要有 GPU
很多读者后台问我:“我用笔记本能训练吗?”"我没显卡是不是没戏了?"答案很干脆:YOLOv8n 这种 nano 模型,10 张图在小破本上几秒钟就能跑完一轮,CPU 都能训。你不是不行,是被"深度学习很吓人"的刻板印象劝退了。
本期核心观点:目标检测的"个性化",本质是"微调(fine-tune)"——站在巨人肩膀上改最后一层,而不是从零造一个模型。 10 张图够用,CPU 够用,你够用。
二、原理详解
2.1 为什么 10 张图也能训出来?——迁移学习
直接训一个从零开始的检测模型,确实需要成千上万张图。但我们不从头训,而是用 Ultralytics 官方在百万级 COCO 数据上预训练好的 YOLOv8n 权重,只做"微调":
传统"从零训练" vs "迁移学习/微调"
从零训练(需要海量数据 + GPU):
[随机初始化权重] → 喂 10 万张图 → 学边缘/纹理/形状/语义 → 几个月
↑ 你只有 10 张,根本喂不饱,必过拟合
迁移学习 / 微调(本期方案,10 张也能动):
[COCO 预训练权重] → 已会"看边缘/纹理/形状"
↓ 只改最后几层
[喂你的 10 张图] → 让模型把"已有的视觉能力"映射到"你的类别"
↓
✅ 小数据也能收敛,因为底层特征不用重新学
打个比方:预训练模型已经是个"认识猫狗水杯的成年人",你只是告诉他"以后把这类杯子叫’阿强的螺丝’“,他不用重新学什么叫"杯子”,只要换个名字就行——这就是 10 张图够用的秘密。
2.2 YOLOv8n 为什么选它?
YOLOv8 是 Ultralytics 出品、目前最稳、文档最全的版本。n 代表 nano(最小),参数量约 300 万,模型文件只有几 MB,专为"小数据 + 弱设备"设计。
2.3 整体流程(一张图看懂)
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐
│ ① 拍 10 张图 │ → │ ② labelImg │ → │ ③ 写 data.yaml│ → │ ④ 一行命令 │
│ (手机/相机) │ │ 框选标注 │ │ 告诉路径类别 │ │ 训练 train │
└─────────────┘ └──────────────┘ └──────────────┘ └─────────────┘
│
↓
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ ⑥ 拍照识别 │ ← │ ⑤ 得到 best.pt│ ←──────────────────────│ 权重文件 │
│ (推理 predict)│ │ 你的专属模型 │ │ │
└─────────────┘ └──────────────┘ └─────────────┘
2.4 对比表格:传统方法 vs YOLO 微调 vs 找人定制
| 方案 | 需要数据量 | 需要 GPU | 技术门槛 | 成本 | 周期 | 适合谁 |
|---|---|---|---|---|---|---|
| 自己从头训模型 | 1 万+ 张 | 必须(3090 级) | 高(要会调参) | 高(买卡/租云) | 数周 | 算法工程师 |
| YOLOv8n 微调(本期) | 10–50 张 | 不需要(CPU 可跑) | 低(复制命令) | 0 元 | 半小时 | 零基础小白 |
| 外包给公司定制 | 几百张(对方准备) | 对方承担 | 你不用管 | 几千~几万 | 1–2 月 | 有预算的企业 |
| 用现成大模型API | 0 张 | 云端 | 中(要写提示词) | 按调用付费 | 几天 | 会调接口的人 |
结论:对"想认自己东西"的个人/小团队,YOLOv8n 微调是性价比最高的路,没有之一。
三、环境准备
本期所有操作在普通 Windows / Mac / Linux 笔记本即可完成,无需显卡。
# 1. 建议先建一个干净的环境(可选,但强烈推荐,避免依赖打架)
python -m venv yolo115
# Windows 激活:
yolo115\Scripts\activate
# Mac/Linux 激活:
source yolo115/bin/activate
# 2. 安装核心库:ultralytics(YOLOv8 官方库)
pip install ultralytics
# 3. 安装标注工具 labelImg(图形界面,框选照片用)
pip install labelImg
# 4. 验证安装是否成功
python -c "import ultralytics; print('ultralytics', ultralytics.__version__)"
labelImg --version
⚠️ 小提示:
- Python 版本建议 3.9 ~ 3.11,太新(3.13)偶尔有兼容坑。
- 国内下载慢,可加
-i https://pypi.tuna.tsinghua.edu.cn/simple换清华源。- 没有 GPU 也完全没问题,训练时 YOLO 会自动用 CPU,就是慢一点点。
四、实战代码(从拍图到识别,5 步走)
下面每一步都是完整可运行的,跟着做就能出结果。
4.1 第一步:准备 10 张照片
不用专业相机,手机拍就行。但要遵循 3 条"土规矩":
- 多角度:同一个物体拍正面、侧面、不同背景各几张(10 张里至少 3 个角度)。
- 有变化:光线亮一点/暗一点、近一点/远一点,模型才"抗造"。
- 单一主体为主:每张图里你的目标要清晰、别被手挡住。
把照片放进文件夹:
mydata/
├── images/
│ ├── cat_01.jpg
│ ├── cat_02.jpg
│ └── ... (共 10 张)
└── labels/ ← 这一步先空着,标注后会自动生成
如果你的目标很小(比如螺丝),拍的时候尽量让它在画面中占 1/3 以上,别拍成"芝麻大一点"。
4.2 第二步:用 labelImg 框选标注
labelImg 是免费开源的标注工具,操作像"画矩形框"。
# 在终端启动标注工具(保持虚拟环境已激活)
labelImg
操作 5 步曲:
- 打开 labelImg 后,点
Open Dir选择mydata/images。 - 点
Change Save Dir选择mydata/labels(标签和图片分开放,规范!)。 - 在左侧
PascalVOC改成 YOLO 格式(点Format切换,YOLO 格式才是我们要的.txt)。 - 按
W画框 → 输入类别名(比如niangao)→ 回车保存。 - 按
D切下一张,重复到 10 张全标完。
标注完成后,labels/ 里会出现 10 个 .txt,每个文件内容是:
# niangao.txt 示例(每行:class_id cx cy w h,坐标都是 0~1 的相对值)
0 0.512 0.463 0.331 0.402
一个常见疑问:只标 10 张,会不会"标错一张就崩"?不会。YOLO 对少量噪声标注有一定容忍度,但框要尽量贴合物体边缘,别框太大把背景也圈进去。
4.3 第三步:写 data.yaml(告诉模型去哪找数据)
在项目根目录新建 data.yaml:
# data.yaml —— 你的数据集说明书
path: ./mydata # 数据根目录(绝对路径更稳妥,Windows 用 / 或 \\)
train: images # 训练图片文件夹(相对 path)
val: images # 验证也用这 10 张(小数据常见做法)
nc: 1 # 类别数量:你只标了 1 类
names: ['niangao'] # 类别名,顺序要和标注的 class_id 对应
💡 小数据技巧:训练集和验证集用同一份 10 张图,虽然不严谨,但对个人玩票/快速验证完全够用。正式项目再按 8:2 拆分。
4.4 第四步:一行命令开训
这是全期最"爽"的一行代码——10 张图也能跑,而且很快:
# train_10photos.py
from ultralytics import YOLO
# 1. 加载官方的 nano 预训练权重(自动下载,约 6MB)
model = YOLO('yolov8n.pt')
# 2. 在 YOUR 的 10 张图上微调
# data: 数据集配置
# epochs: 训练轮数。10 张图,50 轮足够,多了反而过拟合
# imgsz: 输入尺寸,640 是 YOLO 标准
# batch: 批次。数据少,batch=2~4 即可
# device: 'cpu' 表示用 CPU;有显卡写 0
results = model.train(
data='data.yaml',
epochs=50,
imgsz=640,
batch=4,
name='my_niangao_model',
device='cpu', # 有 NVIDIA 显卡改成 device=0 会快很多
pretrained=True, # 关键!基于 COCO 预训练做微调
verbose=True
)
print("训练完成,最佳权重在:", results.save_dir)
运行:
python train_10photos.py
终端会滚动输出每一轮的 box_loss、cls_loss……别慌,只要 loss 在慢慢下降就说明在学。训练完,权重保存在:
runs/detect/my_niangao_model/weights/best.pt ← 这就是你的专属模型!
4.5 第五步:拍照识别(推理)
把 best.pt 拿来用,拍张新照片试试:
# predict_10photos.py
from ultralytics import YOLO
# 加载你刚训好的模型
model = YOLO('runs/detect/my_niangao_model/weights/best.pt')
# 推理一张新照片(可以是手机刚拍的 test.jpg)
results = model.predict(
source='test.jpg',
conf=0.25, # 置信度阈值,越低越容易报框(小数据可降到 0.2)
save=True, # 把画了框的结果图存到 runs/predict/
show=False
)
# 打印检测到的内容
for r in results:
boxes = r.boxes
print(f"检测到 {len(boxes)} 个目标:")
for b in boxes:
cls_id = int(b.cls[0])
conf = float(b.conf[0])
name = model.names[cls_id]
print(f" - 类别: {name}, 置信度: {conf:.2f}")
跑完去 runs/detect/predict/ 看结果图,框已经画好了——你的模型认出了年糕!
4.6 番外:用摄像头实时检测(让模型"活"起来)
训好模型后,最爽的玩法是用摄像头实时看框——不用再一张张存图:
# predict_realtime.py
from ultralytics import YOLO
model = YOLO('runs/detect/my_niangao_model/weights/best.pt')
# source=0 调用默认摄像头,show=True 实时弹窗画框
model.predict(
source=0, # 0 = 笔记本摄像头;手机端玩法见第116期
conf=0.25,
show=True, # 实时显示带框画面
save=False
)
小技巧:弹窗里按
q退出;想顺手录成视频,加save=True,会生成runs/predict/*.avi。如果摄像头打不开,先确认系统里它的设备号——有的双摄笔记本 0 是前置、1 是后置,换个数字试试。
4.7 训练超参数速查表(照抄不踩雷)
10 张图属于"极小数据",参数和常规训练不一样。下面这表直接照抄:
| 参数 | 建议值(10 张图) | 作用 | 调大 / 调小的影响 |
|---|---|---|---|
epochs | 30~50 | 训练轮数 | 太大→背下数据(过拟合);太小→没学够 |
batch | 2~4 | 每步吃几张 | 大→快但吃内存;小→更稳 |
imgsz | 640 | 输入尺寸 | 大→更准但更慢;小→快但漏小目标 |
lr0 | 0.01 | 初始学习率 | 大→可能不收敛乱跳;小→收敛慢 |
augment | True | 数据增强 | 开→模型更"抗造",少过拟合 |
patience | 20 | 早停耐心轮数 | 连续 N 轮没提升就停,防白训 |
warmup_epochs | 3 | 热身轮数 | 小数据设小,避免初期乱更新 |
optimizer | ‘auto’ | 优化器 | 新手保持 auto,YOLO 自动选 AdamW |
记不住就记住一句话:10 张图,epochs 别超 50,augment 一定开,patience 设 20。剩下的交给早停。
4.8 训练曲线怎么看(别被数字吓到)
终端每轮会打印几个 loss,新手只需盯三个:
box_loss:框位置准不准,应持续下降并趋于平缓。cls_loss:类别分对没,应持续下降。mAP50:综合精度,应持续上升(验证集上)。
如果 box_loss 一路降到接近 0 但新照片一测就翻车 → 典型过拟合,回去把 epochs 调小或 augment=True。
五、效果对比(10 张图到底够不够?)
我们用"宠物识别"这个典型场景,对比不同数据量下的真实体感:
| 数据集规模 | 训练设备 | 单轮耗时 | 约总耗时 | 识别自家猫准确率 | 推荐指数 |
|---|---|---|---|---|---|
| 10 张(本期) | CPU | ~3 秒 | ~2.5 分钟 | 70%~85%(角度合适时) | ⭐⭐⭐⭐ 入门首选 |
| 30 张 | CPU | ~8 秒 | ~7 分钟 | 85%~92% | ⭐⭐⭐⭐⭐ 甜点区 |
| 50 张 | CPU | ~12 秒 | ~10 分钟 | 90%~95% | ⭐⭐⭐⭐⭐ 更稳 |
| 200 张 | GPU | 快 | 几分钟 | 95%+ | ⭐⭐⭐ 正式项目 |
关键结论:10 张不是"极限挑战",而是"最低可行验证"。用它确认"这条路走得通",然后慢慢补图到 30~50 张,效果会肉眼可见地变好。先跑通,再优化,比纠结"数据不够"迟迟不动强一百倍。
速度方面,YOLOv8n 在普通笔记本 CPU 上推理一张图约 80~150ms,完全能接受;放到手机上(见第 116 期)还能更快。
六、避坑指南(血泪总结)
❌ 坑1:标注类别名和 yaml 对不上
现象:训练报错 Dataset 'data.yaml' error,或者推理出来类别名是乱码/数字。
原因:labelImg 里你输入的是 年糕,但 data.yaml 的 names 写的是 niangao;或者顺序错乱,class_id 和名字对不上。
解决:
- 类别名统一用英文/拼音,避免中文路径和中文类别名踩编码坑。
names列表的顺序 = 标注文件里 class_id 的数字顺序(第一个是 0,第二个是 1…)。- 不确定时,打开任意一个
.txt看第一列数字,它必须< nc。
❌ 坑2:图片路径/格式导致读不到数据
现象:训练一开始就说 WARNING ⚠️ No images found,或者 labels 数量为 0。
原因:data.yaml 里 path 写错;或图片是 .png 但你在文件夹里放的其实是 .jpeg;或 images/labels 文件名不一一对应。
解决:
path用绝对路径最稳:path: D:/mydata。- 确认 images 和 labels 下文件名一致(仅扩展名不同):
cat_01.jpg↔cat_01.txt。 - 用下面这行命令自查图片数:
ls mydata/images | wc -l # Linux/Mac dir mydata\images # Windows
❌ 坑3:训练轮数太多,反而"学歪了"
现象:训练时 loss 降得很低,但拿新照片一测,要么啥都认不出,要么把背景当目标。
原因:10 张图训 300 轮,模型把这 10 张图的每一个像素都背下来了(过拟合),换个角度就不会了。
解决:
- 10 张图
epochs=30~50足矣,别贪多。 - 加一点"数据增强"让模型见多识广,在 train 里加:
model.train(..., augment=True, hsv_h=0.015, hsv_s=0.7, hsv_v=0.4, flipud=0.0, fliplr=0.5, scale=0.5) - 早停:设
patience=20,连续 20 轮没提升就自动停,省时间。
配套资源:本文涉及的完整代码、数据集和配置文件已整理归档,感兴趣的朋友可以在我的 CSDN 主页简介中找到获取方式。
如果这篇对你有帮助,欢迎 点赞 + 收藏,有问题也欢迎在评论区交流!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)