618 lines
16 KiB
Markdown
618 lines
16 KiB
Markdown
# BEVFusion 项目架构与调用关系分析
|
||
|
||
## 项目概述
|
||
|
||
BEVFusion 是一个用于自动驾驶的多传感器融合框架,基于 MMDetection3D 构建。项目支持:
|
||
- 3D目标检测
|
||
- BEV(鸟瞰图)地图分割
|
||
- 多模态融合(相机 + 激光雷达 + 雷达)
|
||
|
||
## 项目目录结构
|
||
|
||
```
|
||
bevfusion/
|
||
├── configs/ # 配置文件(YAML格式)
|
||
│ ├── default.yaml # 基础配置
|
||
│ └── nuscenes/ # nuScenes数据集相关配置
|
||
│ ├── det/ # 检测任务配置
|
||
│ └── seg/ # 分割任务配置
|
||
├── data/ # 数据集目录
|
||
├── mmdet3d/ # 核心代码库
|
||
│ ├── apis/ # 训练/测试API
|
||
│ ├── core/ # 核心功能(bbox、points等)
|
||
│ ├── datasets/ # 数据集加载
|
||
│ ├── models/ # 模型定义
|
||
│ │ ├── backbones/ # 主干网络
|
||
│ │ ├── necks/ # 特征金字塔网络
|
||
│ │ ├── heads/ # 检测/分割头
|
||
│ │ ├── fusers/ # 多模态融合模块
|
||
│ │ ├── fusion_models/ # 融合模型(BEVFusion核心)
|
||
│ │ └── vtransforms/ # 视图转换(相机到BEV)
|
||
│ ├── ops/ # CUDA算子
|
||
│ └── utils/ # 工具函数
|
||
├── tools/ # 训练/测试脚本
|
||
│ ├── train.py # 训练入口
|
||
│ ├── test.py # 测试入口
|
||
│ └── visualize.py # 可视化工具
|
||
└── pretrained/ # 预训练模型
|
||
|
||
```
|
||
|
||
## 核心调用流程
|
||
|
||
### 1. 训练流程
|
||
|
||
```
|
||
tools/train.py (训练入口)
|
||
├── 加载配置文件 (configs/*.yaml)
|
||
├── 初始化分布式训练 (torchpack.distributed)
|
||
├── build_dataset() → mmdet3d.datasets.NuScenesDataset
|
||
│ └── 数据加载与预处理管道
|
||
├── build_model() → mmdet3d.models.BEVFusion
|
||
│ └── 构建融合模型(见下方详细结构)
|
||
└── train_model() → mmdet3d.apis.train_model
|
||
└── 训练循环、验证、保存检查点
|
||
```
|
||
|
||
### 2. 测试/推理流程
|
||
|
||
```
|
||
tools/test.py (测试入口)
|
||
├── 加载配置文件和检查点
|
||
├── build_dataset() → 测试数据集
|
||
├── build_model() → 加载训练好的模型
|
||
├── multi_gpu_test() / single_gpu_test()
|
||
│ └── 模型前向传播
|
||
└── dataset.evaluate() → 评估指标计算
|
||
```
|
||
|
||
## BEVFusion 模型架构详解
|
||
|
||
### 整体架构
|
||
|
||
```
|
||
BEVFusion (mmdet3d/models/fusion_models/bevfusion.py)
|
||
├── encoders (多模态编码器)
|
||
│ ├── camera (相机分支)
|
||
│ │ ├── backbone: 图像特征提取
|
||
│ │ ├── neck: 特征金字塔
|
||
│ │ └── vtransform: 2D特征 → BEV特征
|
||
│ ├── lidar (激光雷达分支)
|
||
│ │ ├── voxelize: 点云体素化
|
||
│ │ └── backbone: 3D稀疏卷积
|
||
│ └── radar (雷达分支 - 可选)
|
||
│ ├── voxelize: 雷达点云体素化
|
||
│ └── backbone: 特征提取
|
||
├── fuser (特征融合)
|
||
│ └── ConvFuser / AddFuser: 融合不同模态的BEV特征
|
||
├── decoder (BEV解码器)
|
||
│ ├── backbone: BEV特征增强
|
||
│ └── neck: 多尺度特征融合
|
||
└── heads (任务头)
|
||
├── object: 3D目标检测 (TransFusion/CenterPoint)
|
||
└── map: BEV地图分割
|
||
```
|
||
|
||
### 前向传播流程
|
||
|
||
```python
|
||
BEVFusion.forward()
|
||
│
|
||
├── 1. 特征提取 (extract_camera_features / extract_features)
|
||
│ │
|
||
│ ├── Camera分支:
|
||
│ │ ├── backbone(img) → 提取图像特征
|
||
│ │ │ └── ResNet / VoVNet / SwinTransformer
|
||
│ │ ├── neck(features) → FPN特征金字塔
|
||
│ │ │ └── GeneralizedLSSFPN / FPN
|
||
│ │ └── vtransform(features) → 2D → BEV转换
|
||
│ │ └── LSS / DepthLSS / AwareBEVDepth
|
||
│ │ ├── 预测深度分布
|
||
│ │ ├── 投影到3D空间
|
||
│ │ └── BEV pooling
|
||
│ │
|
||
│ ├── LiDAR分支:
|
||
│ │ ├── voxelize(points) → 点云体素化
|
||
│ │ │ └── Voxelization / DynamicScatter
|
||
│ │ └── backbone(voxels) → 3D特征提取
|
||
│ │ └── SparseEncoder (稀疏卷积)
|
||
│ │ └── VoxelResBackBone8x
|
||
│ │
|
||
│ └── Radar分支 (可选):
|
||
│ └── 类似LiDAR分支处理
|
||
│
|
||
├── 2. 特征融合 (fuser)
|
||
│ └── ConvFuser / AddFuser
|
||
│ └── 融合camera_features + lidar_features → unified_bev_features
|
||
│
|
||
├── 3. BEV解码 (decoder)
|
||
│ ├── backbone(unified_bev) → BEV特征增强
|
||
│ │ └── SECOND / ResNet
|
||
│ └── neck(features) → 多尺度特征
|
||
│ └── SECONDFPN
|
||
│
|
||
└── 4. 任务头 (heads)
|
||
│
|
||
├── 训练模式:
|
||
│ ├── object head → 预测 + 计算损失
|
||
│ │ └── TransFusionHead / CenterHead
|
||
│ │ ├── heatmap分类
|
||
│ │ ├── 中心偏移
|
||
│ │ ├── 尺寸回归
|
||
│ │ └── 旋转角度
|
||
│ └── map head → 分割 + 计算损失
|
||
│ └── VanillaSegHead
|
||
│
|
||
└── 推理模式:
|
||
├── object head → 后处理 → 3D检测框
|
||
└── map head → 分割结果
|
||
```
|
||
|
||
## 关键组件详解
|
||
|
||
### 1. Encoders (编码器)
|
||
|
||
#### Camera Encoder
|
||
```
|
||
作用: 将多视角相机图像转换为统一的BEV特征
|
||
|
||
流程:
|
||
Input: (B, N, C, H, W) - N个相机视图
|
||
↓
|
||
Backbone (ResNet/SwinTransformer)
|
||
↓ 提取图像特征
|
||
Neck (FPN)
|
||
↓ 多尺度特征融合
|
||
VTransform (LSS/BEVDepth)
|
||
↓ 2D→BEV转换
|
||
├── 预测深度分布
|
||
├── 生成3D frustum特征
|
||
└── BEV pooling (关键优化)
|
||
↓
|
||
Output: (B, C', H', W') - BEV特征图
|
||
|
||
关键文件:
|
||
- mmdet3d/models/backbones/resnet.py
|
||
- mmdet3d/models/necks/generalized_lss.py
|
||
- mmdet3d/models/vtransforms/lss.py
|
||
- mmdet3d/ops/bev_pool/ (高效BEV pooling算子)
|
||
```
|
||
|
||
#### LiDAR Encoder
|
||
```
|
||
作用: 将激光雷达点云转换为BEV特征
|
||
|
||
流程:
|
||
Input: List[Points] - 原始点云
|
||
↓
|
||
Voxelization (体素化)
|
||
↓ 将点云转为规则网格
|
||
├── 硬体素化: Voxelization
|
||
└── 动态体素化: DynamicScatter
|
||
↓
|
||
Sparse Backbone (3D稀疏卷积)
|
||
↓ 3D特征提取
|
||
└── SparseEncoder (VoxelResBackBone8x)
|
||
└── 多层稀疏卷积
|
||
↓
|
||
Output: (B, C', H', W') - BEV特征图
|
||
|
||
关键文件:
|
||
- mmdet3d/ops/voxel/voxelize.py
|
||
- mmdet3d/models/backbones/sparse_encoder.py
|
||
- mmdet3d/ops/spconv/ (稀疏卷积算子)
|
||
```
|
||
|
||
### 2. Fuser (融合器)
|
||
|
||
```
|
||
作用: 融合不同模态的BEV特征
|
||
|
||
类型:
|
||
├── ConvFuser (卷积融合)
|
||
│ └── 使用卷积层融合不同通道数的特征
|
||
│ Input: [camera_feat(C1,H,W), lidar_feat(C2,H,W)]
|
||
│ Process: Conv → Concat → Conv
|
||
│ Output: fused_feat(C_out,H,W)
|
||
│
|
||
└── AddFuser (简单相加)
|
||
└── 直接相加(要求通道数相同)
|
||
Output: camera_feat + lidar_feat
|
||
|
||
关键文件:
|
||
- mmdet3d/models/fusers/conv.py
|
||
- mmdet3d/models/fusers/add.py
|
||
```
|
||
|
||
### 3. Decoder (解码器)
|
||
|
||
```
|
||
作用: 对融合后的BEV特征进行增强和多尺度处理
|
||
|
||
流程:
|
||
Fused BEV Features
|
||
↓
|
||
Backbone (SECOND/ResNet)
|
||
↓ 特征增强
|
||
└── 多层卷积和残差连接
|
||
↓
|
||
Neck (SECONDFPN)
|
||
↓ 多尺度特征金字塔
|
||
└── 上采样 + 融合不同层特征
|
||
↓
|
||
Multi-scale BEV Features
|
||
└── 用于检测和分割
|
||
|
||
关键文件:
|
||
- mmdet3d/models/backbones/second.py
|
||
- mmdet3d/models/necks/second.py
|
||
```
|
||
|
||
### 4. Heads (任务头)
|
||
|
||
#### Object Detection Head (TransFusion)
|
||
```
|
||
作用: 从BEV特征预测3D目标检测框
|
||
|
||
流程:
|
||
BEV Features
|
||
↓
|
||
TransFusionHead
|
||
├── Heatmap分支 (分类)
|
||
│ └── Conv → Sigmoid → 目标中心热图
|
||
├── Bbox回归分支
|
||
│ ├── Center offset (中心偏移)
|
||
│ ├── Size (宽高长)
|
||
│ ├── Rotation (旋转角度)
|
||
│ └── Velocity (速度 - 可选)
|
||
└── Transformer Decoder (可选)
|
||
└── Query-based检测优化
|
||
|
||
训练:
|
||
└── 计算损失
|
||
├── FocalLoss (heatmap)
|
||
├── L1Loss (bbox回归)
|
||
└── 其他辅助损失
|
||
|
||
推理:
|
||
└── get_bboxes()
|
||
├── 提取热图峰值
|
||
├── 解码bbox参数
|
||
├── NMS (非极大值抑制)
|
||
└── 输出最终检测结果
|
||
|
||
关键文件:
|
||
- mmdet3d/models/heads/bbox/transfusion.py
|
||
- mmdet3d/models/heads/bbox/centerpoint.py
|
||
```
|
||
|
||
#### Map Segmentation Head
|
||
```
|
||
作用: 对BEV特征进行语义分割
|
||
|
||
流程:
|
||
BEV Features
|
||
↓
|
||
VanillaSegHead
|
||
└── Conv layers → Upsample → Conv
|
||
└── 输出每个类别的logits
|
||
↓
|
||
训练: CrossEntropyLoss
|
||
推理: Argmax → 分割mask
|
||
|
||
关键文件:
|
||
- mmdet3d/models/heads/segm/vanilla.py
|
||
```
|
||
|
||
## 数据流图
|
||
|
||
### 训练时数据流
|
||
|
||
```
|
||
NuScenes Dataset
|
||
├── 多视角图像 (6个相机)
|
||
├── LiDAR点云
|
||
├── Radar点云 (可选)
|
||
├── 标注 (3D bbox, 分割mask)
|
||
└── 相机/LiDAR标定信息
|
||
↓
|
||
Data Pipeline (数据增强)
|
||
├── LoadMultiViewImageFromFiles
|
||
├── LoadPointsFromFile
|
||
├── RandomFlip3D
|
||
├── GlobalRotScaleTrans
|
||
└── Normalize, Pad等
|
||
↓
|
||
Collate (批处理)
|
||
↓
|
||
BEVFusion Model
|
||
├── forward() → 前向传播
|
||
├── loss计算
|
||
│ ├── detection loss
|
||
│ ├── segmentation loss
|
||
│ └── depth loss (如使用BEVDepth)
|
||
└── backward() → 反向传播
|
||
↓
|
||
Optimizer更新参数
|
||
```
|
||
|
||
### 推理时数据流
|
||
|
||
```
|
||
输入数据
|
||
├── 图像: (B, N_cam, 3, H, W)
|
||
└── 点云: List[Points(N_points, C)]
|
||
↓
|
||
BEVFusion.forward()
|
||
↓
|
||
输出
|
||
├── 3D检测: boxes_3d, scores_3d, labels_3d
|
||
└── 分割: masks_bev
|
||
↓
|
||
后处理
|
||
├── NMS
|
||
├── 坐标系转换
|
||
└── 可视化
|
||
```
|
||
|
||
## 配置系统
|
||
|
||
### 配置继承关系
|
||
|
||
```
|
||
configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/convfuser.yaml
|
||
├── 继承: ../default.yaml
|
||
│ ├── 继承: ../../default.yaml
|
||
│ │ ├── 继承: ../../../default.yaml
|
||
│ │ │ └── 继承: configs/default.yaml
|
||
│ │ │ └── 基础配置(数据路径、训练参数等)
|
||
│ │ └── TransFusion特定配置
|
||
│ └── camera+lidar融合配置
|
||
└── ConvFuser配置
|
||
|
||
配置项:
|
||
├── model: 模型结构定义
|
||
│ ├── encoders: {camera, lidar, radar}
|
||
│ ├── fuser: 融合器类型和参数
|
||
│ ├── decoder: 解码器配置
|
||
│ └── heads: 任务头配置
|
||
├── data: 数据集配置
|
||
│ ├── train/val/test: 数据集路径和pipeline
|
||
│ └── samples_per_gpu, workers_per_gpu
|
||
├── optimizer: 优化器配置
|
||
├── lr_config: 学习率调度
|
||
├── runner: 训练epoch数
|
||
└── evaluation: 评估配置
|
||
```
|
||
|
||
## 关键算子和优化
|
||
|
||
### 1. BEV Pooling (核心优化)
|
||
```
|
||
位置: mmdet3d/ops/bev_pool/
|
||
|
||
作用: 高效地将2D图像特征投影到BEV空间
|
||
优化: CUDA实现,相比原始LSS快40x
|
||
|
||
原理:
|
||
对于每个图像特征点:
|
||
1. 根据深度分布采样多个深度值
|
||
2. 投影到3D空间 (frustum)
|
||
3. 转换到LiDAR坐标系
|
||
4. 映射到BEV网格
|
||
5. 累加特征 (pooling)
|
||
```
|
||
|
||
### 2. Sparse Convolution (稀疏卷积)
|
||
```
|
||
位置: mmdet3d/ops/spconv/
|
||
|
||
作用: 对稀疏的体素化点云进行高效卷积
|
||
优化: 只计算非空体素,节省计算和内存
|
||
|
||
关键操作:
|
||
- SparseConv3d: 3D稀疏卷积
|
||
- SubMConv3d: 子流形稀疏卷积
|
||
- SparseInverseConv3d: 稀疏反卷积
|
||
```
|
||
|
||
### 3. Voxelization (体素化)
|
||
```
|
||
位置: mmdet3d/ops/voxel/
|
||
|
||
类型:
|
||
├── Hard Voxelization (硬体素化)
|
||
│ └── 固定每个体素最多容纳K个点
|
||
│ └── 超过K个点的取前K个或随机采样
|
||
│
|
||
└── Dynamic Voxelization (动态体素化)
|
||
└── 不限制每个体素点数
|
||
└── 使用scatter操作聚合
|
||
```
|
||
|
||
## 损失函数
|
||
|
||
### Detection Loss
|
||
```
|
||
TransFusion Head:
|
||
├── FocalLoss (heatmap)
|
||
│ └── 类别分类损失
|
||
├── L1Loss (bbox regression)
|
||
│ ├── center loss
|
||
│ ├── size loss
|
||
│ └── rotation loss
|
||
└── IoULoss (可选)
|
||
└── 3D IoU损失
|
||
```
|
||
|
||
### Segmentation Loss
|
||
```
|
||
Segmentation Head:
|
||
└── CrossEntropyLoss
|
||
└── 像素级分类损失
|
||
```
|
||
|
||
### Depth Loss (如使用BEVDepth)
|
||
```
|
||
BEVDepth VTransform:
|
||
└── BinaryCrossEntropy / KLDivergence
|
||
└── 深度预测监督
|
||
```
|
||
|
||
## 评估指标
|
||
|
||
### 3D Object Detection (nuScenes)
|
||
```
|
||
指标:
|
||
├── mAP (mean Average Precision)
|
||
│ └── 不同距离和IoU阈值下的AP
|
||
├── NDS (nuScenes Detection Score)
|
||
│ └── 综合指标: mAP + 其他属性
|
||
├── mATE (mean Average Translation Error)
|
||
├── mASE (mean Average Scale Error)
|
||
├── mAOE (mean Average Orientation Error)
|
||
├── mAVE (mean Average Velocity Error)
|
||
└── mAAE (mean Average Attribute Error)
|
||
```
|
||
|
||
### BEV Map Segmentation
|
||
```
|
||
指标:
|
||
└── mIoU (mean Intersection over Union)
|
||
└── 各类别IoU的平均值
|
||
```
|
||
|
||
## 扩展和自定义
|
||
|
||
### 添加新的Backbone
|
||
```python
|
||
# 1. 在 mmdet3d/models/backbones/ 中实现
|
||
@BACKBONES.register_module()
|
||
class MyBackbone(nn.Module):
|
||
def __init__(self, ...):
|
||
...
|
||
def forward(self, x):
|
||
...
|
||
|
||
# 2. 在 __init__.py 中导入
|
||
# 3. 在配置文件中使用
|
||
model:
|
||
encoders:
|
||
camera:
|
||
backbone:
|
||
type: MyBackbone
|
||
...
|
||
```
|
||
|
||
### 添加新的Fuser
|
||
```python
|
||
# 在 mmdet3d/models/fusers/ 中实现
|
||
@FUSERS.register_module()
|
||
class MyFuser(nn.Module):
|
||
...
|
||
```
|
||
|
||
### 添加新的Head
|
||
```python
|
||
# 在 mmdet3d/models/heads/ 中实现
|
||
@HEADS.register_module()
|
||
class MyHead(nn.Module):
|
||
...
|
||
```
|
||
|
||
## 性能优化建议
|
||
|
||
### 训练优化
|
||
```
|
||
1. 使用混合精度训练 (FP16)
|
||
└── 配置: fp16 = dict(loss_scale=512.)
|
||
|
||
2. 梯度累积
|
||
└── 小batch size时模拟大batch
|
||
|
||
3. 分布式训练
|
||
└── torchpack dist-run -np [num_gpus]
|
||
|
||
4. 数据加载优化
|
||
└── workers_per_gpu: 4-8
|
||
└── persistent_workers: True
|
||
```
|
||
|
||
### 推理优化
|
||
```
|
||
1. TensorRT部署
|
||
└── 参考: NVIDIA CUDA-BEVFusion
|
||
|
||
2. 批处理推理
|
||
└── samples_per_gpu > 1
|
||
|
||
3. 模型剪枝和量化
|
||
└── INT8量化可达25fps (Jetson Orin)
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
### Q1: 如何使用单模态(仅camera或仅lidar)?
|
||
```yaml
|
||
# 仅使用camera:
|
||
model:
|
||
encoders:
|
||
camera: {...}
|
||
# lidar: null # 注释掉或设为null
|
||
fuser: null # 不使用fuser
|
||
```
|
||
|
||
### Q2: 如何添加新的数据集?
|
||
```python
|
||
# 1. 继承 Custom3DDataset
|
||
@DATASETS.register_module()
|
||
class MyDataset(Custom3DDataset):
|
||
...
|
||
|
||
# 2. 实现数据加载和评估方法
|
||
# 3. 准备数据info文件
|
||
# 4. 在配置中使用
|
||
```
|
||
|
||
### Q3: 如何可视化中间特征?
|
||
```python
|
||
# 在模型forward中添加:
|
||
import torch
|
||
torch.save(features, 'features.pth')
|
||
|
||
# 或使用tensorboard:
|
||
from torch.utils.tensorboard import SummaryWriter
|
||
writer.add_image('bev_features', features)
|
||
```
|
||
|
||
## 总结
|
||
|
||
### 核心创新点
|
||
1. **统一BEV表示**: 在BEV空间融合多模态特征
|
||
2. **高效BEV Pooling**: CUDA优化,速度提升40x
|
||
3. **多任务支持**: 检测和分割共享backbone
|
||
4. **模块化设计**: 易于扩展和自定义
|
||
|
||
### 主要组件调用关系
|
||
```
|
||
Entry (train.py/test.py)
|
||
↓
|
||
BEVFusion Model
|
||
├── Camera Encoder → BEV Features
|
||
├── LiDAR Encoder → BEV Features
|
||
├── Fuser → Unified BEV
|
||
├── Decoder → Enhanced BEV
|
||
└── Heads → Predictions
|
||
```
|
||
|
||
### 推荐学习路径
|
||
1. 理解BEV表示和视图转换
|
||
2. 学习稀疏卷积和体素化
|
||
3. 研究TransFusion检测head
|
||
4. 深入CUDA算子优化
|
||
5. 实验不同配置和模态组合
|
||
|
||
---
|
||
生成时间: 2025-10-16
|
||
|