☰
手机检测数据集:基于YOLOv8训练目标检测模型的完整实战指南
2026/9/30 23:22:14 网站建设 项目流程

你是不是也有过这种经历:会议室里想统计谁在低头刷手机,靠人眼盯着监控画面一帧一帧找;工位上想验证“摸鱼检测”算法,结果找遍全网没有能直接用的数据集;课堂行为分析项目做到一半,模型能把人框出来,却分不清手里拿的是手机还是笔记本……这类需求的共同点就是一句话:先得有一个能稳定检测“手机”这个目标的模型,才有可能往下做行为判断。

这份手机检测数据集,就是一个专门解决“把手机从画面里找出来”这个问题的目标检测数据集,一共2800 张图片,全部用YOLO 格式标注。它解决的痛点是:通用目标检测模型里“手机”这个类别太宽泛,且公开数据集中手机样本占比极低,导致在真实监控画面上误检漏检严重。这篇文章我会从数据集的定位、标注格式、目录结构讲起,再到用 YOLOv8 训练一个可用模型的完整实操过程,最后把训练中最容易踩的坑翻出来逐个讲透。无论你是刚入门目标检测的在校生,还是在公司里做行为分析、安防巡检、手机回收分拣的工程师,这篇内容都能直接照着做。

1. 这个数据集能做什么:先想清楚需求再动手

1.1 手机检测不是通用目标检测的“简单子集”

很多人一开始会问:COCO 数据集里本来就有 cell phone 这个类别,直接用现成模型不就行了?我最初也这么干过,实际一测才发现情况差得远。

COCO 里的手机样本大多是大而完整的商品图,背景干净、光照充足、没有遮挡。而现实场景中的手机检测,几乎全是“小目标 + 部分遮挡 + 复杂光照”的恶劣组合:远处桌上扣着放的手机只有十几个像素;手里握着的手机被手指挡掉一半;屏幕反光导致外观特征完全变化。这类场景在通用数据集里占比极少,模型自然学不到。

所以这份数据集的定位很明确——它是专门围绕“手机在真实场景中被使用、被携带、被放置”的各种状态来采集和标注的,而不是简单地从 COCO 里切一个子集出来。检测目标只有一个类别phone,专注、不分散,模型能充分收敛到这个单一类别的特征上,在垂直场景下的精度比通用模型高一截。

1.2 2800 张图真的够用吗

这是所有拿到数据集的人第一反应的问题。我的回答是:够用,但有个前提——必须配合预训练权重做微调,而不是从零训练。

从零训练一个目标检测模型需要几万乃至几十万张图,但 YOLOv8 这类模型在 COCO 上已经有很强的通用特征提取能力。我们拿它的预训练权重作为起点,在这个手机数据集上做迁移学习,模型真正要做的只是“在已有特征基础上,把‘手机’这个类别强化出来”。2800 张图用于微调,配合 YOLO 自带的数据增强(mosaic、翻转、HSV 扰动等),效果已经足够支撑大多数应用场景。

如果你的场景有特殊性,比如全是俯拍考场画面,或者全是桌面近景,那这个数据集可以作为基础底座,再补充一部分你自己的场景图片继续微调。这也是我推荐的做法。

2. 数据集构成与标注格式拆解

2.1 图像内容与采集思路

这批数据的核心原则是“覆盖检测时可能遇到的绝大多数情况”。采集和筛选时重点覆盖了以下几类变化维度:

  • 目标尺度变化:从近景占画面大半个框的“大目标”,到远景只有二三十像素的“小目标”;
  • 手持状态:右手持机、左手持机、双手持机、打电话贴近耳朵、走路看手机;
  • 放置状态:桌面平放、桌面立放、口袋里露出一角、充电支架上横放;
  • 遮挡关系:手部遮挡屏幕、遮挡机身、被其他物品挡住一部分;
  • 光照条件:室内灯光、窗户逆光、夜间屏幕亮起、屏幕熄灭状态、强烈反光;
  • 手机形态差别:不同品牌、全面屏与带实体键盘的老款机型、横竖屏方向。

整理数据之前,我建议你先列一张覆盖矩阵,把你知道的常见变化维度列出来,再对着采集。只拍一种场景的数据再多也没有用,模型永远学不会泛化。

另外,这批数据里单张图片的物体数量并不固定。有的图只有一台手机,有的图同时出现三四台——这一点对真实场景很重要,因为多人同时看手机的监控画面太常见了。

2.2 YOLO 标注格式到底长什么样

YOLO 格式的每个标注框对应一张图片的同名 txt 文件,每一行的格式是:

