☰
打架检测数据集详解与YOLO11三平台训练实战
2026/10/5 2:36:17 网站建设 项目流程

简介:一份面向监控场景打架检测项目的实战数据集说明文档,覆盖街道、酒吧、商店、公交、监狱等多类真实监控画面,包含两人打架与多人斗殴样本,标签统一为fight单类别。数据由labelimg高质量标注,提供VOC(xml)、COCO(json)、YOLO(txt)三种格式,可直接用于YOLO等算法训练,适合目标检测入门及安防项目开发者使用。资源包为单个PDF文件,大小5.6MB,内含数据集详细介绍、标注格式说明及网盘获取方式,并随附YOLO11一键训练脚本,支持GPU/CPU/Mac(M芯片)多平台运行,还提供博主训练日志供对比参考。目前已有695人学习,适合需要快速获取已标注打架数据并开展模型训练的研究者与工程师。

1. 打架检测数据集:1000 张真实监控图,三种标注格式直接开训

做监控场景算法的人应该都有体会:打架检测这类行为识别,最缺的不是模型结构,而是带真实监控视角的数据。网上开源数据集要么是体育比赛镜头,要么是摆拍视频抽帧,跟实际安防摄像头拍到的画面差距很大,训练出来的模型一上生产就露馅。这份打架检测数据集就是冲着这个痛点来的,1000 张真实监控场景下的高质量图片,覆盖街道、酒吧、商店、公交车、监狱、空旷地等场景,既有两人扭打也有多人群殴,标签统一为 fight 一个类别。更省事的是,每张图都同时提供了 VOC(xml)、COCO(json)、YOLO(txt)三种格式的标注,拿到手不用做任何格式转换,直接就能喂给 YOLO 系列训练。外加一套支持 GPU、CPU、Mac(M 芯片)三平台的 YOLO11 一键训练脚本,适合正在做安防监控项目、需要快速验证打架检测方案,或者想拿真实场景数据补充训练集的算法工程师和研究者。

2. 数据结构与标注格式:VOC/COCO/YOLO 三件套怎么选、怎么用

2.1 解压后先看目录:图片、标注、脚本的对应关系

拿到资源后,第一步不是急着训练,而是先看清目录结构。常见做法是数据集打包成如下布局:

fight_dataset/ ├── images/ │ ├── street_001.jpg │ ├── bar_002.jpg │ ├── shop_003.jpg │ └── ... ├── annotations/ │ ├── VOC/ │ │ ├── street_001.xml │ │ ├── bar_002.xml │ │ └── ... │ ├── COCO/ │ │ └── coco_annotations.json │ └── YOLO/ │ ├── street_001.txt │ ├── bar_002.txt │ └── ... ├── yolo11_train/ │ ├── train.py │ ├── train_cpu.py │ ├── train_mac.py │ ├── dataset.yaml │ └── README.md └── 训练结果日志/ └── results_xxx.log

图片和标注严格同名对应,这是 labelimg 标注导出的标准产物。images 目录存放原始图片,annotations 下按格式分三个子目录,互不干扰。YOLO 格式的 txt 文件每行对应一个目标,格式是class_id x_center y_center width height,其中坐标值都是相对于图片宽高的归一化小数。VOC 的 xml 则是 Pascal VOC 标准结构,包含 object 节点、bndbox 包围框坐标和 name 标签名。COCO 格式把所有标注汇总到一个 json 文件里,包含 images、annotations、categories 三个核心字段。

这种按格式分开存放的设计有个明显好处:你不需要跑任何转换脚本,想用哪种格式直接指定目录就行。我一般会先抽查几个文件,确认标注坐标在图片范围内、类别名统一为 fight,再开始配训练环境。

2.2 VOC 格式详解:xml 里到底存了什么

用 labelimg 标注后导出的 VOC xml 文件,结构很固定。随便打开一个看看:

<annotation> <folder>images</folder> <filename>street_001.jpg</filename> <path>/your/path/fight_dataset/images/street_001.jpg</path> <source> <database>Unknown</database> </source> <size> <width>1280</width> <height>720</height> <depth>3</depth> </size> <segmented>0</segmented> <object> <name>fight</name> <pose>Unspecified</pose> <truncated>0</truncated> <difficult>0</difficult> <bndbox> <xmin>312</xmin> <ymin>245</ymin> <xmax>689</xmax> <ymax>578</ymax> </bndbox> </object> </annotation>

<size>节点记录的宽高必须和原始图像一致,一旦被压缩过,xml 里的坐标就失效了。<bndbox>里 xmin、ymin 是框左上角坐标,xmax、ymax 是右下角坐标,单位是像素,没有归一化。<name>就是类别名,这份数据集里统一是 fight。

很多人在 VOC 转 YOLO 时踩坑,就是忘了除以宽高做归一化。其实这里数据已经替你做好了三种格式,完全不需要自己转。但如果以后标注新数据,记住公式:x_center = (xmin + xmax) / 2 / width,y_center = (ymin + ymax) / 2 / height,宽高也要对应除以图片宽高。

2.3 COCO 格式要点:json 里 images 与 annotations 的 id 关联

COCO 格式是很多检测框架的默认输入,比如 Detectron2、MMDetection。这份数据集提供一个完整的 coco_annotations.json,顶层结构大致如下:

{ "images": [ { "id": 0, "file_name": "street_001.jpg", "width": 1280, "height": 720 } ], "annotations": [ { "id": 0, "image_id": 0, "category_id": 1, "bbox": [312, 245, 377, 333], "area": 125541, "iscrowd": 0 } ], "categories": [ { "id": 1, "name": "fight" } ] }

注意 COCO 的 bbox 格式是[x, y, width, height],x、y 是左上角坐标,width 和 height 是框的宽高,不是右下角坐标。很多从 VOC 转过来的人在这里搞混。另外每个 annotation 必须通过 image_id 关联到对应的 image,category_id 要从 categories 里查找。

用 MMDetection 或 Detectron2 训练时,只要把 json 路径和图片目录路径配好就行。如果框架要求 coco 格式的目录结构是 annotations 和 images 平级,这份资源的布局刚好满足,不用调整。

2.4 YOLO 格式与 dataset.yaml 的对应关系

YOLO 格式的 txt 是最简洁的,每行五个数字,类别 id 必须是整数从 0 开始,后四个是归一化坐标。比如:

0 0.390625 0.571528 0.294531 0.462500

这里 0 是 fight 类别的 id,接下来分别是归一化后的 x_center、y_center、width、height。这份数据集只有 1 个类别,所以 txt 里的 class_id 应该全是 0。

训练前要写 dataset.yaml,Ultralytics YOLO11 靠这个文件定位数据和类别。内容大概是:

path: /absolute/path/fight_dataset train: images val: images nc: 1 names: 0: fight

path 建议写成绝对路径,相对路径在不同系统上容易出问题。train 和 val 都指向 images 目录,如果不拆分训练集和验证集,可以这样直接指定;要正经评估精度,还是应该划分一个 val 子目录,按 8:2 或 9:1 抽一部分图进去。这里强调一下,一个只有 1000 张图的数据集,不划分验证集直接开训,loss 曲线会很好看,但泛化性能无从得知,做项目最好还是留出验证子集。

3. YOLO11 一键训练脚本实测:GPU、CPU、Mac 三平台配置与启动

3.1 Ultralytics 环境安装与版本选择

YOLO11 是 Ultralytics 在 YOLOv8 基础上更新迭代的新版本,安装方式延续了 Ultralytics 的一贯风格,pip 直接装:

pip install ultralytics

装完验证一下版本,YOLO11 对应 ultralytics 版本要求不算苛刻,一般最新版就能支持:

python -c "import ultralytics; print(ultralytics.__version__)"

