Make `argmax` in `post_process_semantic_segmentation` optional

用户在使用 Hugging Face Transformers 的语义分割模型(如 DETR、MaskFormer、Mask2Former、OneFormer 等)时,通过 post_process_semantic_segmentation 函数获取分割结果。当前该函数会强制对 logits/sc

Make `argmax` in `post_process_semantic_segmentation` optional

Make `argmax` in `post_process_semantic_segmentation` optional

快速结论:当用户需要获取语义分割模型的类别概率(shape [N, C, H, W])而非硬分割图(shape [N, H, W])时触发,例如计算 ROC AUC 指标或使用自定义分割损失函数。优先排查:在调用 post_process_semantic_segmentation 前,手动处理模型原始输出以避免被强制 argmax

问题场景

用户在使用 Hugging Face Transformers 的语义分割模型(如 DETR、MaskFormer、Mask2Former、OneFormer 等)时,通过 post_process_semantic_segmentation 函数获取分割结果。当前该函数会强制对 logits/scores 执行 argmax,返回硬分割图(shape [N, H, W])。但在某些应用场景(如计算 ROC AUC 指标、实现 SMP 库中的自定义分割损失、使用 RankSEG 等后处理方法)中,用户需要获取类别概率(shape [N, C, H, W])而非最终分割图。

报错原文

# 没有直接的报错信息,核心问题是功能缺失
# 用户期望:从 post_process_semantic_segmentation 返回 [N, C, H, W] 的类别概率
# 当前行为:强制 argmax 后返回 [N, H, W] 的硬分割图

原因分析

可能原因:Transformers 的 post_process_semantic_segmentation 函数设计为一次性完成从模型原始输出到最终分割图的转换,内部包含对所有模型的通用后处理逻辑(包括对 DETR 的 class_queries_logitsmasks_queries_logits 的组装、MaskFormer 的 mask 处理等),最后强制执行 argmax。对于需要中间类别概率表示的下游任务,这一设计过于刚性。

  • 用户手动复制各模型(DETR、ConditionalDETR、MaskFormer、Mask2Former、OneFormer 等)的后处理代码进行改造,代码极度冗余。
  • 不同模型的输出结构不同:有些模型输出 logits(可直接 softmax),而 DETR/MaskFormer 等输出 class_queries_logitsmask_queries_logits,需要先通过 Einsum 组装为分类得分。
  • 社区提交了 PR #37904 尝试添加 class_proba 参数,但尚未合并。

环境排查

  • Transformers 版本:低于 v4.49.0(2026年7月8日关闭 Issue 时的当前版本)。
  • 模型类型:DETR(DetrForSegmentation)、ConditionalDETR(ConditionalDetrForSegmentation)、MaskFormer(MaskFormerForInstanceSegmentation)、Mask2Former(Mask2FormerForUniversalSegmentation)、OneFormer(OneFormerForUniversalSegmentation)、SegFormer(SegformerForSemanticSegmentation)等。
  • Python 环境:需要 PyTorch 和 torchvision(对于模型推理)。

解决步骤

  1. 获取模型原始输出:直接调用模型的 forward,如 outputs = model(pixel_values),不通过 pipeline。
  2. 手动处理模型输出:根据模型类型编写自定义后处理函数,获取类别概率。参考 Issue 中提供的代码模式:
    • 对于输出 logits 的模型(如 SegFormer):probs = outputs.logits.softmax(dim=1)
    • 对于 DETR/ConditionalDETR:提取 class_queries_logitsmasks_queries_logits,执行 masks_classes = class_queries_logits.softmax(dim=-1)[..., :-1](注意处理 null class),masks_probs = masks_queries_logits.sigmoid(),然后用 torch.einsum 组装得分。
    • 对于 MaskFormer/Mask2Former/OneFormer:提取 class_queries_logitsmasks_queries_logits,类似 DETR 处理,但需注意模型特有的输出键(如 masks_queries_logits 在 Mask2Former 中为 mask_embeddings)。
  3. 可优先尝试:参考试验分支 leev1s/semantic-rankseg 中的实现(通过 _get_semantic_segmentation_probs 方法获取概率)。
    probs = self._get_semantic_segmentation_probs(model_outputs)[0]
  4. 等待官方功能:关注 PR #37904 或后续版本是否添加 class_proba 参数。

验证方法

确认输出张量的形状为 [N, C, H, W],且每个像素的类别概率和为 1(softmax 后)。可以通过 probs.sum(dim=1).allclose(torch.ones_like(probs[:, 0, :, :])) 进行验证。

参考来源

huggingface/transformers #37715

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 12016

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注