class_id x_center y_center width height

注意这里的四个坐标值都是相对于图片宽高的归一化坐标,范围在 0 到 1 之间。比如一张 640×640 的图片里,一个手机框左上角在 (160, 160),右下角在 (320, 320),那么中心点就是 (240, 240),相对坐标就是 240/640 = 0.375,宽高都是 160/640 = 0.25,标注行就是:

0 0.375 0.25 0.25

很多人第一次写训练代码报错,就是因为把像素坐标直接写进去了。YOLO 内部做数据加载时会把归一化坐标换算回特征图上的相对位置,坐标一旦大于 1,轻则框位置错乱,重则训练直接发散。拿到数据后的第一件事应该是写一个小脚本检查标注是否越界。

我提供一个 Python 脚本,用来遍历数据集,检查是否有坐标越界的标注,并可视化抽查几张图:

import cv2 import os import numpy as np img_dir = "phone_dataset/images/train" label_dir = "phone_dataset/labels/train" for img_name in os.listdir(img_dir): img_path = os.path.join(img_dir, img_name) label_path = os.path.join(label_dir, os.path.splitext(img_name)[0] + ".txt") if not os.path.exists(label_path): print(f"Missing label: {img_name}") continue img = cv2.imread(img_path) h, w = img.shape[:2] with open(label_path, "r") as f: for line in f: parts = line.strip().split() cls, x_c, y_c, bw, bh = int(parts[0]), float(parts[1]), float(parts[2]), float(parts[3]), float(parts[4]) # 坐标越界检查 if not (0 <= x_c <= 1 and 0 <= y_c <= 1 and 0 <= bw <= 1 and 0 <= bh <= 1): print(f"Invalid bbox in {img_name}: {line}") continue # 还原像素坐标并绘制 x1 = int((x_c - bw / 2) * w) y1 = int((y_c - bh / 2) * h) x2 = int((x_c + bw / 2) * w) y2 = int((y_c + bh / 2) * h) cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.imshow("check", img) cv2.waitKey(0) cv2.destroyAllWindows()

用这个脚本快速过一遍所有图片,能发现很多标注软件导出时产生的低级错误。

2.3 数据集划分:一个容易被忽略的关键步骤

数据集的默认划分是训练集 2520 张、验证集 280 张,约 9:1。为什么要单独留验证集?因为训练过程中我们需要一个“模型没见过的数据”来衡量效果,否则只看训练集 loss 下降,根本分不清模型是真正学会了还是死记硬背。

划分时最容易犯的错误是“同场景图像泄漏”。比如同一个会议室的连续帧画面,一部分被分进训练集,一部分被分进验证集。模型在训练时已经见过几乎一模一样的画面了,验证集分数自然虚高,但一到新场景就现原形。所以在划分之前,最好先按“场景会话”分组,确保同一个房间、同一段监控的画面整体只进训练集或只进验证集。

另外建议在完整训练前先用下面这个命令快速验证数据配置是否正确:

yolo detect train data=phone.yaml model=yolov8n.pt epochs=1 imgsz=640

如果配置有问题,这一步会立刻抛错,能帮你节省大量排查时间。

3. 训练实操:用 YOLOv8 把模型跑起来

3.1 环境准备与安装

训练环境我推荐用 conda 管理,避免不同项目之间的依赖冲突。执行以下命令:

conda create -n phone_det python=3.10 conda activate phone_det pip install ultralytics

ultralytics 包会连带安装 PyTorch(CPU 版)。如果你有 Nvidia GPU,建议先单独安装对应 CUDA 版本的 PyTorch,再安装 ultralytics,否则训练速度会慢到怀疑人生:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics

我这里用的是 CUDA 11.8 为例,具体按你的显卡驱动版本选择。装完后命令行里敲yolo能弹出帮助信息,环境就算备好了。

3.2 数据目录与配置文件

将数据集解压后建议整理成 YOLOv8 要求的目录结构:

phone_dataset/ ├── images/ │ ├── train/ │ ├── val/ ├── labels/ │ ├── train/ │ ├── val/

对应的 images 和 labels 目录下的文件名必须一一对应,只允许后缀不同。然后写一个phone.yaml:

path: /path/to/phone_dataset train: images/train val: images/val nc: 1 names: ['phone']

path是数据集根目录的绝对路径,train和val写成相对路径,这样就算整个数据集目录移动了,只要改path一行即可。nc是类别数量,这里只有手机一类,所以是 1。names列表里的顺序必须和标注文件里的class_id对应,如果你标注时手机类别 id 是 0,那 names 里第一个就是 phone。