我一般建议在虚拟环境里装,避免和系统 Python 环境打架。conda 创建一个干净环境比较省心:

conda create -n yolo11 python=3.10 -y conda activate yolo11 pip install ultralytics

为什么不直接用 base 环境?因为目标检测项目的依赖往往很重,torch、torchvision、opencv 这些版本一冲突,排查起来非常浪费时间。虚拟环境是成本最低的隔离手段。安装完成后,资源里的训练脚本假设你已经有了可用的 Python 环境和 ultralytics 库。

3.2 GPU 平台训练脚本解读

GPU 脚本是最核心的,命名一般是 train.py 或 train_gpu.py,核心逻辑围绕 Ultralytics 的 YOLO 接口展开。常见实现如下:

from ultralytics import YOLO # 加载预训练权重,yolo11n 是最轻量的版本,适合快速验证 model = YOLO("yolo11n.pt") # 训练入口,参数根据数据集规模调整 model.train( data="dataset.yaml", epochs=100, imgsz=640, batch=16, device=0, # 0 表示第一张 GPU 卡 workers=4, name="fight_gpu", project="runs", pretrained=True, )

参数含义说明:

  • epochs:100 轮对于 1000 张图的数据集是够用的,观察日志里 val/box_loss 不再下降就可以提前停。数据量小,训太多轮容易过拟合。
  • imgsz:640 是 YOLO 系列的标准输入尺寸,检测目标如果是密集人群里的打架动作,也可以试 768 或 896 提升小目标召回率,代价是训练和推理变慢。
  • batch:16 在 8GB 显存的卡上差不多是上限了,显存不足报 CUDA out of memory 时,先降到 8 或 4。
  • device:0 是使用第一张 GPU;多卡可以写成 device=[0,1] 或用 device=0,1 的写法,前提是显存够。CPU 训练时改成 device="cpu"。
  • workers:数据加载线程数,Windows 上偶尔会因为 workers 大于 0 报 DataLoader worker 相关错误,改成 0 或 2 能缓解。

训练脚本通常还会设置 seed 保证可复现,Ultralytics 里 seed 参数可以直接传。日志里会输出每一轮的 box_loss、cls_loss、dfl_loss,以及 Precision、Recall、mAP50、mAP50-95 等指标。

跑起来之后建议盯着前 10 轮看 loss 下降趋势,正常情况 box_loss 应从 1.5 左右快速降到 0.8 以下。如果 loss 纹丝不动,大概率是 dataset.yaml 路径配错或者数据加载出了问题。

3.3 CPU 平台训练的降速策略

CPU 训练不是不能跑,但要认清差距。同样的 100 轮、640 分辨率、1000 张图,GPU 可能 2 小时跑完,CPU 可能要 10 到 20 小时。脚本里针对 CPU 的做法通常是调小模型、关并行、降分辨率:

from ultralytics import YOLO model = YOLO("yolo11n.pt") # 用 n 版本,CPU 上尽量别碰 l/x 版本 model.train( data="dataset.yaml", epochs=50, # CPU 上先训 50 轮验证流程没问题 imgsz=416, # 分辨率降低,显存和算力压力都小 batch=8, device="cpu", workers=0, # CPU 训练时 workers 设小,避免资源争抢 amp=False, # CPU 上 AMP 混合精度收益有限,有时反而更慢 name="fight_cpu", )

关键参数变化:

  • imgsz 从 640 降到 416,计算量大约减少一半多。代价是检测精度会掉一些,但验证训练流程完全够用。
  • amp=False:混合精度在 GPU 上是加速利器,在 CPU 上可能因为算子不支持导致额外开销,关掉更稳。
  • workers=0:CPU 训练时数据加载线程和计算线程抢 CPU 资源,反而拖慢速度。
  • epochs 减半:先跑通流程,确认数据加载、评估环节正常,再决定是否拉长。

