恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

YOLO溺水检测实战:339张数据集处理与训练全流程

  • 首页
  • 资讯中心
  • /
  • YOLO溺水检测实战:339张数据集处理与训练全流程

相关资讯

Python机器学习信用评估实战:从评分卡到风控模型上线 2026/10/11 0:36:41
太阳能电池板YOLO高变焦检测:24577张数据集训练实战 2026/10/11 0:31:41
GANMaster人脸矫正实战:从模糊脸到公安标准证件照 2026/10/11 0:31:41

最新资讯

多智能体非中心化安全控制:DMPC实战落地指南
Matlab风功率预测误差分析实战:指标选型、脚本实现与工程应用
彭大帅的AI运维助手实战案例 5 · 新接手的服务器,先让 AI 摸底
Node.js异步调用短信API:从同步阻塞到事件循环的工程化实践
AnyPS5跨端串流与输入兼容技术解析:延迟优化与手柄适配实战
PostgreSQL 12 Windows 下 PostGIS 3.4.2 离线部署与避坑指南

今日推荐

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本周热门

UE动画修改实战:从资产编辑到重定向与蒙太奇驱动
统计随机数生成器攻击下的KLJN安全密钥交换协议Matlab仿真
政务API安全治理:资产测绘、低代码编排与行标对标实践

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

YOLO溺水检测实战:339张数据集处理与训练全流程

