bev-project/RMT_PPAD_VS_BEVFUSION_HEAD_...

17 KiB
Raw Blame History

RMT-PPAD vs BEVFusion 多任务头模块对比分析

分析时间: 2025-11-05
分析目标: 对比RMT-PPAD和BEVFusion的多任务检测/分割头架构,寻找可借鉴的优化方向


1. 架构总览对比

RMT-PPAD 多任务头架构

论文: RMT-PPAD: Real-time Multi-task Learning for Panoptic Perception
GitHub: https://github.com/JiayuanWang-JW/RMT-PPAD

核心特点:

  1. 门控控制适配器 (Gate Control with Adapter)

    • 自适应融合共享特征和任务特定特征
    • 通过可学习的门控机制平衡通用特征和任务特定特征
    • 有效缓解任务间负迁移问题
  2. 自适应分割解码器 (Adaptive Segmentation Decoder)

    • 自动学习多尺度特征的权重
    • 避免为不同分割任务手动设计特定结构
    • 训练过程中动态调整特征融合策略
  3. 实时性设计

    • 轻量级架构,适合实时应用
    • 共享骨干网络,减少计算冗余

BEVFusion 多任务头架构

论文: BEVFusion: Multi-Task Multi-Sensor Fusion
当前实现: Phase 4A Stage 1

核心特点:

  1. 独立任务头设计

    • 检测头: TransFusionHead (Transformer-based)
    • 分割头: EnhancedBEVSegmentationHead (CNN-based)
    • 两个头独立处理共享BEV特征
  2. 统一BEV表示

    • 多模态融合后生成统一512通道BEV特征 (360×360)
    • 两个任务头接收相同的BEV输入
    • 简单的损失加权策略 (loss_scale)
  3. 丰富的特征增强模块

    • ASPP: 多尺度空间金字塔池化
    • Channel Attention: 通道注意力
    • Spatial Attention: 空间注意力
    • Deep Supervision: 深度监督

2. 详细模块对比

2.1 特征共享策略

维度 RMT-PPAD BEVFusion (当前)
共享层级 共享骨干 + 门控适配器 完全共享BEV特征
任务特定适配 门控机制自适应选择 直接输入相同特征
特征融合 可学习权重融合 简单拼接/直接使用
负迁移处理 显式处理 依赖损失权重平衡

关键差异:

# RMT-PPAD: 门控适配器机制
shared_feat = backbone(x)
task_specific_feat = task_adapter(shared_feat)
gate_weight = sigmoid(gate_network(shared_feat))
final_feat = gate_weight * shared_feat + (1 - gate_weight) * task_specific_feat

# BEVFusion: 直接共享
bev_feat = decoder_neck(fusion_output)  # (B, 512, 360, 360)
det_output = detection_head(bev_feat)    # 相同输入
seg_output = segmentation_head(bev_feat) # 相同输入

2.2 解码器设计

维度 RMT-PPAD BEVFusion Enhanced Head
解码器类型 自适应多尺度解码器 4层深度CNN解码器
尺度融合 自动学习权重 ASPP多尺度
注意力机制 门控注意力 Channel + Spatial
深度监督 中间层监督 辅助分类器

BEVFusion Enhanced Head架构:

EnhancedBEVSegmentationHead:
  1. BEV Grid Transform: 360×360  600×600 上采样
  2. ASPP: 多尺度感受野 (dilation=[6,12,18])
  3. Channel Attention: 通道权重调整 (reduction=16)
  4. Spatial Attention: 空间权重调整 (kernel=7)
  5. Deep Decoder: [256256128128] 4
  6. Per-class Classifier: 每个类别独立分类器
  7. Auxiliary Classifier: 深度监督

2.3 损失函数策略

维度 RMT-PPAD BEVFusion (当前)
分割损失 自适应加权Focal + Dice Focal + Dice (固定权重)
类别平衡 动态调整 静态类别权重
任务平衡 门控机制隐式平衡 显式loss_scale
深度监督 多层次监督 单层辅助监督

当前BEVFusion损失配置:

# Phase 4A Stage 1配置
loss_weight = {
    'drivable_area': 1.0,
    'ped_crossing': 3.0,
    'walkway': 1.5,
    'stop_line': 4.0,
    'carpark_area': 2.0,
    'divider': 3.0,  # ⚠️ 当前最具挑战性
}

# 任务间平衡
loss_scale = {
    'object': 1.0,  # 检测任务
    'map': 1.0,     # 分割任务
}

3. 性能对比与分析

3.1 当前BEVFusion性能 (Epoch 5最新)