CPU 训练完的模型同样能用于推理,只是帧率会低不少。做实时监控检测,最终还是得上 GPU。

3.4 Mac M 芯片训练脚本:mps 后端的使用与注意事项

Mac 用户拿 M 系列芯片跑 YOLO11,走的是 PyTorch 的 MPS(Metal Performance Shaders)后端。脚本大致如下:

import torch from ultralytics import YOLO # 确保 MPS 后端可用 print("MPS available:", torch.backends.mps.is_available()) model = YOLO("yolo11n.pt") model.train( data="dataset.yaml", epochs=50, imgsz=640, batch=8, device="mps", workers=2, amp=False, # MPS 上 AMP 支持不完整,关闭更稳 name="fight_mac", )

MPS 后端这两年成熟了不少,但坑依然存在,列几个常见的:

  • 有些算子在 MPS 上没有实现,运行中报 not implemented,常见解法是把 device 切回 "cpu" 或用 CPU 版本的模型跑推理。
  • AMP 在 MPS 上精度问题频发,脚本里默认关闭是明智的,精度有损失但流程稳定。
  • batch 不能开太大,M 芯片内存带宽有限,推荐 8 或 4。
  • 首次运行要做 Metal shader 编译,前几步会很慢,过一会儿就趋于正常,别误以为卡死了。

M 芯片 Mac 训练速度和入门级 GPU 差不多,M1 Pro 跑 yolo11n 大概比 CPU 快 3 到 5 倍。做实验调参够用,大规模训练还是建议交给服务器。

4. 标注质量与类别均衡:1000 张图单个类别,训练时要注意的事

4.1 用 labelimg 标注的数据质量怎么快速检查

这份数据集是用 labelimg 标注的,标注质量整体较高,但拿到手建议做一个系统性体检。我会用一小段脚本扫描所有标注文件,统计每个文件的框数量、类别分布、是否有坐标越界:

import os from xml.etree import ElementTree as ET xml_dir = "fight_dataset/annotations/VOC" total_boxes = 0 empty_files = 0 for xml_file in os.listdir(xml_dir): tree = ET.parse(os.path.join(xml_dir, xml_file)) root = tree.getroot() size = root.find("size") width = int(size.find("width").text) height = int(size.find("height").text) objects = root.findall("object") total_boxes += len(objects) if len(objects) == 0: empty_files += 1 for obj in objects: bbox = obj.find("bndbox") xmin = int(bbox.find("xmin").text) ymin = int(bbox.find("ymin").text) xmax = int(bbox.find("xmax").text) ymax = int(bbox.find("ymax").text) if xmin >= xmax or ymin >= ymax or xmax > width or ymax > height: print(f"坐标异常: {xml_file} bbox=({xmin},{ymin},{xmax},{ymax})") print(f"总框数: {total_boxes}, 空文件数: {empty_files}")

这段代码做的事情很简单:遍历所有 VOC xml 文件,读取每个目标的 bndbox 坐标,检查坐标是否越界、框是否有效,最后输出统计总量。为什么要做这一步?因为标注过程中偶发鼠标误操作会产生无效框,这些框进入训练后会变成噪声标签,让模型收敛变差。1000 张图人工检查不现实,脚本扫一遍最省时间。

如果发现个别坐标异常,可以用脚本过滤掉对应图片,或者在训练时忽略这些样本。这个数据集整体标注质量不错,但花五分钟跑一次体检是值得的。

4.2 单一类别和场景分布对训练结果的约束

该数据集只有一个 fight 类别,这意味着模型的任务被简化成了二分类加回归:判断画面里有没有打架行为,并且用框框出来。相比多类别检测,单类别的收敛压力小很多,mAP50 能做到很高,但不代表模型具备判断打架强度的能力。

场景分布是另一个变量。酒吧、商店、公交车这些室内场景的光线、遮挡、摄像头角度差异很大;街道和空旷地是背景的差异最明显的两组。如果训练集和验证集来自同分布,性能指标会很好看,但换一批监控点的数据就未必还能打。

