草原牦牛行为识别数据集:YOLO+VOC双格式8674张样本实战解析
发布时间:2026/10/2 8:35:15来源:尧图网络
简介数据集为草原牦牛行为识别数据集面向计算机视觉学习者与智慧牧场应用开发者共8674张jpg图片及对应标注覆盖吃草、打架、站立、躺、移动、交配等8种行为可直接用于目标检测模型训练。资源包共2000个文件其中Annotations文件夹含1999个xml标注文件labels文件夹含txt标注另有说明文件压缩包约694.83MB图片与标注分目录存放查找方便。目前已有230人学习下载。标注框总计18423个各行为类别数量已单独统计如eating 6897个、standing 3710个、lying 2071个等便于分析类别分布并划分训练/验证集。YOLO与VOC两种格式可无缝适配YOLOv5/YOLOv8、Faster R-CNN等常见框架省去格式转换环节适合快速开展牦牛行为识别实验或作为数据增强的基准数据集。1. 草原牦牛行为识别数据集8674张双格式样本能解决的问题不止“认牛”拿到这个压缩包先别急着解压。标题里的“草原耗牛行为识别数据集yolovoc格式8674张8种行为.zip”点破了三件关键事图片量是8674张不是几百张的小样标注格式是YOLO和VOC双轨行为类别有8种。这意味着你可以直接拿它训练一个能判断“牛在吃草、站立、行走还是争斗”的检测模型省掉自己去草原蹲点采集、标注的几个月时间。适合两拨人一是刚入门目标检测、想拿真实野外数据练手的新手二是做智慧畜牧或牧场视频监控落地的工程师拿它当预训练权重或迁移学习的起点。至于标题里的“耗牛”是“牦牛”的常见笔误搜索资料和解压后找目录时都留意一下。2. 先看懂数据VOC和YOLO双标注到底怎么组织的2.1 同一批图片两套标注文件的对应关系VOC格式沿用Pascal VOC的XML标注记录的是绝对像素坐标YOLO格式用同名txt文件记录归一化后的中心点坐标和宽高。二者描述同一张图里的同一个目标服务不同年代的工具链老牌标注软件、检测框架多认VOCYOLO系列训练默认读txt所以“双格式”本质是同一份数据给你发了两个版本。一张图片对应一个XML文件和一个txt文件文件名通常与图片名一致只是后缀不同。如果解压后看到Annotations/目录下是XML、labels/目录下是txt那就是标准的双轨布局如果只有一个目录说明压缩包内部其实只有一种原始标注另一种是脚本生成的。无论哪种先做文件清点。2.2 解压后优先检查这四类文件解压后不要直接开训先确认下面四类东西是否齐整。文件类型常见目录/文件名作用图片images/或JPEGImages/训练与验证输入VOC标注Annotations/下的.xml绝对坐标、类别名、图片尺寸YOLO标注labels/下的.txt归一化类别ID与坐标类别清单classes.txt或obj.names8个行为类的名称与顺序数据划分train.txt、val.txt或train/val子目录训练集与验证集划分先写几行命令看目录结构再动手unzip -q 草原耗牛行为识别数据集yolovoc格式8674张8种行为.zip -d yak_dataset cd yak_dataset find . -maxdepth 2 -type d | sortunzip -q静默解压避免刷屏解压到yak_dataset目录避免污染当前路径。find只看两层目录确认有没有images、labels、Annotations这类顶层目录。如果解压后是一堆散文件说明压缩包没带目录层级需要自己按文件名前缀归组。注意压缩包内的文件名可能包含“耗牛”字样与标题一致但脚本和目录名里最好统一改成“yak”免得后续路径处理踩坑。2.3 统计8类行为的数据分布先看长尾“8种行为”听起来平均实际上大概率不平均。野外采集场景天然偏斜站立和吃草的样本可能占六成争斗、饮水这类短时行为可能只有几百张。不统计直接训模型会被高频行为带偏。写个脚本快速统计YOLO标注里的类别分布from collections import Counter from pathlib import Path labels_dir Path(yak_dataset/labels) counter Counter() total_boxes 0 for txt in labels_dir.glob(*.txt): for line in txt.read_text().splitlines(): if line.strip(): cls_id int(line.split()[0]) counter[cls_id] 1 total_boxes 1 print(total boxes:, total_boxes) for cls_id, cnt in sorted(counter.items()): print(fclass {cls_id:2d}: {cnt:5d} {cnt / total_boxes * 100:5.1f}%)遍历全部txt读取每行第一个数字作为类别ID用Counter计数。输出能直接看出哪一类占比不足5%这就是之后训练时要重点加权的对象。这个脚本不依赖任何第三方库纯标准库就能跑。如果某个类别的框数只有几百而最多的类别有三四千说明长尾严重训练时的class_weights或数据增强要单独处理。3. 从VOC转YOLO一份能直接跑的转换脚本3.1 为什么非转不可两种坐标体系的差异很多开源数据集只给VOC格式而YOLO训练要求标签是txt。就算这个压缩包已经给了双格式也经常因为“txt是生成的、不完整”或者“缺val划分”需要自己重转一遍。VOC的XML记录的是绝对坐标比如xmin120, ymin80, xmax340, ymax260单位是像素YOLO记录的是相对坐标中心点和宽高都除以图片宽度与高度取值范围在0到1之间。坐标系原点和表示方式都不同转换公式必须准确中心点x (xmin xmax) / 2 / 图片宽中心点y (ymin ymax) / 2 / 图片高宽度 (xmax - xmin) / 图片宽高度 (ymax - ymin) / 图片高图片尺寸必须从XML的size字段读取不能自己用PIL现量。原因有两个一是量8000多张图耗时二是如果图片被预处理过比如去EXIF旋转后另存XML里记录的原始尺寸可能和实际磁盘尺寸不一致量了反而错。3.2 转换脚本与最小用法下面是我常用的转换脚本标准库即可运行import os import xml.etree.ElementTree as ET from pathlib import Path def voc_to_yolo(xml_path, save_dir, class_list): tree ET.parse(xml_path) root tree.getroot() img_width int(root.find(size/width).text) img_height int(root.find(size/height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in class_list: continue cls_id class_list.index(name) bndbox obj.find(bndbox) xmin float(bndbox.find(xmin).text) ymin float(bndbox.find(ymin).text) xmax float(bndbox.find(xmax).text) ymax float(bndbox.find(ymax).text) # 防止越界但先记录原始值 xmin max(0.0, min(xmin, img_width - 1)) xmax max(0.0, min(xmax, img_width - 1)) ymin max(0.0, min(ymin, img_height - 1)) ymax max(0.0, min(ymax, img_height - 1)) if xmax xmin or ymax ymin: continue # 宽高为负的坏框直接丢弃 x_center (xmin xmax) / 2.0 / img_width y_center (ymin ymax) / 2.0 / img_height width (xmax - xmin) / img_width height (ymax - ymin) / img_height # 强制clip到[0, 1]区间防止浮点误差 x_center max(0.0, min(x_center, 1.0)) y_center max(0.0, min(y_center, 1.0)) width max(0.0, min(width, 1.0)) height max(0.0, min(height, 1.0)) lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}) if not lines: return False # 空标签文件 save_path Path(save_dir) / (Path(xml_path).stem .txt) save_path.write_text(\n.join(lines) \n) return True if __name__ __main__: class_list [grazing, standing, walking, running, lying, fighting, drinking, scratching] # 以压缩包内 classes.txt 实际内容为准这里只是示例顺序 xml_dir Path(yak_dataset/Annotations) txt_dir Path(yak_dataset/labels) txt_dir.mkdir(exist_okTrue) converted 0 empty 0 for xml_file in xml_dir.glob(*.xml): ok voc_to_yolo(xml_file, txt_dir, class_list) if ok: converted 1 else: empty 1 print(empty or invalid:, xml_file.name) print(fconverted {converted} files, {empty} empty results)脚本先从XML的size/width和size/height拿到图片宽高这是转换精度关键。然后遍历每个object节点取类别名和坐标框做坐标防越界裁剪再套用归一化公式。逻辑说明max(0.0, min(xmin, img_width - 1))把框限制在图片有效像素范围内避免xmax超出宽度导致归一化大于1。xmax xmin的判断会过滤掉标注坏框这类框进入训练会造成损失函数异常。最后强制clip到[0,1]区间是防浮点误差不是隐藏问题——如果大量样本触发clip说明原始标注批量越界得回头查标注工具。参数说明class_list的顺序就是训练时的类别ID顺序必须与data.yaml的names保持一致。脚本默认跳过未出现在class_list中的类别名。3.3 转换后必做的三类自检转换结束并不代表能直接训练建议按以下顺序检查第一抽样对比XML与txt内容。选一张样本打开XML看原始坐标再打开对应txt手动算一遍公式结果是否吻合。批量转换里最容易犯的错是图片宽高取错这类错会让所有框偏移一个固定比例。第二检查空标签数量。野外数据存在“图片里确实没有目标”的情况这类图片在YOLO训练里应该被剔除或单独处理直接放进去会影响评估指标。脚本里已经统计了empty数量如果超过1%先看是不是XML解析路径写错了。第三检查类别ID是否越界。8种行为对应的类别ID范围是0到7如果txt里出现8或更大值说明class_list与XML里的类别名对不上。用上一章的统计脚本再跑一次看类别分布是否正常。4. 用YOLO把8类行为训起来环境、训练命令与参数4.1 环境搭建与预训练权重推荐直接用ultralytics库它是YOLOv5到YOLO11的训练入口命令行和Python API都能用。环境安装很简单pip install ultralytics如果在国内网络环境把pip源换成清华镜像否则下载依赖容易超时。验证安装python -c from ultralytics import YOLO; print(YOLO.__name__)输出YOLO说明库可用。图形化依赖版本坑多在PyTorch与CUDA版本不匹配CPU环境训练8674张图会非常慢一张640x640的图片在CPU上可能要跑好几秒建议至少用一块带8GB显存的GPU。预训练权重下载要认准官方渠道。YOLOv8s的权重文件约22MBYOLOv8m约50MB这是官方发布的基础模型权重不是从其他机构二次训练的版本。训练命令会自动下载也可以手动放weight/目录避免反复拉取。这个数据集类别是动物行为与COCO的80类差异很大但用预训练权重做初始化仍然能显著加速收敛新手别从随机权重开始训。4.2 data.yaml怎么配置YOLO训练的数据配置用一个YAML文件搞定path: /data/yak_dataset train: images/train val: images/val names: 0: grazing 1: standing 2: walking 3: running 4: lying 5: fighting 6: drinking 7: scratchingpath是数据集根目录的绝对路径train和val是相对于path的图片目录路径names的类别顺序必须与训练标签txt里的ID一致。这里写的是示例类别名具体以压缩包内classes.txt为准。如果数据集的划分不是目录结构而是两个txt文件每行一个图片路径可以把train写成train.txt的路径ultralytics也支持train: train.txt这种写法。4.3 训练命令与关键参数数据准备好了训练命令非常短yolo detect train \ datayak.yaml \ modelyolov8s.pt \ epochs100 \ imgsz640 \ batch16 \ workers4 \ patience15 \ device0modelyolov8s.pt表示用YOLOv8s结构并加载COCO预训练权重如果写yolov8s.yaml则表示只用结构、随机初始化收敛慢且最终精度通常更低。imgsz640是训练输入尺寸图片喂进网络会被缩放到640x640batch16是每批次样本数显存不够就降到8或4。patience15是早停机制连续15个epoch验证集mAP不提升就自动结束省时间。参数建议值说明modelyolov8s.pt / yolov8m.pt数据量不大s起步精度不足再升mepochs100~2008类行为不算复杂100轮足够imgsz640牦牛目标较大不必强行上1280batch16 / 8 / 4按显存调整显存不足先降batchworkers4数据加载线程数过高反而慢device0指定GPU编号CPU训练写cpubatch和imgsz的关系要单独说imgsz增大会显著增加显存占用如果显存只有8GBimgsz640, batch16可能刚好imgsz1280, batch16大概率爆显存。野外目标检测场景里目标尺寸通常占画面的比例不小不需要为了小目标强行拉高分辨率。训练开始的第一个epoch会较慢因为要做数据加载、缓存、归一化之后的每个epoch速度会稳定。如果某个epoch突然卡住很久多半是workers太高把CPU打满或者磁盘读取速度跟不上。训练结束后在runs/detect/train/目录下会生成best.pt和last.pt。best.pt是验证集mAP最高的权重推理、导出都用它last.pt是最后一个epoch的权重通常用于断点续训。5. 避坑与常见问题数据解压、标签和训练实录5.1 解压后找不到标签目录路径多了一层现象解压后发现图片在一个层级很深的目录里labels/和预期路径对不上训练报AssertionError: Label class 8 exceeds nc8之类的错误。原因压缩包内目录通常带项目名嵌套比如草原耗牛/yolo/labels和草原耗牛/yolo/images直接把路径写死到yak_dataset/labels找不到文件。解决先用find . -name *.txt | head定位所有标签文件的实际路径再用软链接或目录整理脚本把images和labels提到同一层。5.2 转换脚本里类别顺序与训练配置不一致loss降不下去现象训练loss前期下降但验证mAP一直很低或者某个类别的精确率接近0。原因VOC转YOLO时给XML里的行为名手动编号和YOLO训练时的names顺序不一致。比如XML里“fighting”排在第三位脚本里却是第5位模型学到的全是错位标签。解决永远从classes.txt读取类别顺序来生成class_list不要自己手敲顺序。代码里先读文件再传列表class_list Path(yak_dataset/classes.txt).read_text().splitlines() print(class_list)这样转出的txt与训练配置天然一致。这也是“玄学”返工最常见的原因标签错位不会报错只会让模型成绩很难看。5.3 坐标越界与坏框导致训练中BN崩溃现象训练到第几十个epochloss突然变为NaN或者验证阶段一张图上出现几百个重叠预测框。原因VOC转换时没有处理xmax超出图片宽度的坏框。这些框的存在会让归一化坐标超出[0,1]YOLO训练时的损失函数计算出现异常。加上某些图片自带的标注框宽高为0也会造成类似问题。解决转换脚本里必须clip坐标并过滤空宽高的框。同时转换完成后写一条命令扫描labels中所有非空txt检查每行的坐标值是否都在0到1之间超出就定位对应XML人工复核。5.4 行为类别长尾严重模型把所有牛都认成“站立”现象验证集总mAP显示0.6以上但具体到“争斗”“喝水”这类细粒度行为AP只有0.1。打开预测图几乎所有的牛都被识别成高频类别。原因数据集中8种行为的框数量极度不均。高频行为的梯度主导了模型更新低频行为的特征没有被充分学习。这是行为识别数据集的通病野外采集天然偏斜。解决训练前用第2章的统计脚本输出类别占比对低频类别做两件事。第一在yolo detect train配class_weights对低频类别加大损失权重第二检测图片里低频行为样本做复制粘贴增强把这些行为实例贴到其他场景里生成新标注。5.5 图片EXIF旋转导致标注偏移现象训练过程正常但推理时预测框位置与牛的实际位置整体偏移尤其是竖拍照片。原因部分手机或运动相机拍摄的图片包含EXIF旋转信息。XML标注坐标是基于原始感光矩阵的像素位置而YOLO训练前ultralytics会按EXIF信息把图片转正导致坐标与新图片尺寸不匹配。解决这是VOC转YOLO最常见的隐蔽问题。转换脚本读取图片宽高时应该先按EXIF校正后保存图片再读校正后的实际宽高。如果数据集是网络公开数据也可能已经统一校正过但仍建议抽样打印几张图片的实际尺寸与XML里的size字段对比不一致就批量校正。6. 验证与进阶从训练完到野外视频流的最后一公里6.1 看混淆矩阵别只盯mAPmAP是一个聚合指标8个类的均值掩盖了单个行为的问题。训练出的best.pt在验证集上跑一次混淆矩阵yolo detect val \ modelruns/detect/train/best.pt \ datayak.yaml结束后去runs/detect/val/看confusion_matrix.png。重点关注“争斗”“奔跑”这类同类易混行为是否大量互相误判。如果两类的混淆度超过20%把它们合并成一个行为类别或者补充数据比调参更有效。6.2 把模型接进视频推理野外场景最终是视频流实时分析。ultralytics的推理接口支持视频文件直接输入yolo detect predict \ modelruns/detect/train/best.pt \ sourceranch_video.mp4 \ conf0.35 \ iou0.5 \ saveTrueconf0.35是置信度阈值野外监控建议比公测常用的0.25高一点减少误检iou0.5是NMS的交并比阈值两个高重叠候选框会被合并。结果视频输出到runs/detect/predict/。如果要在边缘设备或NVR后端跑先把权重导出为TensorRT引擎或ONNX格式推理速度提升明显。导出命令是yolo export modelruns/detect/train/best.pt formatonnx opset12 yolo export modelruns/detect/train/best.pt formatengine device0TensorRT导出依赖GPU型号换设备后需要重新导出这是部署时必须记住的坑。6.3 下一步数据增强、难例挖掘与部署训练收敛后想再往上提精度最有效的不是继续拉长epochs而是做两件数据侧的功夫。一是针对牦牛多目标拥挤的场景做Mosaic增强默认开启但把mosaic概率调低到0.5左右否则小批量数据里融合太多样本反而让模型学糊涂。二是收集预测置信度在0.3到0.6之间的“难例”把真实标注拉出来合并进训练集再训一轮这比盲目增加图片数量更划算。我自己的教训是行为识别项目里80%的提升来自把数据和标签弄干净剩下20%才是模型和超参。先把压缩包里每一张图和每一条标签都检查过再去调imgsz和anchor顺序别搞反。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网