发布时间:2026/10/11 0:36:41
YOLO溺水检测实战:339张数据集处理与训练全流程 简介这是一份面向目标检测实战的YOLO系列算法溺水数据集共339张图像覆盖溺水、出水、游泳等场景适合yolov5、yolov8、yolov9、yolov10及yolo11等主流版本直接训练与验证。包体共1018个文件每张jpg图像均配套txt格式的YOLO标签和xml格式的VOC标签另含1个yaml配置文件标签采用归一化坐标记录目标框位置与类别索引两种格式分目录存放方便数据格式切换。整个压缩包仅14.6MB数据集已预先划分能有效降低模型复现与对比实验的准备工作量。目前已有303人学习下载尤其适合计算机视觉初学者、算法工程师及水上安全监控项目开发者。借助这份数据可快速完成数据加载、模型微调、精度评估等环节免去自行采集标注的繁琐流程是验证YOLO系列检测性能的实用素材。1. yolo算法做溺水检测数据才是真正的门槛yolo算法做溺水检测最卡人的往往不是模型选型而是数据。这套 339 张带标签的溺水数据集把爬图和人工标注的时间一次省掉了图像、标签、zip 打包在一起解压就能开始做格式整理和训练。它覆盖溺水、出水、游泳三类目标适合拿来做智慧泳池、水库监控的可行性验证也适合学生用最小成本把 YOLO 检测全流程跑通。但要提前说明339 张图只够验证流程撑不起生产级精度。标签口径、类别映射、验证集划分这些坑一个都不会少。2. 打开 zip 先别训练把 339 张图的「家底」摸清楚拿到 zip 的第一反应多半是解压、配环境、直接开训但我建议先花 15 分钟做数据体检。小数据集最大的风险不是模型训不出来而是脏标签把整个训练带偏图与标签对不上、两种标签格式混用、类别字符串和标题对不上号。这些问题在 339 张的量级上靠肉眼根本看不完用几条命令就能查清。2.1 压缩包里到底有什么文件清单与命名规律先建工作目录再解压把 zip 里的大目录结构打平避免后面路径套路径。mkdir -p yolo-drowning cd yolo-drowning unzip ../yolo算法-溺水数据集-339张图像带标签-溺水出水游泳.zip # 看两层目录结构识别 images/labels 或 JPEGImages/Annotations find . -maxdepth 2 -type d | sort # 图像与标签各自的数量这是第一道体检 find . -name *.jpg -o -name *.png | wc -l find . -name *.txt -o -name *.xml | wc -lunzip 之后先 find 目录而不是直接 ls是因为压缩包里除了图像目录往往还藏着 README 或已经划分好的 train/val 子目录这些信息直接影响后面的训练配置。数量对不上是常态常见做法是先把多出来的孤儿图或孤儿标签找出来单独放一边不要急着删。命名规律通常是同名的 .jpg 和 .txt/.xml 一一对应如果压缩包自带 train.txt/val.txt 这样的划分文件后面切验证集能省不少事——但要先确认这份划分和实际文件对得上。如果 find 输出的数量差距明显可以用一个遍历脚本找出具体差集而不是只看到一个总数。# 找没有标签的图假设标签后缀是 .txt for img in $(find . -name *.jpg); do base${img%.jpg} if [ ! -f $base.txt ] [ ! -f $base.xml ]; then echo 缺失标签: $img fi done文件名比对要按完整相对路径做因为不同子目录下可能有同名文件只比对 basename 会误判。缺失标签的图有两种处理方向生成空 txt 文件把它当负样本或者直接删掉取决于你后面是想压制误报还是只想保持训练集干净。2.2 标签是 YOLO 还是 VOC一眼识别与统一口径随便抽一个文件用 head 看内容首行格式立刻见分晓。YOLO 的 txt 每行是 5 列纯数字VOC 的 xml 就是标准 XML 结构里面有 object/name 和 bndbox。head -5 labels/drowning_001.txt # 5 列数字class x_center y_center width height head -30 Annotations/drowning_001.xml # objectnamedrowning/namebndbox...两种格式不能混用这是训练前必须统一的硬前提。YOLO 坐标是相对图像宽高的 0~1 归一化值VOC 是像素绝对坐标同一个框用两种格式表达数值差几十倍。混在一个数据集里模型会同时学到两套坐标系损失曲线直接发散。对比项YOLO txtVOC xml每行内容class x_center y_center width heightobject/name/bndbox 嵌套结构坐标范围0~1 归一化像素绝对值类别表达整数 id字符串读取方式ultralytics 直接读需要 xml 解析我的建议是统一转成 YOLO txt。ultralytics 训练时默认在图像同目录找同名 txt转换一次之后不再依赖解析工具xml 还得写解析脚本出错时多一层黑匣子排查成本高。2.3 类别到底有几个溺水/出水/游泳的标签口径标题写了「溺水出水游泳」三个词但标签里到底有几个类别、类别的 id 对应哪个动作要靠统计而不是猜。这一步是后面类别映射的唯一依据。# YOLO txt 按第一列统计类别 id 分布 cat labels/*.txt | awk {print $1} | sort -n | uniq -c # VOC xml 按 name 文本统计 grep -h name Annotations/*.xml | sed s/.*name\(.*\)\/name.*/\1/ | sort | uniq -c统计结果会告诉你三件事类别总数是不是 3如果出现 0、1、2 之外的 id说明格式并不干净如果 xml 里的 name 是 person、swimmer 这类字符串就要在转换脚本里做一次字符串到 id 的映射。只拿到 id 列表还不够最好随机抽 10 张图人工确认类别名对应关系——我见过数据包的标注把「出水」标成「游泳」训练完混淆矩阵里这两类互相打架调参根本调不好。2.4 图像质量与分辨率339 张里有多少能直接用目标检测对图像分辨率不挑剔但一个训练集里混着 320 的小图和 1920 的大图YOLO 统一 resize 到 imgsz 时会产生不少失真样本。用 python 快速统计宽高分布心里先有个底。from PIL import Image from pathlib import Path imgs list(Path(images).glob(*.jpg)) sizes {} for p in imgs: with Image.open(p) as im: w, h im.size # 按 100 像素分桶避免散点干扰判断 key (w // 100 * 100, h // 100 * 100) sizes[key] sizes.get(key, 0) 1 for k, v in sorted(sizes.items()): print(f{k[0]}x{k[1]}: {v} 张)这段脚本把分辨率压到 100 像素的档位再统计一眼就能看出主流分辨率。如果绝大多数是 1920x1080训练时 imgsz 用 640 会让溺水的人形目标缩得很小如果混着一批 320x240imgsz 用 640 又会拉伸糊掉。合理做法是按主流分辨率定 imgsz把离群图离线缩放到主流分辨率附近而不是丢给 YOLO 在线 resize 硬扛。另一个容易被忽略的是重复图。爬虫采集的数据集常有连拍或重复下载重合度高的图在训练里被反复计入验证集里也会虚高。先用 md5 查一遍。md5sum images/*.jpg | awk {print $1} | sort | uniq -d | wc -l到这里格式、类别、分辨率三个底数基本摸清。这些信息是第 3 章转换脚本和第 4 章训练参数的直接输入跳过这一章直接训练大概率会在中间某个环节返工。3. 把标签统一成 YOLO txt类别映射与坐标转换脚本不管压缩包里原本是 xml 还是乱序的 txt训练前都要统一成「类别 id 从 0 开始、每行 5 列、坐标 0~1 归一化」的标准 txt。这一步看着简单实际是溺水检测数据里翻车最频繁的地方类别名拼写不一致、坐标越界、标签文件对不上。下面给出可以直接复制进项目用的转换脚本。3.1 确定类别顺序0 是溺水还是游泳得先定死类别顺序一旦写进数据集 YAML整个训练产物的读取就依赖它。后面生成的 best.pt、混淆矩阵、每个类别的 PR 曲线全部按这个顺序对齐中途改动等于重训。先约定一个常见顺序也给出每个类可操作的判断标准。id类别判断标准0drowning头部在水面以下或大量呛水身体姿态失控1emerging头部刚露出水面手在扑腾处于出水瞬间2swimming正常泳姿头部有规律地浮出换气实际标签里可能是别的顺序转换脚本里的 CLASS_MAP 按压缩包的真实内容改即可。关键是先定死再写代码不要边写边改。3.2 从 VOC xml 到 YOLO txt坐标归一化转换脚本import xml.etree.ElementTree as ET from pathlib import Path # 类别映射xml 里的 name 文本 - 训练 id顺序按 3.1 节定义 CLASS_MAP {drowning: 0, emerging: 1, swimming: 2} def convert_xml(xml_path: Path, out_dir: Path): tree ET.parse(xml_path) root tree.getroot() # 宽高从 xml 的 size 节点取不要重新读图 # 否则遇到 exif 旋转或批量裁剪过的图坐标会全部错位 size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.findall(object): name obj.find(name).text if name not in CLASS_MAP: print(f[skip] 未映射类别: {name} in {xml_path.name}) continue cls_id CLASS_MAP[name] box obj.find(bndbox) x1 float(box.find(xmin).text) y1 float(box.find(ymin).text) x2 float(box.find(xmax).text) y2 float(box.find(ymax).text) # 左闭右开不做 1/-1避免不同标注工具的口径差异 x_center (x1 x2) / 2 / w y_center (y1 y2) / 2 / h bw (x2 - x1) / w bh (y2 - y1) / h lines.append(f{cls_id} {x_center:.6f} {y_center:.6f} {bw:.6f} {bh:.6f}) out_path out_dir / (xml_path.stem .txt) out_path.write_text(\n.join(lines)) xml_dir Path(Annotations) out_dir Path(labels) out_dir.mkdir(exist_okTrue) for xml_file in xml_dir.glob(*.xml): convert_xml(xml_file, out_dir)坐标保留 6 位小数在 640 输入下误差远小于一个像素不需要更高精度。未映射类别先打印跳过而不是抛异常跑完数一下 skip 的数量就知道有多少脏标签要人工回放。x_center 用(x1 x2) / 2 / w而不是拆开两次除法两种写法数学等价但前者只在最后除一次浮点误差小一些。输出文件名用xml_path.stem保证和 jpg 同名。3.3 如果标签本来就是 YOLO txt重映射与脏数据清洗压缩包里直接给 txt 的情况下也别以为能直接训练。常见问题包括类别 id 从 1 开始而不是从 0 开始坐标出现大于 1 或小于 0 的越界某几行只有 3 列或 4 列。这些脏数据用命令行就能洗一遍。# 把 id 从 1~3 平移到 0~2并过滤掉越界行 awk { if ($1 1 $1 3 $2 0 $2 1 $3 0 $3 1 $4 0 $4 1 $5 0 $5 1) { print $1-1, $2, $3, $4, $5 } } labels_raw/*.txt labels/clean.txt这段 awk 对每行做「类别范围 坐标范围」双检查符合条件的输出平移后的新 id其他行静默丢弃。越界坐标宁可直接丢也不要带进训练——归一化坐标大于 1 的框会让损失函数在前期算出异常大的值拖慢收敛。输出文件要单独放目录不要覆盖原始标签后面排查时还要回看原始数据。命令行过滤有一个局限它不关心同一张图是否存在同名标签文件。清洗完之后补一步数量核对。for f in images/*.jpg; do b${f##*/}; b${b%.jpg} [ ! -f labels/$b.txt ] echo $b 缺标签 done缺标签的图有两个处理方向生成空 txt 文件把这张图当作纯负样本适合压制「无人水域误报」直接删图保持训练集干净。对溺水检测我会保留一部分空背景图当负样本后面第 4 章的 YAML 里还能用它们做验证集一举两得。4. 用 YOLOv8 把溺水模型跑起来数据集 YAML 与三个关键超参339 张图属于典型的小样本检测模型选型和超参设置比大数据集敏感得多。用 YOLOv8n 这种轻量骨架是稳妥起点nano 系列本身只有约 300 万参数在小数据上不容易一开始就过拟合。下面给一份能直接跑通的 YAML 和训练命令再教你读懂训练日志。4.1 数据集 YAML 的写法与路径坑ultralytics 的数据集描述文件是训练前必须写对的东西。最常见翻车点是 path 用相对路径然后换了一个工作目录运行整个数据集找不到。我一般直接在 path 写绝对路径。# dataset.yaml path: /home/you/projects/yolo-drowning # 改成你自己的绝对路径 train: images val: images # 还没切验证集时先指向训练集只用于跑通流程 test: # 留空即可 names: 0: drowning 1: emerging 2: swimmingtrain 和 val 的值可以是目录名也可以是 txt 文件路径列表目录名相对 path 解析。val 先指回 images 只在第一轮跑通时用原因后面第 5 章会细讲一旦用训练集当验证集调参验证指标就不再代表真实水平。yaml 里不要写 download 字段小数据集没必要触发下载逻辑省得联网失败报一堆无关错误。names 的数量必须和标签里最大的类别 id 1 对齐少一个都会在读取时报 label shape 错误。提示dataset.yaml 改完后先跑一个 epochs1 的训练观察数据加载阶段的日志确认标签被正确读取后再正式训练。这个习惯能省掉大量无效等待。4.2 训练命令与最小参数yolo detect train \ datadataset.yaml \ modelyolov8n.pt \ imgsz640 \ epochs80 \ batch8 \ workers4 \ optimizerSGD \ lr00.01 \ patience10 \ projectruns/drowning \ nameexp_v1逐参数说明modelyolov8n.ptnano 版339 张图用 s 或 m 会在十几个 epoch 后就开始过拟合n 先跑通再考虑放大。imgsz640默认值适合大多数监控画面。如果第 2.4 节统计发现主流分辨率偏低降成 320 省显存溺水目标普遍很小才用 960。epochs80小数据集建议 80 起步配 patience10 早停。数据集再小也不建议低于 50否则损失还没收敛就停了。batch8取决于显存。12G 的卡跑 yolov8n 可以到 168G 就乖乖用 8。workers4数据加载进程数。Windows 上偶尔会因为 num_workers 报错改成 2在 AGX Orin 这类嵌入式设备上workers 太高反而拖慢整体速度。optimizerSGD小数据下 SGD 比 Adam 稳Adam 前期收敛快但容易记住噪声。lr00.01SGD 常用起点训练日志显示 loss 剧烈震荡时减半。这组参数不是最优而是「不会翻车」的起点。先跑通一次再往目标方向调。第一次跑通后我会优先动两个地方imgsz 和类别损失权重而不是盲目加 epochs。4.3 训练日志怎么看loss 降不下去不代表数据差训练过程的黑匣子就是每轮打印的 loss 曲线。YOLOv8 的损失函数由三个分量组成box_loss 负责预测框和真值框的 IoU 误差cls_loss 负责分类置信度dfl_loss 负责框的分布建模。三个分量一起降说明模型在正常学只降 box 不降 cls基本可以断定类别映射或数据不均衡有问题。看日志也有技巧。前 20 个 epoch 内损失曲线不是直线下降而是有波动这是正常的但如果 30 个 epoch 后 cls_loss 仍在一个高位原地抖动优先检查标签而不是加大学习率。小数据集上最隐蔽的问题是模型把背景错当成目标又没在损失里体现出来——这时要结合验证集 PR 曲线看而不是只看训练 loss。遇到 loss 数值异常偏大先把 imgsz 调到和图像分辨率接近再试在线 resize 太狠会把损失曲线带歪。5. 溺水数据集训练的 5 个常见坑与排查办法小数据集训练遇到的问题七成和模型无关而是数据与配置的「脏」。按踩坑频率排序下面五条基本覆盖了 339 张这种量级的典型事故。5.1 训练报错 label shape连第一个 epoch 都进不去现象ultralytics 启动后打印 label 信息时报错提示 label shape 不是 (N, 5)。原因标签列数不对或者类别 id 超过 names 数量。常见于 xml 转换脚本漏了归一化、原始 txt 里混了 4 列数据。解决先用统计命令定位坏文件。# 查看列数分布 awk {print NF} labels/*.txt | sort | uniq -c # 查看最大类别 id awk {print $1} labels/*.txt | sort -n | tail -1看到有文件列数不是 5用 grep 找出具体文件名回到转换脚本重新处理id 最大值大于等于 names 数量说明类别映射没做干净。这类问题排查从不超五分钟因为统计命令把可疑范围缩得很小。5.2 mAP 虚高验证集和训练集来自同一批连续帧现象训练完 val 的 mAP50 能到 0.9拿真实泳池视频一测框乱飘溺水的人完全检不到。原因339 张图里大量是同一场景的连续帧随机切分时同一段连续帧同时进了训练集和验证集模型等于见过答案再考试。加上 4.1 里 val 指向 images指标虚高更严重。解决按「场景」而不是按「单张图」切分同一段连续帧只能落在一侧。假设文件名里有场景编号先用前缀分组再对组做随机 8:2 划分。# 提取场景前缀假设命名是 scene_001_0001.jpg 这类再去重 ls images/*.jpg | sed s/.*\///; s/_[0-9]*\.jpg// | sort -u scenes.txt # 从场景列表里随机抽 20% 作为验证场景 shuf -n $(($(wc -l scenes.txt) * 2 / 10)) scenes.txt val_scenes.txt保证验证集里出现的地点人物训练集没看过mAP 才有参考价值。如果文件名没有场景编号只能靠录制的连续性人工分组麻烦但躲不掉。5.3 类别极度不均衡游泳框占七八成溺水框只有个位数现象训练日志里 cls_loss 降得慢验证集每个类别的 AP 差距巨大溺水那类 AP 接近 0。原因339 张图的类别分布天然不均衡溺水本身是罕见事件标注框自然少。模型学到的最优策略是全预测成游泳因为这样总体损失最小。解决先看 2.3 的统计结果如果溺水框占比低于 10%优先放大少数类的影响。ultralytics 的 YAML 里没有现成的类别权重字段常见做法是自定义 loss 或在数据侧做类别重采样我一般倾向先做离线增强专门把溺水目标抠出来贴到没有目标的泳池背景图上每次贴 2~3 个目标生成 50~100 张增强图。注意贴图时目标大小要与原图目标比例匹配否则学到的全是异常尺度推理时对真实尺度反而失灵。5.4 drowning 和 emerging 互相混淆标注口径不一致现象验证集的混淆矩阵里drowning 和 emerging 这两个类别互相认错比例高达三四成。原因标注阶段对「溺水」和「出水」的判断标准不统一同一个动作有人标 0 有人标 1。解决回到标签源头定死规则头部在水面以下算 drowning头部刚露出且手在挣扎算 emerging。标注完再抽 20 张图做一致性复核。如果项目周期短到没法复核把两个类合并成一个 danger 类先保证检出率再谈细分。这种合并损失的是类别多样性但溺水检测业务里漏检比错分危险得多。5.5 显存不够batch16 直接 CUDA OOM现象训练启动后几秒内报 OutOfMemory或者显卡几乎满载导致系统卡死。原因imgsz 和 batch 的乘积超出显存Jetson 之类设备上还要算上数据加载进程占的内存。解决换小 batch 或让 ultralytics 自动探测一个可用 batch。# 自动探测可用 batch yolo detect train datadataset.yaml modelyolov8n.pt imgsz640 batch-1显存推荐 batch备注8G8不推荐开 mosaic 之外的增强12G163060/4070 级别常见24G32可以换 yolov8s 试在 AGX Orin 这类嵌入式设备上除了调小 batch还要把 workers 降到 2不然 CPU 数据加载会成为瓶颈。更省显存的做法是 imgsz 降到 480效果和 640 差别不大训练速度却快一截。6. 339 张图的模型怎么验收留出法、测试视频与一个小目标增强验证不等同于跑一次 val 命令。我的习惯是三层验收第一层用严格切分的验证集算 mAP第二层拿一段模型没见过的真实泳池视频做冒烟测试第三层才回到训练集里数错检样本。# 验证集评估按类看 AP yolo detect val \ datadataset.yaml \ modelruns/drowning/exp_v1/weights/best.pt \ imgsz640 \ conf0.25重点看每个类别的 AP而不是总和。溺水这类少数类 AP 如果明显低于游泳回到 5.3 做类别加权或增强。盯同一个目标误报宁可少一个漏检必须为零。339 张图训出来的模型我一般不会直接上线而是带着现场视频回到标注工具把最容易误报的帧水花、波光、泳镜反光补成负样本跑第二轮。这个循环跑两三次比换更大的模型有效得多。数据增强的优先级也要调整mosaic 对小目标有奇效但溺水的人常常只有几十像素mosaic 会把它切碎这时候关掉 mosaic改成离线放大目标区域再训练或者用 imgsz960 保持目标分辨率。如果后续要区分泳姿可以往 YOLO 实例分割方向走但那是数据量翻几倍之后的事现在这个阶段先把检测做稳。yolo算法做溺水检测数据的真实程度决定模型上限。我第一次拿这套数据时图省事没做类别重映射训练没报错但 metrics 一塌糊涂事后查是标签 id 对错了位血泪经验。后来老老实实把第 5 章的坑一个个过掉溺水类 AP 才从 0.2 拉到 0.7。这份 339 张的数据集适合用来建立基准和验证流程真正要落地还是得往里面补自己场景的视频帧。希望帮到你。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号