怎么缓解?常见做法是训练时开启数据增强,Ultralytics 默认的增强已经包含随机翻转、色调抖动、缩放等,可以适当加强 hsv_h、hsv_s、degrees 等参数。另一个做法是训练一个 baseline 后在真实监控视频上测试,用实际效果决定要不要补充采集数据。

4.3 训练日志怎么读:哪些指标说明模型真的能用了

资源附带了博主的训练结果日志。读日志时,重点看这么几个指标:

看 mAP50 和 mAP50-95。mAP50 衡量 IoU 阈值 0.5 时的平均精度,数值到 0.9 以上说明大致检得准;mAP50-95 更严格,跨多个 IoU 阈值取平均,一般比 mAP50 低 0.1 到 0.2 都算正常。

看 Precision 和 Recall 的平衡。打架检测的应用场景里,漏检比误报更危险,所以 Recall 尽量维持在 0.9 以上。如果 Precision 很高但 Recall 很低,说明模型偏保守,很多打架动作没框出来,这时可以调低置信度阈值。

看 loss 曲线的收敛趋势。box_loss 持续下降后进入平台期,说明模型学得差不多了。如果 val loss 在某个 epoch 后开始反弹,而 train loss 还在降,就是典型的过拟合信号,该用早停或者加大数据增强。

一个经验参考:这种单类别、1000 张图、真实监控场景的数据集,yolo11n 训练 100 轮,mAP50 正常情况下应该在 0.85 到 0.95 之间。如果低于 0.7,先检查数据是否有问题,再调整超参数。

5. 避坑指南:格式转换、中文路径、标签映射这些最常翻车的地方

5.1 用了英文路径还是报 FileNotFoundError

现象:脚本明明配置好了 dataset.yaml,训练启动时却报 images 目录不存在或者图片加载失败。

原因:最常见的是 dataset.yaml 里 path 写了相对路径,而执行脚本的当前工作目录不在数据集根目录下;另一种可能是数据集的路径里有中文或空格,Ultralytics 底层调用 cv2.imread 读图时,中文字符路径在某些环境下无法正确解析。

解决:统一用绝对路径写入 dataset.yaml,并且路径里不要包含中文和空格。Linux 和 Mac 上路径区分大小写,windows 上不区分,但都建议用小写字母和下划线命名的目录。改完之后重新运行训练,确认日志里 The results are saved to 后面输出的路径是正确位置。

5.2 GPU 显存不足,batch 调小还是换模型更有效

现象:batch 设为 16 直接报 CUDA out of memory,程序崩溃。

原因:显卡显存不够装下模型、输入图像和梯度中间变量。8GB 显存跑 yolo11n + 640 分辨率 + batch 16 确实勉强,尤其是开了 AMP 也救不回来的时候。

解决:先把 batch 调到 8,再不行调到 4。如果还想提升速度,把 imgsz 从 640 降到 512,显存占用会显著下降。终极方案是换更轻的模型 yolo11n 或 yolo11s,这俩在显存占用和速度上优势明显。也可以开梯度累积,Ultralytics 的 Train params 里没有直接暴露这个参数,所以简单点直接降 batch 就好。

5.3 三种格式标签混用,训练时类别数对不上

现象:使用 COCO json 训练时,模型输出的类别数量不对,或者 loss 异常大。

原因:COCO 的 categories 里如果有 id 跳过没用(比如用了 id=0 和 id=2,没有 id=1),一些框架会认为有 3 个类别而非 2 个。VOC 里 name 大小写不统一(如 Fight vs fight)会导致框架把同一个类别当成两个处理。

解决:打开 coco_annotations.json 检查 categories 的 id 是否从 1 开始连续递增,YOLO 格式的 txt 里 class_id 是否只出现 0。VOC xml 的 name 统一小写。这份数据集的标注规范做得比较到位,实际踩这种坑的场景是自己扩展数据集叠加标注时。

