04 · CUB → YOLO Pose
转换器是 Demo 里最需要认真验收的代码
训练失败往往不是模型问题,而是归一化、左右点交换、不可见点或越界框处理错误。转换器必须同时生成标签、manifest、异常日志和可视化接触表。
每个正样本标签恰好 50 个字段
class cx cy w h
back_x back_y back_v
beak_x beak_y beak_v
...
throat_x throat_y throat_v
# 5 + 15 × 3 = 50 tokens
空标签就是无鸟
images/train/example_negative.jpg
labels/train/example_negative.txt
# txt 文件存在但内容为空
# 不建立 non-bird 类,也不画“背景框”
| 转换步骤 | 规则 | 必须审计 | 失败处理 |
| 图像尺寸 | 以实际 JPEG 宽高为准,不从 bbox 推断。 | 可打开、宽高 > 0、hash 记录。 | 损坏图退出,不静默跳过。 |
| 鸟框 | x1,y1,w,h → clip 后的归一化 cx,cy,w,h。 | 所有值在 [0,1]、面积 > 0。 | CUB train 有 14 个框精确越界;clip 并逐条记录。 |
| 可见关键点 | CUB visible=1 → YOLO v=2。 | x/y 在图内且归一化后在 [0,1]。 | train 有 1 个可见点越界;改为 0 0 0 并记录,不把它硬推到边缘。 |
| 不可见关键点 | CUB visible=0 → 0 0 0。 | 不可见点不能保留任意坐标。 | 转换器断言,不符合即失败。 |
| 水平翻转 | 左右眼、腿、翼成对交换。 | 翻转前后画 16 张骨架图。 | 关掉 fliplr,直到 flip_idx 视觉通过。 |
| 负样本 | 同名空 txt。 | 图片与标签一一对应、内容长度 0。 | 缺标签或非空即失败。 |
数据 YAML 的核心契约
Ultralytics 运行时会按数据覆盖 nc / kpt_shape
path: data/cub15_pose_demo
train: images/train
val: images/val
names:
0: bird
kpt_shape: [15, 3]
flip_idx: [0, 1, 2, 3, 4, 5, 10, 11, 12, 9, 6, 7, 8, 13, 14]
kpt_names:
0: [back, beak, belly, breast, crown, forehead,
left_eye, left_leg, left_wing, nape,
right_eye, right_leg, right_wing, tail, throat]
不要把 COCO bird 框直接混进这一版 Pose:COCO bird 有框但没有 CUB 的 15 点。如果把 15 点全写成 v=0,模型会把“无关键点”当作大量监督模式,影响 visibility 和关键点头。正式流程应先用 CUB+COCO+负样本训练 Detect,再把其兼容权重迁移到只含真实 15 点标签的 Pose 阶段;若要混合 box-only 样本,需要自定义 loss mask,而不是伪造不可见点。