3.3 训练命令与参数选择

基础训练命令:

yolo detect train data=phone.yaml model=yolov8n.pt epochs=100 imgsz=640 batch=16

这里拆开讲几个关键参数怎么定。

模型选择:yolov8n 是最轻量的版本,适合先跑通流程;显存充裕且对精度要求更高的场景,换成yolov8s.pt或yolov8m.pt。我的经验是先用 nano 跑一版完整的训练流程,确认指标正常,再换大模型,能避免大模型训练半天才发现数据有问题的尴尬。

imgsz:YOLOv8 默认 640,但手机在监控画面里经常属于小目标,输入分辨率直接决定小目标有多少像素。如果数据集中有不少小目标,我建议直接设成 768 或 1024,对最终精度影响非常明显。代价是显存占用增大、训练变慢,可以配合batch调低一点。

batch:这里的 16 是总 batch size,分布在所有 GPU 上。单卡 8G 显存跑 640 输入、yolov8n,batch 16 基本是极限;如果报 OOM,就先减半到 8,再不行开 AMP 混合精度。AMP 在 YOLOv8 里默认开启,一般不需要额外配置。

epochs:100 轮是起步值。从 loss 曲线上看,如果 60 轮左右验证集 mAP 已经不再上升,就可以提前早停;如果 100 轮还没收敛,可能是数据问题而不是轮数不够。

用户可能会想,为什么不直接用model=yolov8m.pt起步?因为大模型对错误数据更敏感,先用小模型跑通,能更快定位问题。

3.4 训练评估与模型导出

训练过程中终端会实时打印每个 epoch 的损失值和指标,包括box_loss、cls_loss、dfl_loss、precision、recall、mAP50、mAP50-95。训练结束后,最好的权重默认保存在runs/detect/train/weights/best.pt。

关于指标怎么看,我建议重点看mAP50和mAP50-95两个值。mAP50 是预测框和真实框 IoU 阈值 0.5 时的平均精度,适合快速衡量模型“大概能不能用”;mAP50-95 是 IoU 从 0.5 到 0.95 每隔 0.05 取一次平均,标准苛刻得多,更能反映框定位的精细程度。对手机检测这种对框位置有一定要求的场景,两个都重要。

验证集上跑一下:

yolo detect val data=phone.yaml model=runs/detect/train/weights/best.pt

输出结果里的speed字段能直接看到单张图片的推理耗时。上传到服务器部署之前,全流程先在本地过一个遍。

推理测试单张图片:

yolo detect predict model=runs/detect/train/weights/best.pt source=test.jpg conf=0.25

conf=0.25是置信度阈值,低于这个值的预测框会被过滤掉。在误检严重的场景可以调高到 0.4 或 0.5,漏检严重的场景则调低。

最后如果需要部署到边缘设备,导出为 ONNX 通用格式:

yolo export model=runs/detect/train/weights/best.pt format=onnx imgsz=640

ONNX 可以无缝转到 TensorRT、OpenVINO 等推理框架,这在实际项目中比直接在 PyTorch 里推理实用得多。

4. 训练中容易被坑的细节:问题排查实录

4.1 小目标漏检严重怎么办

如果推理画面里远处的手机完全没有框,模型在验证集上的表现也不差,但实际场景里小目标就是检测不到,最直接的原因就是输入分辨率不够。

YOLOv8 的骨干网络有下采样倍数,最终特征图分辨率是输入尺寸的 1/32。输入 640×640 时,最大的特征图尺度是 20×20,每个格子负责的区域很大,一个 20 像素宽的手机框可能连一个格子都占不满,模型自然学不到特征。三个层面的改进方向:

  • 提高imgsz到 768 或 1024,让目标占据更多的有效像素;
  • 对原图做滑窗切分(比如把 1920×1080 切成四块 960×540 分别推理),目标相对尺度直接放大数倍;
  • 换用带有更强小目标检测能力的模型版本,比如 YOLOv8 本身在 head 里有多尺度检测,但小目标分支仍然较弱,可以考虑加入 P2 层或换用专门优化小目标的模型结构。

另外批量标注的时候,小目标框很容易标得偏大或偏小,注意框要贴住手机边缘,多标几次就能找到感觉。

4.2 标注数据里的隐藏问题

训练集里如果还有错误标注,模型很快就学会了错误答案。几个实际遇到的坑:

