YOLOv11室内耳朵检测数据集:209张图训练与推理全流程解析
发布时间:2026/10/2 4:01:38来源:尧图网络
简介面向YOLOv5、YOLOv7、YOLOv8、YOLOv11等系列目标检测算法的室内人脸耳朵检测数据集共包含四百二十一个文件压缩包大小约八点六七兆字节。其中二百一十一张JPG图像与二百零九个TXT标注文件一一对应标签类别统一为耳朵另含一个YAML配置文件已预先完成训练集、验证集等划分下载后按YOLO格式放置即可直接用于模型训练。数据集采集自室内人脸场景适用于安防监控、人机交互、姿态分析等实际应用也适合目标检测初学者快速熟悉YOLO数据组织流程与训练调参方法。目前已有十四人学习下载可作为实验教学、毕业设计或算法效果对比的基准数据。资源内置配置文件并划分好数据省略了手动整理标签与拆分数据集的环节能帮助使用者更快启动训练、验证检测效果尤其适合需要快速搭建耳朵检测任务的开发者。1. YOLOv11室内耳朵检测数据集209张图像怎么训练出目标检测模型目标检测项目里最难拿到的往往不是模型代码而是干净、能直接喂给网络的标注数据。这份YOLOv11室内人脸耳朵目标检测数据集一共209张图像标注类别只有“耳朵”一个class压缩包解压后是标准的YOLO格式目录适合做训练、微调和算法验证。209张确实不算多但如果按小数据集的节奏来处理配合数据增强和合理的训练参数足够跑通一个能用的耳朵检测器。它解决的是这类场景人像近景中耳朵区域的定位比如耳机佩戴检测、耳部特征分析、注意力判断、人脸遮挡评估。适合刚接触目标检测数据集的初学者也适合需要快速验证YOLOv11在自己业务数据上效果的从业者。接下来我从数据结构、标注解析、训练配置到推理验证完整拆一遍。2. 数据集结构与YOLO格式解析先看懂每一行数字再动手2.1 解压后的目录与文件清单拿到数据集压缩包后先不要急着开训练。把目录结构理清楚确认images和labels是否对齐。常见解压后是这样组织datasets/ears/ ├── images/ │ ├── train/ │ │ ├── ear_001.jpg │ │ └── ... │ └── val/ │ ├── ear_002.jpg │ └── ... ├── labels/ │ ├── train/ │ │ ├── ear_001.txt │ │ └── ... │ └── val/ │ └── ear_002.txt ├── classes.txt └── data.yaml如果拿到的包没有按train/val分开就需要自己划分。我一般会先跑一个脚本统计每个目录下图片和txt文件数量是否一致确保没有“图片存在、标注缺失”的情况find datasets/ears/images -name *.jpg | wc -l find datasets/ears/labels -name *.txt | wc -l两个数字对不上说明有掉标注的图片这类样本训练时会被YOLO当背景图处理影响不算致命但如果掉得多了会拉低召回率。2.2 标注内容逐行拆解YOLO格式的标注文件每一行是五个数字0 0.4526 0.3821 0.1264 0.1715从左到右依次是类别id0代表耳朵、归一化后的边界框中心点x、中心点y、框宽度w、框高度h。所有坐标都除以了原始图片的宽高值域在0到1之间。注意这里不是左上角坐标而是中心点加宽高。写个Python脚本检查所有标注是否合法重点看有没有越界、负数、宽度高度为0的情况import os from pathlib import Path label_dir Path(datasets/ears/labels/train) # 单类别数据集的合法class_id范围是0如果类别数量变化按实际修改 valid_ids {0} problems [] for txt in sorted(label_dir.glob(*.txt)): # 空文件代表该图像没有目标属于背景样本单独记录不报错 if txt.stat().st_size 0: continue with open(txt, encodingutf-8) as f: lines f.readlines() for idx, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: problems.append(f{txt.name} 第{idx 1}行字段数异常: {line.strip()}) continue cls_id, cx, cy, w, h parts cls_id, cx, cy, w, h int(cls_id), float(cx), float(cy), float(w), float(h) # 归一化坐标合法范围是[0,1]宽高必须是正数 if cls_id not in valid_ids: problems.append(f{txt.name} 类别id越界: {cls_id}) if not (0 cx 1 and 0 cy 1): problems.append(f{txt.name} 中心点越界: cx{cx}, cy{cy}) if not (0 w 1 and 0 h 1): problems.append(f{txt.name} 宽高越界: w{w}, h{h}) if problems: print(f发现 {len(problems)} 个问题:) for p in problems[:50]: print(p) else: print(标注检查通过)这段脚本的作用是把YOLO标注里的数值合法性全部扫一遍重点服务于后续训练稳定性。实际使用时如果发现某个txt文件的行数大于图像中可见耳朵数量多半是标注时框到了头发或者背景区域要么删除要么重标。2.3 把标注可视化出来才能发现问题数值检查只能发现格式错误发现不了框得准不准。更实用的做法是写可视化脚本把边界框画回原图上逐张翻看import cv2 from pathlib import Path image_dir Path(datasets/ears/images/val) label_dir Path(datasets/ears/labels/val) out_dir Path(visual_check) out_dir.mkdir(exist_okTrue) for img_path in sorted(image_dir.glob(*.jpg)): image cv2.imread(str(img_path)) h, w image.shape[:2] label_path label_dir / (img_path.stem .txt) if not label_path.exists(): continue with open(label_path, encodingutf-8) as f: for line in f: parts line.strip().split() if len(parts) ! 5: continue cls_id, cx, cy, bw, bh parts cx, cy, bw, bh float(cx), float(cy), float(bw), float(bh) # 反归一化从中心点坐标转为左上角、右下角整数坐标用于绘图 x1 int((cx - bw / 2) * w) y1 int((cy - bh / 2) * h) x2 int((cx bw / 2) * w) y2 int((cy bh / 2) * h) color (0, 255, 0) cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) cv2.putText(image, fear_{cls_id}, (x1, max(0, y1 - 5)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, color, 1) cv2.imwrite(str(out_dir / img_path.name), image) print(f可视化结果已保存到 {out_dir})反归一化时最容易犯的错是直接用cx乘以宽度当作左上角坐标必须减掉半宽。可视化之后我会快速翻一遍图重点看三件事耳朵是否完整落在框内、左右耳是否都标了、框有没有把脸颊或头发大面积包进去。209张图翻起来也就几分钟但能避免后面训练完才发现数据质量不行。2.4 划分训练集与验证集如果压缩包里已经分好了train/val直接用即可。如果没分建议按8:2划分且划分时优先保证同一个人的多张图像不要全部进入验证集否则训练时模型已经见过这个人验证结果虚高python - EOF import random from pathlib import Path random.seed(42) image_dir Path(datasets/ears/images) all_images sorted(image_dir.glob(*.jpg)) random.shuffle(all_images) val_ratio 0.2 val_count int(len(all_images) * val_ratio) # 前80%训练后20%验证按此修改目录或生成索引文件 print(f训练集 {len(all_images) - val_count} 张验证集 {val_count} 张) EOF划分完成后还要同步移动对应的txt文件不能只把图片分成两份而labels不跟着走。单类别数据集的验证集不需要刻意做类别均衡但要注意耳朵姿态的覆盖比如侧脸、正脸、戴耳机遮挡的情况都要有一定比例。3. 训练配置与参数设置209张图像怎么调YOLOv113.1 准备工作安装环境与网络权重YOLOv11在ultralytics框架中对应的是yolo11系列安装依赖和准备权重是第一步pip install ultralytics yolo predict modelyolo11n.pt sourcedatasets/ears/images/val/ear_002.jpg第二条命令是为了让框架自动下载预训练权重到本地缓存。小数据集建议从预训练权重继续训练而不是从头初始化因为COCO上学习到的通用特征能显著降低对数据量的需求。耳朵检测这类任务和COCO中的人体、头部语义接近受益明显。3.2 编写dataset.yaml在数据集根目录写一个data.yaml指定路径和类别信息# 数据集根目录用绝对路径最省心 path: /path/to/datasets/ears train: images/train val: images/val # 单类别类别名称列表和实际标注文件里class_id一一对应 names: 0: ear这里有个细节如果数据集没有划分val目录可以把val指回train目录但这样验证指标会失真。更合理的做法是从训练集里抽一部分出来单独建val目录不要偷懒复用train。YOLO训练时如果val目录不存在框架会用train数据做验证跑出来的精度没有任何参考价值。3.3 训练命令与关键参数解读209张图的数据量决定了两件事模型不要选太大的epoch不要设太少。我用的命令如下yolo detect train \ data/path/to/datasets/ears/data.yaml \ modelyolo11s.pt \ epochs200 \ imgsz640 \ batch16 \ patience30 \ optimizerauto \ lr00.005 \ projectruns/ears各参数的取舍逻辑列在下面这张表里参数推荐值原因modelyolo11s.pt小数据集用large或x模型很容易过拟合s版本参数量适中训练速度快epochs200209张图的迭代不宜太短配合早停机制模型能充分收敛imgsz640标准分辨率与预训练权重输入尺寸一致迁移效果最好batch16每张显卡一次处理的样本量显存不够可以降到8patience30验证集mAP连续30轮不提升就停止训练省时间optimizerauto框架自动选择SGD或AdamW小数据集上通常稳定lr00.005比默认值稍低避免小数据量下Loss震荡epoch并不是越大越好。200轮看起来多但配合patience30通常在80到120轮左右就会触发早停。如果发现训练集mAP升到0.9以上而验证集停在0.5附近波动说明过拟合了此时优先考虑加数据增强而不是继续加大epoch。3.4 数据增强如何开YOLOv11内置了多种增强方式在训练参数里直接控制yolo detect train \ data/path/to/datasets/ears/data.yaml \ modelyolo11s.pt \ epochs200 \ imgsz640 \ batch16 \ patience30 \ hsv_h0.015 \ hsv_s0.7 \ hsv_v0.4 \ degrees10 \ translate0.1 \ scale0.5 \ flipud0.0 \ fliplr0.5参数含义逐个说来hsv_h、hsv_s、hsv_v分别控制色相、饱和度、亮度的随机扰动幅度室内灯光条件下适度调节能提升模型对不同光照的适应性degrees10表示每张图有10度的随机旋转耳朵检测不需要大角度旋转10度足够translate0.1允许图像平移10%的像素范围scale0.5控制缩放倍数。flipud设为0因为耳朵上下翻转没有物理意义fliplr保留0.5的水平翻转左右耳特征对调后仍然有效同时相当于把训练样本翻了一倍。注意翻转对标注的影响YOLO格式的归一化坐标在水平翻转后中心点x会变成1 - cx框架内部会自动处理不需要手动改标注文件。4. 推理验证与保存结果从weights到可视化预测4.1 训练产物解读训练结束后runs/ears目录下会生成多个文件最常用的是这两个权重best.pt和last.pt。best是验证集上mAP最高的一次保存last是最后一轮保存。千万不要图省事直接用last小数据集上最后一轮很可能已经过拟合实际表现不如best。我在工程里做了个规定上线推理一律使用best.pt除非手动验收过last的指标。先跑一次验证看模型在200张数据上到底学到了什么yolo val \ data/path/to/datasets/ears/data.yaml \ modelruns/ears/weights/best.pt \ splitval输出结果里的关键指标抓两个看mAP50衡量框位置和类别判定的综合表现单类别小数据集上正常值应该在0.85以上mAP50-95是更严格的标准对框的贴合度要求更高0.5到0.7属于合理区间。如果mAP50低于0.7大概率是标注质量或数据量问题先回头检查可视化结果。4.2 对单张图片和视频做推理并保存推理和保存结果的代码写起来很短但有几个参数容易被忽略from ultralytics import YOLO # 加载训练好的权重 model YOLO(runs/ears/weights/best.pt) # source可以是图片文件、目录、视频流框架自动识别 results model.predict( sourcedatasets/ears/images/val, conf0.25, # 置信度阈值低于此值的检测框会被过滤 iou0.45, # NMS的IoU阈值两个框重叠超过此值会保留分数更高的 imgsz640, saveTrue, # 保存标注后的图像 save_txtTrue, # 把预测结果输出为txt文件格式与训练标注一致 save_cropTrue, # 裁剪出检测到的耳朵区域单独保存成小图 projectruns/predict, nameears_val ) # 逐图读取预测框坐标方便二次开发 for r in results: boxes r.boxes.xyxy.cpu().numpy() # 左上角右下角坐标像素单位 confs r.boxes.conf.cpu().numpy() # 置信度数组 for box, conf in zip(boxes, confs): x1, y1, x2, y2 [int(v) for v in box] print(fear at ({x1}, {y1})-({x2}, {y2}), confidence{conf:.2f})conf0.25在室内干净背景下够用如果后续要部署到视频流并追求低漏检可以降到0.1代价是误检变多通常再加一层面积过滤兜底。save_cropTrue是个容易漏掉的参数但做数据筛选和后期清洗时非常有用能把检测到的耳朵批量导出来直接用来扩充别的任务。4.3 推理结果留存为结构化文件调试阶段看图片够了但做效果评估时最好把详细信息导出成表格方便按置信度排序找坏例。框架输出的predictions.csv可以配合脚本转成方便阅读的形式或者直接在代码里组织数据import csv rows [] for r in results: # 从results对象中提取每帧的路径、检测框、置信度 frame_path r.path boxes r.boxes.xyxy.cpu().numpy() confs r.boxes.conf.cpu().numpy() for box, conf in zip(boxes, confs): rows.append([frame_path, *[round(v, 2) for v in box], round(float(conf), 3)]) with open(runs/predict/ears_val/predictions.csv, w, newline) as f: writer csv.writer(f) writer.writerow([image_path, x1, y1, x2, y2, confidence]) writer.writerows(rows)输出CSV之后用Excel或者pandas按置信度升序排列就能把模型最没把握的样本捞出来人工复核。我一般看两类置信度低但确实有耳朵的这说明训练数据里缺少这类姿态置信度高但实际没耳朵的这是误检需要把对应图片单独拉出来做难例挖掘。5. 避坑排查小数据集训练YOLO的五个典型翻车现场5.1 训练Loss一直降但验证集几乎检测不到耳朵现象训练集上loss曲线平滑下降precision和recall都逼近0.95但拿到验证集图片一测大部分耳朵没被框出来。原因数据划分时训练集和验证集存在分布差异或者训练集里某些图片的姿态在验证集里占比过高模型实际上记住了训练图的背景特征。另一个常见原因是验证集里耳朵目标占比太小imgsz640下小耳朵只有几十个像素模型学到的特征无法泛化。解决先做一次分层抽样把同一个场景、同一个人的多张照片按比例同时分配到训练和验证集避免某一类姿态只出现在一个集合里。再把imgsz从640提高到960小目标在放大后特征更容易被网络捕获。5.2 Mosaic增强导致小目标消失现象开启Mosaic后训练集mAP很高但验证集表现差而且单独针对耳朵目标的召回率极低。原因Mosaic会把四张图拼成一张拼图过程中会随机裁剪裁剪掉的部分如果恰好包含小目标区域该目标的标注在增强后就不再有效。209张的小数据集里一个样本失效就意味着损失约0.5%的数据。解决训练后期关闭MosaicYOLOv11支持在训练过程中动态调节yolo detect train \ data/path/to/datasets/ears/data.yaml \ modelyolo11s.pt \ epochs200 \ imgsz640 \ batch16 \ patience30 \ mosaic0.5mosaic0.5表示每轮只有一半样本启用Mosaic。小数据集上我建议从0.5起步而不是默认的1.0。也可以用框架的close_mosaic参数在最后10个epoch自动关闭让模型在更接近真实分布的数据上收敛。5.3 标注框一半压在头发上模型框出来的也偏大现象推理结果里检测框总是包含耳朵周围一大圈头发mAP50看着不低但框和真实耳朵边缘不贴合。原因原始标注本身就不够紧标注员把头发、耳廓外围一起框进去了。YOLO的回归目标学习的是标注框标注框不紧模型学出来的自然不紧。解决把之前可视化检查里发现的问题标注重新拉一遍。如果不想人工改全部一个折中方案是训练时把标注框统一缩小5%到10%在读取训练数据时做一次坐标变换import cv2 from pathlib import Path # 调整单个txt文件里的标注框收缩比例shrink_ratio def shrink_labels(txt_path, shrink_ratio0.1): with open(txt_path, encodingutf-8) as f: lines f.readlines() new_lines [] for line in lines: parts line.strip().split() if len(parts) ! 5: continue cls_id, cx, cy, w, h parts cx, cy, w, h float(cx), float(cy), float(w), float(h) # 宽度和高度同时缩小中心点保持不变 nw w * (1 - shrink_ratio) nh h * (1 - shrink_ratio) new_lines.append(f{cls_id} {cx} {cy} {nw:.6f} {nh:.6f}\n) with open(txt_path, w, encodingutf-8) as f: f.writelines(new_lines)收缩比例超过0.15容易让框边界越过耳朵边缘丢失部分耳廓特征压缩包里的标注质量不同建议先收缩0.1跑一轮看结果再说。5.4 训练过程中显存溢出现象batch16跑得好好的换到batch32或者imgsz960直接OOM程序退出。原因显存占用和imgsz的平方成正比从640升到960单张图占用的显存翻了一倍多batch也要相应减半。解决参考这个组合调整imgsz960时batch降到8如果还溢出就降到4。另一种做法是用梯度累积来模拟更大的batch但小数据集上梯度累积带来的稳定性提升不明显优先降低batch更直接。5.5 验证集mAP高但换个摄像头效果崩掉现象训练集和验证集都是用同一个相机拍摄的室内照片mAP50达到0.95。换一个角度或者换一个摄像头拍漏检率明显上升。原因数据集本身采样局限209张图里如果有超过半数来自同一个机位、同一个背景模型会无意中学会依赖背景特征。耳朵检测在这种场景下尤其容易受影响因为耳朵在脸部区域占的像素比例不大。解决如果短期内拿不到更多数据用数据增强模拟不同视角把degrees从10提高到20translate从0.1提高到0.2scale从0.5提高到0.7。同时在验证时多留一批“从未见过”的图像不要只在val目录里测。6. 进阶把增强与小目标优化用到极限在小数据集上追求更好效果方向有两个一是把现有数据榨干二是针对耳朵的小目标特性调网络输入。先说增强组合。ultralytics除了CLI参数还支持在Python里直接定义增强流水线。我通常会把亮度、对比度和轻微模糊叠加起来使用from ultralytics import YOLO model YOLO(yolo11s.pt) results model.train( data/path/to/datasets/ears/data.yaml, epochs200, imgsz640, batch16, hsv_h0.02, hsv_s0.8, hsv_v0.5, degrees15, translate0.15, scale0.6, fliplr0.5, mosaic0.5, erasing0.1, # 随机遮挡部分区域逼迫模型学耳廓本身 mixup0.1 # 样本混合增强小数据集单类别场景下有效 )erasing0.1会随机擦除图像中的一小块矩形区域如果擦到了耳朵附近模型不能只靠局部纹理识别还得依赖整体位置信息。mixup0.1两张图按比例混合成一个训练样本单类别下相当于把不同姿态的耳朵特征做了插值。再说小目标优化。耳朵在640分辨率下如果只占二三十个像素检测头的高层特征图上几乎没人任何响应。最直接的办法是加大imgsz到960或者1280推理时保持和训练一致。这笔显存开销换来的收益通常比更换模型结构更大。另外可以用SAHI这类切图推理工具把大图切成多个小块分别推理再合并适合耳朵目标密集分布的场景。YOLOv11的特征融合对不同尺度目标都有覆盖但小目标对框的回归偏差更敏感。如果验证集mAP50-95明显低于mAP50说明框的贴合度还有提升空间。此时我一般会检查标注框是否紧贴耳廓边缘再决定是否收缩标注框重训。作为收尾的教训每次拿到新的小数据集我都会强制走一遍“可视化检查标注 → 脚本校验坐标 → 分层划分数据 → 跑一轮baseline → 再看bad case”的流程不做完不碰训练参数。这个流程帮我挡掉过很多次标注错位、数据泄露、分布偏差的坑。209张图不多但只要每个环节都较真训练出来的模型在真实场景里同样能打。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网