DensePose CSE 连续表面嵌入完全指南:人体与动物稠密姿态估计的架构、损失设计与模型库实战
DensePose CSE 连续表面嵌入完全指南:人体与动物稠密姿态估计的架构、损失设计与模型库实战
DensePose CSE(Continuous Surface Embeddings,连续表面嵌入)是 DensePose 项目中用于稠密姿态估计的第二种核心范式:模型不再预测离散的 UV 坐标,而是同时学习网格顶点与图像像素的嵌入描述子,并通过匹配把每个像素定位到三维物体表面。本文以仓库内 DENSEPOSE_CSE.md 为骨架,结合 DensePose 子项目的配置、源码与评测模块,系统讲解 CSE 的架构流水线、数据集约定、完整模型库(Model Zoo)基线、hard/soft 损失设计、嵌入器机制以及动物类别微调实战,读完即可独立复现与扩展 CSE 模型。
一、概述:CSE 的核心思想与流水线
1.1 从"离散图表"到"连续表面"
DensePose 项目中存在两条并行的技术路线(见 DensePose 主 README):
- 基于图表的估计(Chart-based,DENSEPOSE_IUV):将三维网格切分成多个 chart,为每个像素预测图表索引
I与局部坐标(U, V); - 连续表面嵌入(CSE,本文主题):让模型同时学习网格顶点的描述子和图像像素的描述子,将两者放入同一嵌入空间并建立对应关系,从而推导出每个像素在三维模型上的位置。
CSE 的优势在于它不依赖预定义的图表划分,天然支持把同一套方法迁移到新类别(例如动物),只要该类别存在一个三维网格模型即可。
1.2 架构流水线
CSE 流水线以 Faster R-CNN + Feature Pyramid Network(FPN) 为元架构(Meta Architecture)。对每一个被检测到的目标,模型预测两路输出:
- 粗分割
S(coarse segmentation):2 个通道,即前景 / 背景; - 嵌入
E(embedding):16 个通道,即每个像素的连续表面嵌入向量(16 维嵌入空间)。
与此同时,嵌入器(embedder) 为对应的三维网格产生顶点嵌入 Ê。通用的位置嵌入 E(像素侧)与顶点嵌入 Ê(网格侧)被匹配起来,从而为每个像素推导出其连续表面嵌入(即在三维表面的位置)。
这一流程在源码中可以得到直接印证:DensePose 的 CSE 预测器 predictors/cse.py 中的 DensePoseEmbeddingPredictor 对头部特征并行执行两次转置卷积——embed_lowres 输出通道数为 CSE.EMBED_SIZE,coarse_segm_lowres 输出通道数为 NUM_COARSE_SEGM_CHANNELS,随后经双线性插值上采样,最终返回 DensePoseEmbeddingPredictorOutput(embedding=embed, coarse_segm=coarse_segm):
# densepose/modeling/predictors/cse.py(要点摘录)
self.coarse_segm_lowres = ConvTranspose2d(
dim_in, n_segm_chan, kernel_size, stride=2, padding=int(kernel_size / 2 - 1))
self.embed_lowres = ConvTranspose2d(
dim_in, embed_size, kernel_size, stride=2, padding=int(kernel_size / 2 - 1))
其中 embed_size = cfg.MODEL.ROI_DENSEPOSE_HEAD.CSE.EMBED_SIZE,其默认值为 16,定义在 densepose/config.py 的 add_densepose_head_cse_config 中;n_segm_chan = NUM_COARSE_SEGM_CHANNELS,在 CSE 基础配置 Base-DensePose-RCNN-FPN.yaml 中被设为 2(前景 / 背景),与文档描述完全一致。
1.3 训练数据
CSE 模型训练与验证使用的数据集细节,请参考仓库文档 DENSEPOSE_DATASETS.md:
- 人体:基于 COCO 2014 的 CSE 标注(
densepose_coco_2014_train_cse、valminusminival_cse、minival_cse); - 动物:DensePose LVIS 中 9 个动物类别(cat、dog、sheep、horse、zebra、giraffe、elephant、cow、bear)的 CSE 标注,划分出
ds1_train与ds2_train两个训练集(详见 数据集文档的 CSE 标注章节)。
数据集使用注意事项(来自数据集文档):
ds2_train复用了部分ds1_train的标注,且ds1_train中的部分标注出现在ds2_val中——因此若要在ds2_val上评估,不应在ds1_train上训练,以免数据泄漏。
二、模型库(Model Zoo)与基线表现
以下表格完整继承自 DENSEPOSE_CSE.md 的模型库章节。其中 lr sched 为学习率调度(s1x / 4K / 16k 分别对应 13 万、4 千、1.6 万次迭代的训练协议);dl 后缀对应 DeepLab 风格的 DensePose 头部(仓库中对应 roi_heads/deeplab.py 的实现,可据此推断)。
2.1 人体 CSE 模型(hard assignment 损失 ℒ)
采用 Neverova et al, 2020 的训练协议,使用硬分配损失 ℒ(对应源码中的 EmbeddingLoss):
| 名称(配置) | lr sched | 训练时间 (s/iter) | 推理时间 (s/im) | 训练显存 (GB) | box AP | segm AP | dp. AP GPS | dp. AP GPSm | model id |
|---|---|---|---|---|---|---|---|---|---|
| R_50_FPN_s1x | s1x | 0.349 | 0.060 | 6.3 | 61.1 | 67.1 | 64.4 | 65.7 | 251155172 |
| R_101_FPN_s1x | s1x | 0.461 | 0.071 | 7.4 | 62.3 | 67.2 | 64.7 | 65.8 | 251155500 |
| R_50_FPN_DL_s1x | s1x | 0.399 | 0.061 | 7.0 | 60.8 | 67.8 | 65.5 | 66.4 | 251156349 |
| R_101_FPN_DL_s1x | s1x | 0.504 | 0.074 | 8.3 | 61.5 | 68.0 | 65.6 | 66.6 | 251156606 |
2.2 人体 CSE 模型(soft assignment 损失 ℒσ)
使用软分配损失 ℒσ(对应源码中的 SoftEmbeddingLoss):
| 名称(配置) | lr sched | 训练时间 (s/iter) | 推理时间 (s/im) | 训练显存 (GB) | box AP | segm AP | dp. AP GPS | dp. AP GPSm | model id |
|---|---|---|---|---|---|---|---|---|---|
| R_50_FPN_soft_s1x | s1x | 0.357 | 0.057 | 9.7 | 61.3 | 66.9 | 64.3 | 65.4 | 250533982 |
| R_101_FPN_soft_s1x | s1x | 0.464 | 0.071 | 10.5 | 62.1 | 67.3 | 64.5 | 66.0 | 250712522 |
| R_50_FPN_DL_soft_s1x | s1x | 0.427 | 0.062 | 11.3 | 60.8 | 68.0 | 66.1 | 66.7 | 250713703 |
| R_101_FPN_DL_soft_s1x | s1x | 0.483 | 0.071 | 12.2 | 61.5 | 68.2 | 66.2 | 67.1 | 250713061 |
2.3 动物 CSE 模型(基于 ds1_train 微调)
将人体 CSE 模型在 ds1_train 动物数据上以软分配损失 ℒσ 微调得到(数据集细节见 DensePose LVIS 章节):
| 名称(配置) | lr sched | 训练时间 (s/iter) | 推理时间 (s/im) | 训练显存 (GB) | box AP | segm AP | dp. AP GPS | dp. AP GPSm | model id |
|---|---|---|---|---|---|---|---|---|---|
| R_50_FPN_soft_chimps_finetune_4k | 4K | 0.569 | 0.051 | 4.7 | 62.0 | 59.0 | 32.2 | 39.6 | 253146869 |
| R_50_FPN_soft_animals_finetune_4k | 4K | 0.381 | 0.061 | 7.3 | 44.9 | 55.5 | 21.3 | 28.8 | 253145793 |
| R_50_FPN_soft_animals_CA_finetune_4k | 4K | 0.412 | 0.059 | 7.1 | 53.4 | 59.5 | 25.4 | 33.4 | 253498611 |
缩写说明:CA(class agnostic,类别无关训练)——将所有被标注的实例映射到单一类别中进行训练。
2.4 动物 CSE 模型(基于 ds2_train,含 cycle loss 方案)
将人体 CSE 模型在 ds2_train 上以软分配损失 ℒσ 微调,部分调度还叠加了循环一致性损失(cycle losses)(详见 RELEASE_2021_06.md 与 Neverova et al, 2021):
| 名称(配置) | lr sched | 训练时间 (s/iter) | 推理时间 (s/im) | 训练显存 (GB) | box AP | segm AP | dp. AP GPS | dp. AP GPSm | GErr | GPS | model id |
|---|---|---|---|---|---|---|---|---|---|---|---|
| R_50_FPN_soft_animals_I0_finetune_16k | 16k | 0.386 | 0.058 | 8.4 | 54.2 | 67.0 | 29.0 | 38.6 | 13.2 | 85.4 | 270727112 |
| R_50_FPN_soft_animals_I0_finetune_m2m_16k | 16k | 0.508 | 0.056 | 12.2 | 54.1 | 67.3 | 28.6 | 38.4 | 12.5 | 87.6 | 270982215 |
| R_50_FPN_soft_animals_I0_finetune_i2m_16k | 16k | 0.483 | 0.056 | 9.7 | 54.0 | 66.6 | 28.9 | 38.3 | 11.0 | 88.9 | 270727461 |
2.5 指标口径说明
box AP/segm AP:标准的目标检测与实例分割平均精度;dp. AP GPS/dp. AP GPSm:DensePose 姿态估计的 AP 指标,基于测地线点相似度(Geodesic Point Similarity, GPS)度量,GPSm为均值版本;GErr:测地线误差(越小越好);GPS:测地线点相似度(越大越好)。这两列仅出现在ds2_train动物模型中,对应 CSE 场景下的网格对齐评估,仓库中的评估实现见 evaluation/mesh_alignment_evaluator.py。
各行的 model id 用于区分不同训练运行;对应模型权重与 metrics.json 训练日志的下载入口,请见原文档 DENSEPOSE_CSE.md 模型库表格中的 download 列。
三、配置体系与源码级解析
3.1 基础配置:Base-DensePose-RCNN-FPN.yaml
所有 CSE 模型共享的基础配置 Base-DensePose-RCNN-FPN.yaml 定义了 CSE 任务的骨架:
- 主干与 FPN:
build_resnet_fpn_backbone,FPN 输入为["res2","res3","res4","res5"],输出["p2","p3","p4","p5","p6"]供 RPN 使用; - ROI 头部:
ROI_HEADS.NAME = "DensePoseROIHeads",NUM_CLASSES = 1(人体单类); - DensePose 头:
ROI_DENSEPOSE_HEAD.NAME = "DensePoseV1ConvXHead",NUM_COARSE_SEGM_CHANNELS = 2(前景 / 背景),PREDICTOR_NAME = "DensePoseEmbeddingPredictor",LOSS_NAME = "DensePoseCseLoss"; - CSE 专属配置:
CSE.EMBED_LOSS_NAME可选"EmbeddingLoss"(硬分配)或"SoftEmbeddingLoss"(软分配); - 求解器:
IMS_PER_BATCH = 16、BASE_LR = 0.01、梯度裁剪(norm 类型、值 1.0); - 评估:
DENSEPOSE_EVALUATION.TYPE = "cse"、STORAGE = "file"。
其中 DensePoseCseLoss 的实现位于 losses/cse.py,它把总损失组织为:
loss_densepose_S = INDEX_WEIGHTS × segm_loss (粗分割损失)
loss_densepose_E{mesh} = EMBED_LOSS_WEIGHT × embed_loss (每网格的嵌入损失)
loss_shape2shape / loss_pix2shape (可选的循环一致性损失)
3.2 人体 CSE 基线与嵌入器配置
Base-DensePose-RCNN-FPN-Human.yaml 为人体 CSE 引入了核心的**顶点嵌入器(embedder)**配置:
MODEL:
ROI_DENSEPOSE_HEAD:
CSE:
EMBEDDERS:
"smpl_27554":
TYPE: vertex_feature # 嵌入器类型
NUM_VERTICES: 27554 # SMPL 网格顶点数
FEATURE_DIM: 256 # 顶点特征维度 K
FEATURES_TRAINABLE: False # 顶点特征(LBO 特征)固定
IS_TRAINABLE: True # 映射矩阵参与训练
INIT_FILE: "..." # 预计算的 LBO 特征文件
DATASETS:
CLASS_TO_MESH_NAME_MAPPING:
"0": "smpl_27554" # 类别 0 对应 SMPL 网格
由此可看到 CSE 的关键设计:顶点特征来自拉普拉斯-贝尔特拉米算子(LBO)预计算并固定(FEATURES_TRAINABLE: False),只训练把特征映射到嵌入空间的参数矩阵。
3.3 顶点嵌入器:vertex_direct 与 vertex_feature
仓库在 modeling/cse/embedder.py 中定义了两种嵌入器类型(EmbedderType 枚举),并通过 create_embedder() 依据配置创建:
vertex_direct(VertexDirectEmbedder,见 vertex_direct_embedder.py):直接把每个顶点映射为一个可学习的[N, D]嵌入张量(N= 顶点数,D= 嵌入维度),forward输出normalize_embeddings(self.embeddings);vertex_feature(VertexFeatureEmbedder,见 vertex_feature_embedder.py):先加载固定顶点特征F(形状[N, K]),再与可学习映射E(形状[K, D])做矩阵乘法F * E得到[N, D]顶点嵌入并归一化。这正是人体 / 动物配置中使用的类型。
嵌入器容器 Embedder 支持多网格(每个网格一个子模块 embedder_{mesh_name}),并支持从已有模型检查点非严格加载(strict=False),以便在不同网格间做微调(例如把人体模型迁移到动物网格)。
3.4 损失函数:hard 与 soft assignment
EmbeddingLoss(硬分配):losses/embed.py 实现。对每个网格,计算观测像素嵌入与所有网格顶点嵌入的平方欧氏距离矩阵,除以EMBEDDING_DIST_GAUSS_SIGMA(默认 0.01)作为未归一化得分,然后对 GT 顶点 ID 做交叉熵(F.cross_entropy),即每个像素被硬性指派到最匹配的顶点;SoftEmbeddingLoss(软分配):losses/soft_embed.py 实现。得分同时考虑嵌入距离(EMBEDDING_DIST_GAUSS_SIGMA,默认 0.01)与网格顶点间的测地线距离(GEODESIC_DIST_GAUSS_SIGMA,默认 0.01):先对 GT 顶点按测地线距离做softmax得到软目标,再与嵌入距离的log_softmax加权求和,使损失对"相邻顶点"更平滑——这正是软分配损失在动物模型(以及_soft_系列人体模型)中被采用的原因。
相关超参数全部集中在 densepose/config.py 的 add_densepose_head_cse_config 中,除上述两个 sigma 外,还包括:
| 配置项 | 默认值 | 说明 |
|---|---|---|
CSE.EMBED_SIZE |
16 | 嵌入空间维度 D |
CSE.EMBED_LOSS_WEIGHT |
0.6 | 嵌入损失权重 |
CSE.EMBED_LOSS_NAME |
"EmbeddingLoss" |
硬 / 软分配损失切换 |
CSE.FEATURES_LR_FACTOR |
1.0 | 顶点特征学习率因子 |
CSE.EMBEDDING_LR_FACTOR |
1.0 | 嵌入参数学习率因子 |
3.5 循环一致性损失(Cycle Losses)
对于跨类别迁移(如 ds2_train 上的 m2m / i2m 方案),文档提到部分调度叠加了循环损失,源码中对应两类:
- shape-to-shape 循环损失(
SHAPE_TO_SHAPE_CYCLE_LOSS,默认ENABLED: False,WEIGHT: 0.025,NORM_P: 2,TEMPERATURE: 0.05,MAX_NUM_VERTICES: 4936):在两个网格的顶点嵌入之间做循环一致性约束; - pixel-to-shape 循环损失(
PIX_TO_SHAPE_CYCLE_LOSS,默认ENABLED: False,WEIGHT: 0.0001,NUM_PIXELS_TO_SAMPLE: 100,PIXEL_SIGMA: 5.0等):在像素嵌入与网格顶点嵌入之间做循环一致性约束。
实现分别位于 losses/cycle_shape2shape.py 与 losses/cycle_pix2shape.py,并由 DensePoseCseLoss 根据配置按权重叠加。
3.6 评估配置
CSE 评估通过 DENSEPOSE_EVALUATION 段配置(densepose/config.py):
TYPE:"cse"或"iou",CSE 模型用前者;STORAGE:"none"/"ram"/"file",其中file最省内存;EVALUATE_MESH_ALIGNMENT:CSE 场景下是否评估网格对齐(动物模型配置中设为True),MESH_ALIGNMENT_MESH_NAMES指定要评估的网格。
四、训练与微调实战要点
4.1 从头训练人体 CSE 模型
以 densepose_rcnn_R_50_FPN_s1x.yaml 为例(hard 分配损失):
_BASE_: "Base-DensePose-RCNN-FPN-Human.yaml"
MODEL:
WEIGHTS: "detectron2://ImageNetPretrained/MSRA/R-50.pkl" # ImageNet 预训练主干
RESNETS:
DEPTH: 50
ROI_DENSEPOSE_HEAD:
CSE:
EMBED_LOSS_NAME: "EmbeddingLoss" # 硬分配损失
SOLVER:
MAX_ITER: 130000
STEPS: (100000, 120000) # s1x 调度:13 万迭代
将 EMBED_LOSS_NAME 换成 "SoftEmbeddingLoss" 即得到 densepose_rcnn_R_50_FPN_soft_s1x.yaml。训练入口为 train_net.py,环境搭建与快速开始请参考 GETTING_STARTED.md。
4.2 微调动物 CSE 模型(ds1_train,类别无关)
densepose_rcnn_R_50_FPN_soft_animals_CA_finetune_4k.yaml 展示了"从人体模型迁移到动物"的完整配方:
- 权重初始化:
MODEL.WEIGHTS指向人体软分配模型densepose_rcnn_R_50_FPN_soft_s1x(model id250533982)的权重,实现跨类别迁移; - 粗分割改用掩码监督:
COARSE_SEGM_TRAINED_BY_MASKS: True; - 损失平滑增强:
EMBEDDING_DIST_GAUSS_SIGMA: 0.1、GEODESIC_DIST_GAUSS_SIGMA: 0.1(比人体默认的 0.01 更大); - 9 个动物网格嵌入器:cat_5001 / dog_5002 / sheep_5004 / horse_5004 / zebra_5002 / giraffe_5002 / elephant_5002 / cow_5002 / bear_4936,均使用
vertex_feature类型、FEATURE_DIM: 256、FEATURES_TRAINABLE: False; - 类别白名单与类别无关映射:
WHITELISTED_CATEGORIES只保留 9 个动物 LVIS 类别 ID;CATEGORY_MAPS把所有动物类别映射到单一类别(如sheep,ID 943),实现CA(class agnostic)训练;CLASS_TO_MESH_NAME_MAPPING给出类别到网格的对应(CA 模式下网格由 GT 数据决定); - 调度:
MAX_ITER: 4000、STEPS: (3000, 3500)(4K 协议); - 评估:
EVALUATE_MESH_ALIGNMENT: True。
4.3 微调动物 CSE 模型(ds2_train,多类别 + 循环损失)
densepose_rcnn_R_50_FPN_soft_animals_I0_finetune_16k.yaml 则展示了多类别版本:
ROI_HEADS.NUM_CLASSES: 9,CLASS_TO_MESH_NAME_MAPPING为 9 个类别分别指定网格(bear_4936、cow_5002、cat_7466、dog_7466、elephant_5002、giraffe_5002、horse_5004、sheep_5004、zebra_5002);- 权重从
densepose_rcnn_R_50_FPN_soft_animals_finetune_maskonly_24k微调而来; - 调度为
MAX_ITER: 16000、STEPS: (12000, 14000)(16k 协议); I0表示不启用循环损失的基准,m2m/i2m变体在 对应配置 中启用不同方向的循环一致性损失。
五、引用(References)
如果使用基于连续表面嵌入的 DensePose 方法,请引用以下文献(BibTeX 条目与 DENSEPOSE_CSE.md 一致):
连续表面嵌入:
@InProceedings{Neverova2020ContinuousSurfaceEmbeddings,
title = {Continuous Surface Embeddings},
author = {Neverova, Natalia and Novotny, David and Khalidov, Vasil and Szafraniec, Marc and Labatut, Patrick and Vedaldi, Andrea},
journal = {Advances in Neural Information Processing Systems},
year = {2020},
}
循环一致性损失(Universal Canonical Maps):
@InProceedings{Neverova2021UniversalCanonicalMaps,
title = {Discovering Relationships between Object Categories via Universal Canonical Maps},
author = {Neverova, Natalia and Sanakoyeu, Artsiom and Novotny, David and Labatut, Patrick and Vedaldi, Andrea},
journal = {The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},
year = {2021},
}
总结
DensePose CSE 以"像素嵌入 ↔ 顶点嵌入"的通用嵌入空间为核心,摆脱了图表划分的约束,使稠密姿态估计能够平滑迁移到人体之外的任意网格类别。结合仓库内 configs/cse 下 19 份配置与 densepose/modeling 中的嵌入器、预测器、损失实现,你可以从 s1x 人体基线出发,通过软分配损失、类别无关映射与循环一致性损失逐步构建并微调属于自己的动物稠密姿态模型。