框坐标越界:有些标注工具导出时会把超出图片边界的框原样写入,比如手机只露出一半,标注框却把整机宽高都写了进去。这类数据在训练时会让模型学到“手机可以超出画面存在”的错误认知。解决方法是写脚本检查并裁剪越界坐标,使用前文提到的那个检查脚本提前筛一遍。

类别文本错位:如果标注工具类别配置错了顺序,txt 里写 0,但实际想标的是 phone,训练完的模型会完全错乱。建议训练前随机挑几张图可视化确认,类别和框都要对得上。

空标签文件:有些图片对应的 txt 是空的,表示这张图没有目标。YOLOv8 会把空标签文件当作背景样本,这是合法的,不用删。但如果大量高质量图片都因为漏标变成了背景样本,那背景比例失衡会让模型偏向于“什么都不预测”。开源数据里常出现这种情况,损失最大。

文件名编码问题:中文文件名在 Windows 上的编码不一致会导致路径读取失败,最好统一改成英文或数字混合命名,并且只保留一张图片一个同名 txt 的对应关系。

4.3 训练不收敛、loss 异常怎么定位

训练了几十个 epoch,loss 不降反升,或者直接出现 NaN,不要急着改模型,优先排查这几个因素。

BN 崩溃:BatchNorm 在 batch size 太小(比如 1 或 2)时,统计量不稳定,容易导致激活值异常放大,最终 loss 爆炸。YOLOv8 默认对输入做了通道归一化,但超小 batch 依然危险。遇到 loss 稳定不降时,先看看是不是 batch 太小。

学习率问题:YOLOv8 默认lr0=0.01,如果你手动改成了 0.1 或更大,基本必炸。观察前几个 epoch,如果 loss 直接冲到 20 以上且不回头,大概率是学习率过大。从默认值开始,只在你对调参很有把握时再动学习率。

数据没归一化:如果你在自己的代码里手动加载数据,而不是走 ultralytics 的数据管线,很容易忘记把图片像素除以 255,或者把坐标当成像素值直接用,这会导致特征分布异常。用 ultralytics 自带管线可以完全避免这个问题。

标签错误:类别 id 超出nc范围时,代码不会立刻报错,但 loss 会异常走高。查一次标签的类别分布,确认只有 0。

4.4 混淆矩阵总和不是 1 是怎么回事

训练完用yolo detect val会自动生成混淆矩阵图。有次一个学员截图问我:矩阵里所有格子的数加总不是 100%,是不是出 bug 了?

这不是 bug。YOLO 生成的混淆矩阵是按真实类别归一化显示的,每一行的数值代表这个类别的真实样本被预测到各个类别(包括背景)的比例,所以单独一行之和接近 1。但整个矩阵因为存在“背景被预测为目标”“目标被预测为背景”等多种情况,各行的基数不同,加总起来自然不等于 100%。看混淆矩阵的正确方式是一行一行看:看phone这一行里有多少比例正确分类,有多少漏成了背景,而不是看整个矩阵的合计值。

4.5 数据增强的度怎么把握

YOLOv8 默认开启mosaic数据增强,把四张图拼成一张,对小目标检测提升很大。但对手机检测这种目标类别单一的垂直任务,增强太猛反而可能害了你。

比如默认的 HSV 扰动会把亮度变化调得很大,如果你的目标场景是室内固定光照,模型反而会在过强的光照扰动上学到不真实的颜色分布。这属于典型的“过度增强”。我的习惯是先用默认参数训练一版,看验证集 mAP 和实际场景测试效果,如果实际画面颜色偏暗而模型总漏检,再调低hsv_v(亮度扰动幅度);如果画面反光严重,可以适当加大hsv_s让模型对颜色变化更鲁棒。数据增强的本质是给模型补充无限多的样本,但补充的样本必须和真实部署场景相关。

最后说点实操体会

这批数据的训练和调优过程我在本地和服务器上反复跑过多次,最大的体会是:数据集的 2800 张图不算多,但当你围绕它把覆盖矩阵列全、标注质量把关到位、再配合预训练权重微调,产出的模型在真实场景里的可用度远远超出预期。建议你先用 yolov8n 花一个下午跑通全流程,看清每个指标的含义,再决定要不要换大模型;不要一上来就追求最高精度,先把流程跑通才能知道瓶颈在哪。

另外这个数据集之后还有两个不错的扩展方向:一是把“手机 + 人手”一起训练,为姿态估计和行为识别提供前置输入;二是采集一些带实体键盘的老款手机和折叠屏新机型,覆盖更广泛的目标形态。做目标检测项目永远是数据和场景先行,模型反而是最不愁的那一环。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询