5.4 Mac MPS 训练中途崩溃或 loss 变成 NaN

现象:M 芯片 Mac 上训练到第几十轮突然崩溃,或者 loss 输出 inf/NaN。

原因:MPS 后端对某些算子支持不完整,混合精度训练时梯度溢出是一个高频原因。PyTorch 版本过旧也会触发 MPS 的坑。

解决:把 PyTorch 升级到最新稳定版,MPS 支持一直在完善。关闭 amp,让训练以全精度跑。如果问题还在,把 device 切回 cpu 继续跑,虽然慢但稳。这类问题不是每次都出现,属于概率性崩溃,跑长训练前先跑 10 轮试探一下模型是否收敛正常。

5.5 训练完的模型推理效果差,先查预处理和后处理

现象:训练日志指标很好看,但拿真实监控视频测试时,框得很不准或者根本没框出来。

原因:训练指标好是因为验证集和训练集同分布,真实监控的画面亮度、摄像机角度、目标大小分布与训练集有差距。还有一个隐性因素是推理时的置信度阈值设置不合适。

解决:推理时把 conf 调低到 0.25 或 0.15,看看 Recall 是否明显提升。Ultralytics 推理写法:model.predict(source="video.mp4", conf=0.25)。如果低置信度还是检不出,说明是域差异问题,建议用该数据集训练的模型作为预训练,在目标监控场景的数据上继续微调,比重新训练快得多。

6. 从训练到部署:模型导出的三种格式和推理加速技巧

训练完成后拿到 best.pt,这只是 PyTorch 权重,要真正部署到监控服务或边缘设备,还需要导出。Ultralytics 的 model.export() 一行搞定:

from ultralytics import YOLO model = YOLO("runs/fight_gpu/weights/best.pt") # 导出 ONNX,用于 CPU 服务或跨平台部署 model.export(format="onnx", imgsz=640, dynamic=True) # 导出 TensorRT,用于 GPU 服务器加速 model.export(format="engine", imgsz=640, half=True)

导出后的 ONNX 可以交给 ONNX Runtime 加载,推理速度比 PyTorch 原生快不少。TensorRT 引擎在 NVIDIA GPU 上能把吞吐量推到很高,适合多路视频流的打架检测。

一个我自己的习惯:每次训练完,除了看 mAP,一定会拿三段不在训练集里的监控视频测一下,一段白天街道、一段夜间室内、一段多人密集场景,确认模型在真实画面上的表现。训练日志只是过程指标,换场景测试才是验收标准。

服务器端的推理还可以用 imageio 或 OpenCV 读流推给模型:

import cv2 from ultralytics import YOLO model = YOLO("fight_best.pt") cap = cv2.VideoCapture("rtsp://your_camera_stream_url") while True: ret, frame = cap.read() if not ret: break results = model.predict(frame, conf=0.3, verbose=False) for r in results: boxes = r.boxes.xyxy.cpu().numpy() for box in boxes: x1, y1, x2, y2 = box.astype(int) cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2) cv2.imshow("fight_detection", frame) if cv2.waitKey(1) == 27: break cap.release() cv2.destroyAllWindows()

这里的推理直接复用了训练好的模型,conf 调到 0.3 是兼顾实时性和召回率的经验值。打架检测宁可多出几个误报框,也不能漏掉真实打架事件,毕竟安防场景里漏报的代价远高于误报。从那以后我每次拿到新数据集训练完,都会强制走一遍流程,先扫标注质量,再跑 10 轮烟测确认 loss 收敛趋势,然后全量训练,最后导出 ONNX 到测试机上验证推理速度。这套流程看着笨,但能替我省掉大半的无效训练时间。

这份资源里带的 YOLO11 训练脚本、三种格式的标注和训练日志,正好省去了从零搭建这些基础设施的时间,希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询