☰
男女性别检测数据集VOC+YOLO格式9769张2类别实战指南
2026/10/1 13:25:44 网站建设 项目流程

简介:本数据集面向计算机视觉开发者与性别识别模型训练者,提供男女性别二分类检测所需的标注数据,适用于目标检测算法训练、模型微调与教学实验等场景。资源采用Pascal VOC与YOLO双格式组织,包含9769张jpg图片,并配套等量的xml标注文件与yolo格式txt文件,标注类别为Female与Male两类,其中Female框数5491、Male框数4308,总框数9799,全部由labelImg工具按矩形框规则完成标注。压缩包为7z格式,共2000个文件,以1999个xml标注文件和1个说明txt为主,整体约104.49MB,目录结构清晰,便于直接接入常见检测框架。目前已有349人学习下载,适合需要快速获取性别检测标注数据、开展训练与验证的读者参考使用。

1. 男女性别检测数据集 VOC+YOLO 格式:9769 张 2 类别,拿到手怎么用

如果你正在做一个「看图识人」的活儿——比如门店客流分析、智能相册自动归类、或者安防场景里先判断画面里的人是男是女,再决定后续走哪条业务逻辑——那你大概率绕不开一个现实问题:公开的、标注干净的、能直接喂给 YOLO 的性别检测数据集,其实没那么多。这个标题里的东西,说白了就是一份已经整理好的性别二分类检测数据集,9769 张图,VOC 和 YOLO 两种标注格式都给了,类别就两个:male 和 female。

它的价值不在于「大」,而在于「省事」。VOC 格式的 XML 适合拿来做数据审查、可视化、转其他框架;YOLO 格式的 txt 可以直接丢进 ultralytics 系的训练脚本。你不需要自己从零爬图、标框、清洗、划分,拿到压缩包解压完就能开始跑 baseline。适合谁?适合想快速验证性别检测可行性的人、适合拿它做课程设计或原型 demo 的开发者、也适合把它当预训练数据再往自己业务场景上微调的工程师。但要注意,9769 张不算大,2 类别也不算复杂,别指望它直接产出工业级精度,它的定位是「起步燃料」。

2. 先搞清楚 VOC 和 YOLO 两套标注到底差在哪

2.1 VOC XML 的结构与字段含义

VOC 格式的核心是一个图对应一个 XML 文件,文件名通常和图片同名。里面最关键的是<object>节点,每个目标一个,包含<name>(类别名)、<bndbox>(左上右下坐标)。坐标是绝对像素值,原点在左上角。这种格式的好处是可读性强,用任何文本编辑器打开都能看懂,坏处是解析慢、文件多、不适合大规模训练直接读。

<annotation> <folder>images</folder> <filename>000001.jpg</filename> <size> <width>640</width> <height>480</height> <depth>3</depth> </size> <object> <name>male</name> <bndbox> <xmin>112</xmin> <ymin>56</ymin> <xmax>308</xmax> <ymax>420</ymax> </bndbox> </object> </annotation>

上面这段里,<size>决定了坐标的参考系,<name>必须和你的类别列表严格一致。很多人转格式时翻车,就是因为 XML 里写的是Male,而 YOLO 的data.yaml里写的是male,大小写不匹配导致训练时类别全乱。

2.2 YOLO txt 的归一化逻辑

YOLO 格式每张图对应一个 txt,每行一个目标,格式是:类别索引 中心x 中心y 宽 高。注意这四个值全部是相对于图片宽高的归一化值,范围 0 到 1。类别索引从 0 开始,对应data.yaml里names列表的顺序。

0 0.328125 0.495833 0.306250 0.758333 1 0.712500 0.520833 0.275000 0.700000

这行的意思是:第一个目标类别索引 0(假设是 male),中心点在图片宽度 32.8% 处,高度 49.6% 处,框宽占整图 30.6%,框高占 75.8%。归一化的好处是图片 resize 后坐标不用重算,坏处是肉眼没法直接判断框准不准,必须写脚本还原。

2.3 两种格式的转换脚本与边界处理

如果你拿到的是 VOC,想转 YOLO,核心就是读 XML、算归一化、写 txt。下面这个脚本我用了很多次,处理过几千张图,稳定。

