MV2DFusion 3D-BEV检测学习教程

MV2DFusion 详细讲解教程

核心思想:3D Detection = 图像分支 ⊕ 点云分支 ⊕ Fusion Transformer
主要代码文件mv2dfusion.py · mv2dfusion_head.py · mv2dfusion_transformer.py · image_distribution_query_generator.py · point_cloud_query_generator.py · detector_wrapper.py


目录

  1. 整体架构与训练流程

  2. 数据输入

  3. 图像分支

  4. [2D 检测与 Proposal 生成](#2D 检测与 Proposal 生成)

  5. [RoIAlign 多尺度选层](#RoIAlign 多尺度选层)

  6. [Image Query 生成(25 个 3D 候选点)](#Image Query 生成(25 个 3D 候选点))

  7. 深度监督机制

  8. 点云分支(FSDV2)

  9. [Fusion Head:Query 组装](#Fusion Head:Query 组装)

  10. [Fusion Transformer Decoder](#Fusion Transformer Decoder)

  11. 加强与抑制机制

  12. 损失函数汇总

  13. 典型配置参数速查

  14. 维度追踪速查表

  15. [附录:关键概念 FAQ](#附录:关键概念 FAQ)


1. 整体架构与训练流程

MV2DFusion 是一个多模态 3D 目标检测框架,三路并行:

| 分支 | 输入 | 输出 | 核心机制 |

|------|------|------|----------|

| 图像分支 | 多视图 RGB | 图像 Query(深度分布) | Faster R-CNN + 射线采样 |

| 点云分支 | LiDAR 点云 | 点云 Query(精确 3D) | SparseConv + Vote + FSDV2 |

| 融合分支 | 双分支 Query | 3D BBox | 6 层 Transformer Decoder |

1.1 训练主链路

入口在 mv2dfusion.py

复制代码
MV2DFusion.forward_train

├─ extract_img_feat → 图像特征(P2~P6 + P4 时序)

└─ forward_pts_train(每帧)

├─ forward_roi_head_train → 2D 检测训练(有梯度)

├─ forward_roi_head → 2D 推理出 proposal(no_grad)

├─ complement_2d_gt → GT 补框

├─ extract_roi_feats → RoIAlign

├─ img_query_generator → 图像 Query(25 depth bins)

├─ pts_backbone

│ └─ pts_query_generator → 点云 Query

└─ fusion_bbox_head → 6 层 Transformer → 3D 预测

Fusion Head 实现在 mv2dfusion_head.py ,Transformer 实现在 mv2dfusion_transformer.py

1.2 架构示意图

复制代码
┌─────────────────────────────────────┐

│ 数据输入 │

│ 多视图图像 + LiDAR + 3D/2D GT │

└──────────────┬──────────────────────┘

│

┌────────────────────┼────────────────────┐

▼ ▼ │

┌───────────────┐ ┌───────────────┐ │

│ 图像分支 │ │ 点云分支 │ │

│ ResNet + FPN │ │ FSDV2 │ │

│ 2D 检测 │ │ Vote + Seg │ │

│ ImageQueryGen │ │ PtsQueryGen │ │

└───────┬───────┘ └───────┬───────┘ │

└────────┬───────────┘ │

▼ │

┌─────────────────┐ │

│ mv2dfusion_head │ ← Fusion Transformer│

└────────┬────────┘ │

▼ │

3D BBox 输出 │

2. 数据输入

典型多模态 3D 检测数据集需包含:

| 字段 | 说明 |

|------|------|

| img | 多视图图像 [B, T, V, 3, H, W] |

| points | LiDAR 点云,每帧 [N_pts, C] |

| gt_bboxes_3d / gt_labels_3d | 3D GT |

| gt_bboxes / gt_labels | 2D GT(每相机一个 list) |

| depths | 2D GT 深度(相机坐标系 Z,用于 depth loss) |

| intrinsics / extrinsics / lidar2img | 标定 |

示例规模(7 相机、640×1600、单帧):

| 参数 | 典型值 |

|------|--------|

| batch_size B | 2~8 |

| 相机数 V | 6~7 |

| pc_range | 约 ±50m × ±25m × ±4m |

| queue_length T | 1(可扩展多帧) |

depths 来源

  • 2D 标注中的 cam_depth / depth 字段

  • 或由 3D 框投影脚本生成:8 角点投影到图像后,取相机坐标系 Z 均值


3. 图像分支

3.1 特征提取

文件mv2dfusion.pyextract_img_feat

复制代码
img [B*V, 3, H, W]

→ GridMask(可选)

→ img_backbone(如 ResNet50)→ C2~C5

→ img_neck(FPN)→ P2~P6,统一 256 通道

两个返回值

| 返回值 | 内容 | 用途 |

|--------|------|------|

| img_feats | 单层(position_level 指定,通常 P4) | 时序 memory |

| img_feats_for_det | P2~P6 全层 | 2D 检测 + Fusion Cross-Attn |

FPN 层与尺寸 (以输入 640×1600、position_level=2 即 P4 为例):

| 层级 | stride | 空间尺寸(约) | 用途 |

|------|--------|---------------|------|

| P2 | 4 | 160×400 | 2D RPN/RoI、RoIAlign |

| P3 | 8 | 80×200 | Fusion Cross-Attn |

| P4 | 16 | 40×100 | 时序 memory + Fusion Cross-Attn |

| P5 | 32 | 20×50 | Fusion Cross-Attn |

| P6 | 64 | 10×25 | Fusion Cross-Attn |

3.2 Fusion Head 如何使用图像特征

文件mv2dfusion_head.pyforward

使用 P3~P6(跳过 P2),每层经 MLN 做相机内外参对齐后 flatten:

复制代码
feat_flatten_img: [B*V, Σ(Hi×Wi), 256]

MLN 输入 14 维 = 内参 fx,fy + 外参 3×4 矩阵。


4. 2D 检测与 Proposal 生成

4.1 数据准备

文件mv2dfusion.pyprepare_detection_data

[B, V, ...] 展平为 B×V 个样本,供 Faster R-CNN 逐 view 处理。

4.2 训练分支(有梯度)

文件mv2dfusion.pyforward_roi_head_train

包装detector_wrapper.pyTwoStageDetectorWrapper.forward_train_w_feat

RPN
  • 多层 FPN 上生成 anchor,预测 fg/bg + bbox delta

  • 采样 256 个 anchor 算 loss

  • 产出约 1000 proposals / view

RoI Head
  • RoIAlign 7×7

  • 采样 512 个 RoI

  • 多类分类 + bbox 回归

4.3 RPN 的 fg/bg 详解

RPN 只有二分类,没有类别。

detector_wrapper.py 中 RPN 调用时 gt_labels=None,只用 gt_bboxes

| | RPN | RoI Head |

|--|-----|----------|

| 分类 | fg/bg(1 sigmoid) | num_classes 类 |

| 用 GT 类别? | | |

| fg 判定 | IoU ≥ 0.7 | IoU ≥ 0.5 |

复制代码
best_iou ≥ 0.7 → fg

best_iou < 0.3 → bg

0.3 ~ 0.7 → ignore

4.4 推理分支(no_grad)

文件mv2dfusion.pyforward_pts_train

python 复制代码
losses_det2d = forward_roi_head_train(...) # 有梯度



self.eval()

with torch.no_grad():

dets = forward_roi_head(...) # 推理

dets = complement_2d_gt(dets, gt) # GT 补框

rois = bbox2roi(dets)

self.train()

| 设计 | 原因 |

|------|------|

| 训练有梯度 | 2D 检测器持续优化 |

| proposal 无梯度 | NMS 不可微;避免噪声干扰 Query/Fusion |

| GT 补框(IoU<0.6) | 2D 漏检仍保留 3D 监督 |

4.5 空 GT 保护(多卡训练)

文件mv2dfusion.pyforward_roi_head_train

全 batch 无 2D GT 时,用假框 forward 并将 loss×0,保证 DDP 各 rank 计算图一致。


5. RoIAlign 多尺度选层

文件mv2dfusion.pyextract_roi_feats

实现 :MMDet SingleRoIExtractor

复制代码
scale = sqrt((x2-x1) * (y2-y1))

level = floor(log2(scale / 56)) # finest_scale=56

→ 在对应 P2~P5 层做 RoIAlign → [N, 256, 7, 7] → AvgPool → [N, 256]

| level | stride | scale(像素) | 典型目标 |

|-------|--------|--------------|---------|

| 0 | 4 | < 112 | 小目标 |

| 1 | 8 | 112~224 | 中等 |

| 2 | 16 | 224~448 | 车辆 |

| 3 | 32 | ≥ 448 | 大目标 |


6. Image Query 生成(25 个 3D 候选点)

文件image_distribution_query_generator.py(基类:image_singple_point_query_generator.py

典型配置prob_bin=25, depth_range=[0.1, 90]

6.1 流程

复制代码
RoI feat [N, 256]

→ + 内参 MLP 融合

→ fc_center → [N, 25, 3] (每 bin: xy offset + depth logit)

→ softmax(depth_logits) → depth_prob [N, 25]

→ center2lidar(xy, d_bins) → [N, 25, 3]

→ cat(..., depth_prob) → dyn_query [N, 25, 4]

6.2 反投影

文件image_singple_point_query_generator.pycenter2lidar

python 复制代码
center_lidar = inv(K @ extrinsic) @ [xy*d, d, 1]

每个 bin 使用网络预测的 xy + 固定 深度网格 d_bins,权重来自 depth_prob

6.3 gt_mono_loss 双路径

文件mv2dfusion.pyforward_pts_train

| 路径 | proposals | 用途 |

|------|-----------|------|

| 第一次 | 检测框 + GT 补框 | Fusion 前向 |

| 第二次 | 纯 GT 2D 框 | depth / 3D 辅助 loss |


7. 深度监督机制

文件image_distribution_query_generator.pydepth_loss

7.1 监督对象

| 量 | 直接监督? | 方式 |

|----|-----------|------|

| depth_logits | ✅ | bin 分类 CE(soft label) |

| xy offset | ❌ | 间接:3D 辅助 loss + Fusion loss |

| 反投影 3D 点 | ❌ | 间接:Fusion 端到端 |

7.2 depth_loss 流程

复制代码
1. proposal 与 GT 2D 框 IoU≥0.6 一对一匹配

2. 取 GT cam_depth

3. 连续深度 → bin 索引(如 45.3m → bin 12.3)

4. Soft label:bin12 权重 0.7,bin13 权重 0.3

5. 加权 CE on depth_logits [N, 25]

文件mv2dfusion.py → loss 汇总为 imgqg.d_loss,通常再乘 loss_weight_3d


8. 点云分支(FSDV2)

8.1 流程

复制代码
点云 → 体素化 → SparseConv UNet

→ VoteSegHead(分割 + 投票)

→ 虚拟体素 → FSDV2Head → BEV NMS

→ point_cloud_query_generator.py

8.2 输出

| 输出 | 用途 |

|------|------|

| pts_query_center | 点云 Query 3D 中心 |

| pts_query_feat | 点云 Query 特征 |

| pts_feat / pts_pos | Cross-Attn 的 BEV KV |

8.3 与图像 Query 对比

| | 图像 Query | 点云 Query |

|--|-----------|-----------|

| 位置精度 | 低(深度不确定) | 高 |

| 特征来源 | RoI 视觉 | FSD 几何 |

| 数量 | 多(~数百) | 少(~数十) |


9. Fusion Head:Query 组装

文件mv2dfusion_head.pyforward

9.1 拼接

点云 query 在前 ,图像 query 在后

python 复制代码
reference_points = cat([pts_ref, img_ref], dim=1)

tgt = cat([pts_tgt, img_tgt], dim=1)

9.2 每个 Query 的组成

| 组件 | 变量 | 含义 |

|------|------|------|

| 内容特征 | tgt | 256 维语义(RoI / FSD 特征注入) |

| 3D 坐标 | reference_points | 锚点位置 |

| 位置编码 | query_pos | sin/cos 3D 编码;图像 query 额外编码 25-bin 深度分布 |

图像 query 动态 query 组装见 gen_dynamic_query ;点云见 gen_pts_query


10. Fusion Transformer Decoder

文件mv2dfusion_transformer.py

Head 调用mv2dfusion_head.pyself.transformer(...)

6 层,每层:Self-Attn → Norm → Cross-Attn → Norm → FFN → Norm

10.1 Self-Attention

文件mv2dfusion_transformer.pyMV2DFusionTransformerDecoderLayer

复制代码
Q = content + query_pos

K = content + query_pos

V = content

所有 img/pts query 同一序列,位置近则 attention 权重大,交换 256 维特征

10.2 Cross-Attention(MixedCrossAttention)

13 个 key_points

配置num_pts=13

python 复制代码
key_points = reference_point + Linear(instance_feature) # [B, n_q, 13, 3]

13 个可学习 3D 采样点,用于:

  • 图像侧:投影到多相机 FPN → Deformable Attention

  • 点云侧:投影 BEV → PETR Attention

深度迭代更新(图像 query)

文件mv2dfusion_transformer.pyMV2DFusionTransformerDecoder

每层 decoder 后:

python 复制代码
dyn_q_logits += dyn_q_prob_branch[layer](query)

dyn_q_probs = softmax(dyn_q_logits)

reference_points[dyn_q_mask] = probs @ dyn_q_coords

10.3 预测

文件mv2dfusion_head.pycls_branches / reg_branches

每层输出分类 + 8D bbox,6 层中间监督。


11. 加强与抑制机制

非硬编码规则,由 Attention + 匈牙利匹配 + NMS 共同产生。

11.1 加强

位置相近的 img_q 与 pts_q 在 Self-Attn 中互传 content 特征;Cross-Attn 从双模态特征图取证。

11.2 抑制

| 机制 | 文件 | 效果 |

|------|------|------|

| 匈牙利匹配 | mv2dfusion_head.py | 1 GT ↔ 1 query,其余 background |

| Focal Loss | 同上 | 未匹配 query 分数压低 |

| BEV NMS | mv2dfusion_head.py | 推理去重 |

同一物体若 img_q 与 pts_q 都靠近,通常只有一个匹配 GT,另一个被标 background。


12. 损失函数汇总

文件mv2dfusion.pyforward_pts_train(loss 汇总)

复制代码
Total ≈ L_fusion × w_3d

+ L_pts × w_pts × w_3d

+ L_det2d

+ L_imgqg × w_3d

| 前缀 | 来源模块 | 内容 |

|------|----------|------|

| fusion.* | mv2dfusion_head.py | 3D cls + bbox(匈牙利) |

| pts.* | FSDV2 backbone | vote + seg + det |

| det2d.* | detector_wrapper.py | RPN + RoI |

| imgqg.d_loss | image_distribution_query_generator.py | depth bin CE |

| imgqg.loss_cls/bbox | 同上 | 初步 3D 辅助 |


13. 典型配置参数速查

以下为一组常见实验配置,可按数据集调整:

| 参数 | 典型值 |

|------|--------|

| img backbone | ResNet50 + FPN |

| position_level | 2(P4) |

| num_cams | 6~7 |

| prob_bin | 25 |

| depth_range | [0.1, 90] m |

| fusion num_query | 100~300(静态上限,实际动态) |

| decoder num_layers | 6 |

| embed_dims | 256 |

| num_pts(cross-attn) | 13 |

| num_levels(cross-attn) | 4 |

| loss_weight_3d | 0.1~1.0 |

| gt_mono_loss | True(推荐) |

| post_bev_nms_thr | 0.2 |

| DN scalar | 10 |

| memory_len | 6×256 ~ 7×256 |


14. 维度追踪速查表

B=2, V=6, H=640, W=1600 为例:

图像

| 阶段 | Shape |

|------|-------|

| img | [12, 3, 640, 1600] |

| FPN P4 | [12, 256, 40, 100] |

| roi_feats | [N_rois, 256] |

| dyn_query[b] | [N_b, 25, 4] |

| feat_flatten_img | [12, ~21250, 256] |

点云

| 阶段 | Shape |

|------|-------|

| pts_query | [B, N_pts_q, 256] |

| pts_feat(KV) | [B, max_bev, 256] |

Fusion

| 变量 | Shape |

|------|-------|

| tgt | [B, num_query, 256] |

| reference_points | [B, num_query, 3] |

| key_points | [B, n_q, 13, 3] |

| outs_dec | [6, B, num_query, 256] |


附录:关键概念 FAQ

Q:RPN fg 和类别有关吗?

A:无关。RPN 仅 fg/bg;类别在 RoI Head 分。

Q:proposal 为何 no_grad?

A:NMS 不可微;避免 2D 检测噪声干扰 Query/Fusion。

Q:深度监督监督什么?

A:depth_logits 的 25-bin 分类,不是 3D 坐标 L1。

Q:Self-Attn 的 query 是位置还是特征?

A:两者:tgt=内容特征,query_pos=位置编码。

Q:13 个 key_points 是什么?

A:Cross-Attn 的 3D 采样点,不是 Self-Attn 的 query。

Q:加强/抑制是硬规则吗?

A:否。Attention 软融合 + 匈牙利 1-to-1 + NMS。

Q:相关文件一览?

| 模块 | 文件 |

|------|------|

| 主检测器 | mv2dfusion.py |

| Fusion Head | mv2dfusion_head.py |

| Transformer | mv2dfusion_transformer.py |

| 图像 Query | image_distribution_query_generator.py |

| 点云 Query | point_cloud_query_generator.py |

| 2D 检测包装 | detector_wrapper.py |

| Query 基类 | image_singple_point_query_generator.py |


❤ 喜欢帮忙点赞 + 收藏,感谢!

相关推荐
Yunzenn6 小时前
深度分析字节最新研究cola-DLM第 06 章:分块因果 DiT 先验 —— 在隐空间里做 Flow Matching
人工智能·rnn·深度学习·神经网络·生成对抗网络·架构·transformer
云飞云共享云桌面6 小时前
企业降本增效新思路:SolidWorks共享部署实战经验分享
运维·服务器·网络·人工智能·3d·自动化
xier_ran6 小时前
【infra之路】Transformer 核心计算流
人工智能·深度学习·transformer
先把态度摆正7 小时前
NAVSIM数据驱动仿真平台
自动驾驶
惊鸿一博7 小时前
大语言模型_概念_Transformer_位置编码 RoPE 解释
人工智能·语言模型·transformer
元让_vincent7 小时前
论文Review SLAM Super-LIO | RA-L 2026 | 面向嵌入式平台的高效 LiDAR-Inertial Odometry 系统
3d·性能提升·kdtree·激光slam
YOLO数据集集合8 小时前
光伏板缺陷检测数据集|红外可见光双模态|无人机光伏巡检|智慧电网光伏识别数据集
开发语言·yolo·目标检测·无人机
YOLO数据集集合9 小时前
无人机航拍智慧工地工程装备检测数据集|6700+图像9类设备YOLO标注|高空视角目标检测研究
人工智能·yolo·目标检测·计算机视觉·无人机
机器学习之心9 小时前
顶刊《KBS》算法应用,PIMO-Transformer-LSTM-ABKDE:投影迭代优化算法概率区间预测,报告+代码
算法·lstm·transformer·投影迭代优化算法