分割性能 (Dice Loss, 越低越好):

✅ drivable_area: 0.1155 (优秀)
✅ ped_crossing:  0.2224 (良好)
✅ walkway:       0.2189 (良好)
⚠️ stop_line:     0.3196 (中等)
✅ carpark_area:  0.1953 (良好)
⚠️ divider:       0.5142 (挑战) ← 主要瓶颈

检测性能:

✅ heatmap Loss:  0.2388
✅ bbox Loss:     0.2991
✅ matched IoU:   0.6198 (优秀)

3.2 Divider性能瓶颈分析

为什么Divider最难

  1. 线性结构细长 - 宽度仅1-2像素
  2. 遮挡严重 - 车辆经常遮挡分隔线
  3. 样本不平衡 - 占总像素比例极小 (<1%)
  4. 特征表达困难 - 需要更强的全局上下文理解

RMT-PPAD的潜在优势:

  • 门控机制可以让分割任务专注于细粒度特征
  • 自适应解码器可以为divider学习特定的尺度权重
  • 减少检测任务对分割特征的干扰

4. 可借鉴的优化方向

高优先级优化

4.1 引入门控适配器机制

目标: 让检测和分割任务获得任务特定的特征表达

实现方案:

class GateControlAdapter(nn.Module):
    """门控适配器:自适应融合共享和任务特定特征"""
    
    def __init__(self, in_channels=512, reduction=16):
        super().__init__()
        
        # 共享特征分支(保持不变)
        self.shared_conv = nn.Identity()
        
        # 任务特定适配器
        self.task_adapter = nn.Sequential(
            nn.Conv2d(in_channels, in_channels, 3, padding=1, bias=False),
            nn.GroupNorm(32, in_channels),
            nn.ReLU(True),
            nn.Conv2d(in_channels, in_channels, 3, padding=1, bias=False),
            nn.GroupNorm(32, in_channels),
        )
        
        # 门控网络
        self.gate_net = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Conv2d(in_channels, in_channels // reduction, 1),
            nn.ReLU(True),
            nn.Conv2d(in_channels // reduction, in_channels, 1),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        """
        Args:
            x: 共享BEV特征 (B, 512, 360, 360)
        Returns:
            adapted_feat: 任务特定适配后的特征
        """
        shared = self.shared_conv(x)
        task_specific = self.task_adapter(x)
        
        # 门控权重:自适应选择共享/特定
        gate = self.gate_net(x)
        
        # 融合
        adapted = gate * shared + (1 - gate) * task_specific
        return adapted

集成到BEVFusion:

# mmdet3d/models/fusion_models/bevfusion.py

class BEVFusion(Base3DFusionModel):
    def __init__(self, ...):
        ...
        # 为每个任务头添加门控适配器
        self.task_adapters = nn.ModuleDict({
            'object': GateControlAdapter(in_channels=512),
            'map': GateControlAdapter(in_channels=512),
        })
    
    def forward_single(self, ...):
        ...
        # 统一BEV特征
        x = self.decoder["neck"](x)  # (B, 512, 360, 360)
        
        # 任务特定适配
        for task_type, head in self.heads.items():
            adapted_feat = self.task_adapters[task_type](x)
            if task_type == "object":
                pred_dict = head(adapted_feat, metas)
            elif task_type == "map":
                losses = head(adapted_feat, gt_masks_bev)

预期收益:

  • 减少任务间负迁移
  • 分割任务可获得更适合细粒度的特征
  • 检测任务可保持对大目标的敏感性
  • 📊 预计Divider Dice Loss改善: 5-10%

4.2 自适应多尺度特征融合

目标: 让不同类别自动学习最优的尺度权重

当前问题:

  • ASPP使用固定的dilation rates [6, 12, 18]
  • 所有类别使用相同的多尺度融合权重
  • Divider需要不同于drivable_area的尺度偏好

RMT-PPAD启发的改进:

class AdaptiveMultiScaleFusion(nn.Module):
    """自适应多尺度融合:每个类别学习专属尺度权重"""
    
    def __init__(self, in_channels, num_classes, num_scales=4):
        super().__init__()
        self.num_classes = num_classes
        self.num_scales = num_scales
        
        # 多尺度特征提取
        self.scale_convs = nn.ModuleList([
            nn.Conv2d(in_channels, in_channels, 3, 
                     padding=rate, dilation=rate, bias=False)
            for rate in [1, 3, 6, 12]
        ])
        
        # 类别特定的尺度权重学习
        self.class_scale_weights = nn.Parameter(
            torch.ones(num_classes, num_scales) / num_scales
        )
        
    def forward(self, x):
        """
        Args:
            x: (B, C, H, W)
        Returns:
            class_features: List[(B, C, H, W)] - 每个类别的特征
        """
        # 提取多尺度特征
        multi_scale_feats = []
        for conv in self.scale_convs:
            multi_scale_feats.append(conv(x))
        multi_scale_feats = torch.stack(multi_scale_feats, dim=1)  # (B, num_scales, C, H, W)
        
        # 为每个类别加权融合
        class_features = []
        for cls_idx in range(self.num_classes):
            weights = F.softmax(self.class_scale_weights[cls_idx], dim=0)
            # (num_scales,) -> (1, num_scales, 1, 1, 1)
            weights = weights.view(1, -1, 1, 1, 1)
            # 加权求和
            cls_feat = (multi_scale_feats * weights).sum(dim=1)  # (B, C, H, W)
            class_features.append(cls_feat)
        
        return class_features

集成方案:

# 在EnhancedBEVSegmentationHead中替换ASPP

class EnhancedBEVSegmentationHead(nn.Module):
    def __init__(self, ...):
        ...
        # 替换原有ASPP
        # self.aspp = ASPP(in_channels, decoder_channels[0])
        
        # 新增自适应多尺度融合
        self.adaptive_fusion = AdaptiveMultiScaleFusion(
            in_channels=decoder_channels[0],
            num_classes=len(classes),
            num_scales=4
        )
    
    def forward(self, x, target=None):
        ...
        # ASPP后获取多尺度特征
        x = self.aspp(x)
        
        # 类别特定的多尺度特征
        class_features = self.adaptive_fusion(x)
        
        # 每个类别使用专属特征进行解码
        outputs = []
        for cls_idx, (cls_feat, classifier) in enumerate(
            zip(class_features, self.classifiers)
        ):
            decoded = self.decoder(cls_feat)
            outputs.append(classifier(decoded))
        ...

预期收益:

  • Divider可以学习偏向小尺度的权重
  • Drivable_area可以学习偏向大尺度的权重
  • 📊 预计Divider Dice Loss改善: 3-8%

4.3 动态损失权重调整

目标: 训练过程中根据各类别性能动态调整损失权重

RMT-PPAD启发: 自适应权重学习

实现方案:

class DynamicLossWeighting(nn.Module):
    """动态损失权重:根据训练进度自适应调整"""
    
    def __init__(self, num_classes, initial_weights, update_freq=100):
        super().__init__()
        self.num_classes = num_classes
        self.update_freq = update_freq
        self.iter_count = 0
        
        # 可学习的权重参数
        self.log_weights = nn.Parameter(
            torch.log(torch.tensor(list(initial_weights.values())))
        )
        
        # 移动平均的损失记录
        self.register_buffer('loss_ema', torch.zeros(num_classes))
        self.ema_decay = 0.9
    
    def forward(self, class_losses):
        """
        Args:
            class_losses: List[Tensor] - 每个类别的损失
        Returns:
            weighted_losses: 加权后的损失
        """
        self.iter_count += 1
        
        # 更新EMA
        current_losses = torch.stack([l.detach() for l in class_losses])
        self.loss_ema = (self.ema_decay * self.loss_ema + 
                        (1 - self.ema_decay) * current_losses)
        
        # 动态权重:对表现差的类别增加权重
        if self.iter_count % self.update_freq == 0:
            # 归一化损失
            normalized_losses = self.loss_ema / (self.loss_ema.mean() + 1e-6)
            # 表现差的类别权重增加
            dynamic_factor = torch.pow(normalized_losses, 0.5)
            self.log_weights.data = torch.log(
                F.softmax(self.log_weights, dim=0) * self.num_classes * dynamic_factor
            )
        
        # 应用权重
        weights = torch.exp(self.log_weights)
        weighted = [w * l for w, l in zip(weights, class_losses)]
        
        return weighted, weights

预期收益:

  • 自动增加Divider的训练关注度
  • 避免简单类别dominate训练
  • 📊 预计整体性能改善: 2-5%

🔧 中优先级优化

4.4 共享Transformer Decoder

目标: 学习RMT-PPAD的共享解码器 + 任务特定查询

当前: 检测用Transformer分割用CNN完全独立

改进方案: 统一使用Transformer通过不同query区分任务

class UnifiedTransformerDecoder(nn.Module):
    """统一Transformer解码器"""
    
    def __init__(self, ...):
        # 共享的Transformer层
        self.transformer_layers = nn.ModuleList([
            TransformerDecoderLayer(...) for _ in range(num_layers)
        ])
        
        # 任务特定的query
        self.detection_queries = nn.Embedding(num_proposals, hidden_dim)
        self.segmentation_queries = nn.Embedding(num_seg_queries, hidden_dim)

优势:

  • 更强的任务间知识共享
  • 参数效率更高
  • ⚠️ 需要重新训练,风险较大

5. 实施建议与路线图

阶段1: 快速验证 (1-2天)

目标: 验证门控适配器的有效性

  1. 实现GateControlAdapter模块
  2. 集成到BEVFusion forward流程
  3. 使用epoch_4.pth热启动训练2-3个epoch
  4. 📊 对比Epoch 5基线评估Divider改善

预期结果:

  • 如果Divider Dice降至0.48-0.50:显著成功 → 继续训练
  • 如果降至0.50-0.52:轻微改善 → 考虑叠加其他优化
  • 如果>0.52:效果不明显 → 回滚,尝试其他方案

阶段2: 深度优化 (3-5天)

前提: 阶段1验证成功

  1. 实现AdaptiveMultiScaleFusion
  2. 集成到分割头
  3. 训练完整10 epochs
  4. 📊 评估所有类别的改善

预期结果:

  • Divider目标: Dice < 0.45
  • 整体mIoU提升: 2-3%

阶段3: 进阶探索 (后续)

前提: 当前方案已达瓶颈

  1. 🔬 动态损失权重调整
  2. 🔬 统一Transformer解码器
  3. 🔬 参考RMT-PPAD的完整训练策略

6. 关键差异总结

RMT-PPAD的核心优势

  1. 显式的任务解耦: 门控机制明确处理任务冲突
  2. 自适应特征选择: 自动学习任务特定的特征表达
  3. 实时性优化: 轻量级设计,适合部署

BEVFusion的核心优势

  1. 统一的多模态表示: BEV空间天然融合Camera+LiDAR
  2. 丰富的特征增强: ASPP, Attention机制完善
  3. 成熟的训练框架: 已有大量训练经验和检查点

融合方向

最佳实践: 保留BEVFusion的多模态融合优势借鉴RMT-PPAD的任务解耦机制

BEVFusion多模态融合 + RMT-PPAD门控适配 = 最优方案
     (Camera+LiDAR)        (任务解耦)

7. 风险评估与注意事项

⚠️ 实施风险

  1. 训练不稳定

    • 新增门控网络可能需要warmup
    • 学习率需要重新调优
    • 建议从小学习率开始 (1e-5)
  2. 显存增加

    • 门控适配器增加参数量 ~5-10%
    • 自适应融合需要额外前向计算
    • 当前显存充足,风险较低
  3. 训练时间

    • 预计单次iteration增加5-10%时间
    • 从2.63s/iter → 2.8s/iter
    • 可接受范围

缓解策略

  1. 渐进式集成

    • 先验证单个模块
    • 逐步叠加优化
    • 每次保留检查点
  2. 性能监控

    • 每500 iters记录各类别loss
    • 观察门控权重分布
    • 及时发现异常

8. 结论与建议

核心建议

🎯 优先实施: 门控适配器 (GateControlAdapter)

  • 实现简单,风险低
  • 理论基础扎实
  • 可热启动验证

📊 预期效果:

  • Divider Dice Loss: 0.5142 → 0.48-0.50 (改善5-10%)
  • 其他类别: 保持或轻微改善
  • 检测性能: 基本不变

⏱️ 实施时间线:

Day 1: 实现GateControlAdapter模块 (2小时)
Day 1: 集成到BEVFusion (1小时)  
Day 1: 启动训练热启动epoch_4.pth (3分钟)
Day 2-3: 训练2-3个epochs (每epoch ~11小时)
Day 3: 评估结果,决定后续方向

下一步行动

  1. 立即可做: 实现GateControlAdapter并测试
  2. 🔄 待验证后: 实现AdaptiveMultiScaleFusion
  3. 📅 长期规划: 探索统一Transformer解码器

参考文献

  1. RMT-PPAD: Real-time Multi-task Learning for Panoptic Perception in Autonomous Driving
  2. BEVFusion: Multi-Task Multi-Sensor Fusion with Unified Bird's-Eye View Representation
  3. Multi-Task Learning Using Uncertainty to Weigh Losses
  4. GitHub: RMT-PPAD

文档生成时间: 2025-11-05 06:30 UTC
当前训练状态: Epoch 5, iter 10500/15448
Divider Dice Loss: 0.5142 (待优化)