import xml.etree.ElementTree as ET import os # 类别映射,顺序决定 YOLO 的类别索引 classes = ["male", "female"] def convert_voc_to_yolo(xml_path, txt_path, img_w, img_h): tree = ET.parse(xml_path) root = tree.getroot() lines = [] for obj in root.findall("object"): cls_name = obj.find("name").text.strip() if cls_name not in classes: continue # 跳过不在类别表里的目标 cls_id = classes.index(cls_name) bbox = obj.find("bndbox") xmin = float(bbox.find("xmin").text) ymin = float(bbox.find("ymin").text) xmax = float(bbox.find("xmax").text) ymax = float(bbox.find("ymax").text) # 归一化并转中心点格式 cx = (xmin + xmax) / 2.0 / img_w cy = (ymin + ymax) / 2.0 / img_h w = (xmax - xmin) / img_w h = (ymax - ymin) / img_h # 边界裁剪,防止坐标越界 cx = min(max(cx, 0.0), 1.0) cy = min(max(cy, 0.0), 1.0) w = min(max(w, 0.0), 1.0) h = min(max(h, 0.0), 1.0) lines.append(f"{cls_id} {cx:.6f} {cy:.6f} {w:.6f} {h:.6f}") with open(txt_path, "w") as f: f.write("\n".join(lines))

逻辑说明:先解析 XML,拿到每个 object 的类别和框坐标,然后用图片实际宽高做归一化。参数上,classes列表的顺序必须和训练时data.yaml的names完全一致,否则类别索引会错位。边界裁剪那几行是后悔药,有些标注框会超出图片边缘,不裁剪的话 YOLO 训练时可能报错或产生异常梯度。

3. 用这份数据集跑通 YOLOv8 训练的最小闭环

3.1 目录组织与 data.yaml 写法

拿到压缩包解压后,不管原来目录多乱,我一般会重组成标准结构:images/train、images/val、labels/train、labels/val。图片和标签文件名一一对应,只是扩展名不同。然后写一个data.yaml:

path: /home/user/gender_dataset train: images/train val: images/val nc: 2 names: 0: male 1: female

path是数据集根目录,train和val是相对路径。nc是类别数,这里 2。names的键值对必须和 YOLO txt 里的类别索引对应。常见错误是names写成列表["male", "female"],在部分版本里也能跑,但保险起见用字典形式。

3.2 训练命令与关键参数设置

环境装好 ultralytics 后,一条命令就能开跑:

yolo detect train \ data=/home/user/gender_dataset/data.yaml \ model=yolov8n.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ patience=20 \ project=gender_run \ name=exp1

参数说明:model=yolov8n.pt是最小的预训练模型,适合快速验证;imgsz=640是输入分辨率,9769 张图用 640 在单卡 8G 显存上 batch 16 基本能跑;lr0初始学习率,0.01 是 YOLOv8 的默认值,数据集小可以降到 0.005;patience=20表示 20 轮没提升就早停,省时间。如果显存不够,把batch降到 8 或 4,或者用yolov8n.pt换成更小的模型。

3.3 训练过程看什么指标

跑起来后,终端会打印每轮的 box_loss、cls_loss、dfl_loss 和 mAP。box_loss 管框准不准,cls_loss 管类别对不对,dfl_loss 是分布焦点损失,影响框的精细度。重点看 mAP50 和 mAP50-95,前者是 IoU 0.5 时的平均精度,后者是 0.5 到 0.95 多个阈值的平均。性别检测这种二分类任务,mAP50 能到 0.85 以上就算不错,mAP50-95 通常低不少,0.6 左右是正常水平。如果 cls_loss 一直不降,先检查类别索引有没有错位。

4. 训练完别急着上线:验证与推理的四个关键动作

4.1 用验证集跑一遍看混淆矩阵

训练结束后,runs/detect/gender_run/exp1/下会生成混淆矩阵图。重点看 male 和 female 有没有互相误判。如果 female 被大量判成 male,可能是 female 样本里存在大量遮挡或侧脸,也可能是两类样本数量不均衡。9769 张里如果 male 占 7000、female 占 2769,那模型会偏向 male,需要做重采样或加类别权重。

4.2 单张图片推理与结果解析

from ultralytics import YOLO model = YOLO("runs/detect/gender_run/exp1/weights/best.pt") results = model("test.jpg", conf=0.25, iou=0.45) for r in results: for box in r.boxes: cls_id = int(box.cls[0]) conf = float(box.conf[0]) xyxy = box.xyxy[0].tolist() print(f"类别: {model.names[cls_id]}, 置信度: {conf:.3f}, 框: {xyxy}")

conf=0.25是置信度阈值,低于这个的框不输出;iou=0.45是 NMS 的 IoU 阈值,控制重叠框的合并。这两个参数是推理时最常调的,漏检多就降 conf,框重叠多就降 iou。

4.3 批量推理与结果落盘

实际业务里很少一张张推,通常是批量跑一个文件夹,把结果写成 json 或 csv。我一般会加一个后处理,把框坐标还原成绝对像素值,方便和原图叠加。注意批量推理时不要一次性把所有图读进内存,用生成器或分 batch 处理,否则 9769 张图能把内存吃满。

4.4 导出 ONNX 做部署前验证

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

导出 ONNX 后用 onnxruntime 跑一遍,对比 PyTorch 和 ONNX 的输出差异。如果差异大,检查导出时的 opset 版本和动态轴设置。这一步是部署前的最后一道保险,别跳过。

5. 避坑与排查:性别检测数据集训练中最容易翻车的五件事

5.1 类别索引错位导致所有预测都是 male

现象:训练 loss 正常下降,但推理时所有框都标成 male,female 一个都检不出。原因:YOLO txt 里的类别索引和data.yaml的names顺序不一致,比如 txt 里 0 是 female,但 yaml 里 0 写的是 male。解决:写个脚本统计所有 txt 里出现的类别索引,和 yaml 对照,确保一一对应。

5.2 图片和标签文件名不匹配导致大量样本被跳过

现象:训练时提示No labels found或有效样本数远小于 9769。原因:图片是.jpg,标签是.txt,但文件名前缀不一致,比如图片叫IMG_001.jpg,标签叫001.txt。解决:批量重命名,保证除扩展名外完全一致。用os.path.splitext处理,别手动改。

5.3 标注框越界导致训练中途报错

现象:训练几个 epoch 后突然报RuntimeError: invalid bbox或 loss 变成 nan。原因:VOC 转 YOLO 时没做边界裁剪,某些框的 xmax 超过图片宽度,归一化后值大于 1。解决:转换脚本里加min(max(...))裁剪,或者在训练前用脚本扫描所有 txt,把越界值修正。

5.4 验证集里出现训练集图片导致指标虚高

现象:mAP50 高得离谱,0.98 以上,但实际推理效果很差。原因:划分 train/val 时没打乱,或者用了随机划分但没固定种子,导致同一张图既在训练集又在验证集。解决:划分前先对所有图片文件名做 shuffle,用固定随机种子,然后按 8:2 切分,确保没有交集。

5.5 小目标性别特征不明显导致漏检

现象:远处的人、侧脸、戴帽子的人经常漏检。原因:性别检测依赖面部和发型特征,小目标下这些特征像素太少,模型学不到。解决:训练时开启mosaic增强,提高小目标占比;推理时降低conf到 0.15 左右;如果业务允许,先做人检测再裁图做性别分类,两阶段比单阶段检测更稳。

6. 把 9769 张用出 10 万张的效果:三个进阶技巧

第一个技巧是「借预训练模型的力」。YOLOv8n 在 COCO 上预训练过,已经学会了「人」这个大类。你拿它做性别检测,相当于在会认人的基础上再学男女差异,收敛快很多。我一般会先冻结 backbone 训 10 个 epoch,再解冻全量微调,这样小数据集上更稳。

第二个技巧是「用分类模型补检测的漏」。性别检测本质是二分类,检测模型负责定位,分类模型负责判断。你可以把检测框裁出来,送进一个轻量分类网络(比如 MobileNetV3)做二次判断,两个模型的结果做融合。实测在遮挡和侧脸场景下,召回能提升 5 到 8 个百分点。

第三个技巧是「难例挖掘」。训练完第一轮后,用模型跑一遍训练集,把置信度低或预测错的样本挑出来,人工检查标注是否有误,或者把这些难例复制多份加入下一轮训练。9769 张里通常有 5% 到 10% 是难例,处理完再训一轮,mAP 能涨 2 到 3 个点。

# 难例挖掘的简单实现:挑出置信度低于阈值的样本 from ultralytics import YOLO import os model = YOLO("best.pt") hard_examples = [] for img in os.listdir("images/train"): r = model(os.path.join("images/train", img), conf=0.5, verbose=False)[0] if len(r.boxes) == 0: hard_examples.append(img) # 没检出任何目标,可能是难例或漏标 print(f"难例数量: {len(hard_examples)}")

这段代码跑完,把hard_examples里的图拿出来人工过一遍,该补标的补标,该删的删。别小看这一步,数据质量提升带来的收益,往往比换模型、调参数大得多。

我自己做这类小数据集项目,最大的教训就是:别一上来就想着换更大的模型、加更复杂的结构。先把数据本身的问题解决掉——类别对不对、框准不准、有没有重复、难例处理了没有。这些做完,YOLOv8n 也能跑出让你满意的结果。希望帮到你。

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

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

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

立即咨询