BEVFusion-mit复现与实践(nuscenes数据集)

一、CUDA版本11.1

二、创建虚拟环境并激活

conda create -n bevfusion python=3.8
conda activate bevfusion

三、安装pytorch

1、下载cuda对应版本的torch和torchvision到本地文件夹

下载地址:https://download.pytorch.org/whl/torch_stable.html

在这里插入图片描述
2、进入安装包文件夹安装:

pip install torch-1.10.0+cu111-cp38-cp38-linux_x86_64.whl
pip install torchvision-0.11.0+cu111-cp38-cp38-linux_x86_64.whl

3、验证:

python
import torch
print(torch.__version__)
#1.10.0+cu111
import torchvision
print(torchvision.__version__)
#0.11.0+cu111

四、安装openmpi

1、下载安装:

wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.4.tar.gz
tar zxf openmpi-4.1.4.tar.gz

cd openmpi-4.1.4
./configure --prefix=/usr/local/openmpi
make -j8
sudo make install

2、 配置环境~/.bashrc

MPI_HOME=/usr/local/openmpi
OMPI_MCA_opal_cuda_support=true
export PATH=${MPI_HOME}/bin:$PATH
export LD_LIBRARY_PATH=${MPI_HOME}/lib:$LD_LIBRARY_PATH
export MANPATH=${MPI_HOME}/share/man:$MANPATH

3、测试

cd openmpi-4.1.4/examples
make
mpirun -np 4 hello_c

出现以下:
在这里插入图片描述

五、安装功能包

conda 虚拟环境下

pip install mmcv-full==1.4.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.10.0/index.html
pip install mmdet==2.20.0
conda install openmpi
conda install mpi4py
pip install Pillow==8.4.0
pip install tqdm
pip install torchpack
pip install nuscenes-devkit
pip install ninja
pip install numpy==1.19
pip install numba==0.48.0
pip install shapely==1.8.0

六、源码下载

源码下载地址:https://github.com/mit-han-lab/bevfusion

git clone https://github.com/mit-han-lab/bevfusion.git

七、参数修改与编译

1、更改indice_cuda.cu

在mmdet3d/ops/spconv/src/indice_cuda.cu下,将里面的4096都改成256,否则会爆显存

2、更改目录的setup.py

需要把显卡算力改成自己对应的,其余的注释掉。例如我的3090是86(具体的算力对应大家可以查查)

"-D__CUDA_NO_HALF_OPERATORS__",
"-D__CUDA_NO_HALF_CONVERSIONS__",
"-D__CUDA_NO_HALF2_OPERATORS__",
"-gencode=arch=compute_70,code=sm_70",
"-gencode=arch=compute_80,code=sm_80",
"-gencode=arch=compute_86,code=sm_86",

3、当前目录下编译

python setup.py develop

八、nuscenes-mini版本

1、配置文件

1.1 下载nuScenes数据集

下载地址:https://www.nuscenes.org/nuscenes

1.2 文件夹结构

bevfusion
├── tools
├── configs
├── data
│   ├── nuscenes
│   │   ├── maps
│   │   ├── samples
│   │   ├── sweeps
│   │   ├── v1.0-mini

Map expansion pack(v1.3) 下载解压到maps文件夹中。否则后面运行分割的时候会报错!
在这里插入图片描述

1.3 运行数据转换的脚本

python tools/create_data.py  nuscenes --root-path ./data/nuscenes/ --version v1.0-mini --out-dir data/nuscenes/ --extra-tag nuscenes

报错1ImportError: cannot import name ‘feature_decorator_ext’ from partially initialized module ‘mmdet3d.ops.feature_decorator’ (most likely due to a circular import) (/home/mengwen/bevfusion/mmdet3d/ops/feature_decorator/init.py)

解决

(1)注释掉 mmdet3d/ops/init.py 中的 from .feature_decorator import feature_decorator

报错2FileNotFoundError: NuScenesDataset: [Errno 2] No such file or directory: ‘data/nuscenes//nuscenes_infos_train.pkl’

解决:更改tools/data_converter/nuscenes_converter.py 中第95~100行

info_path = osp.join(root_path,
'{}_infos_train.pkl'.format(info_prefix))
info_val_path = osp.join(root_path,
'{}_infos_val.pkl'.format(info_prefix))

在这里插入图片描述

转换之后nuscenes文件夹:

在这里插入图片描述

2、开始复现

2.1 下载预训练权重

下载地址:http://drive.google.com/drive/folders/1Jru7VTfgvFF949DlP1oDfriP3wrmOd3c

在这里插入图片描述

2.2 训练

(1)修改参数

  • 设置训练轮数:
    configs/default.yaml中修改epoch:max_epochs: 6
    configs/nuscenes/det/transfusion/secfpn/camera+lidar/default.yaml, max_epoch:6
  • 显存溢出:
    configs/nuscenes/default.yaml, samples_per_gpu: 2(bitch_size),workers_per_gpu: 2
    configs/nuscenes/det/centerhead/lssfpn/camera/256x704/swint/ default.yaml, 建议设置samples_per_gpu: 3

(2)开始训练

原文readme里-np后面是8,这里要改成1(因为我们PC上跑是单GPU),不然会卡住不动

torchpack dist-run -np 1 python tools/train.py configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/convfuser.yaml --model.encoders.camera.backbone.init_cfg.checkpoint pretrained/swint-nuimages-pretrained.pth --load_from pretrained/lidar-only-det.pth

报错1TypeError: FormatCode() got an unexpected keyword argument ‘verify’

解决:yapf包的版本问题,我原来yapf包的0.40.2,降低为yapf==0.40.1

pip install yapf==0.40.1

报错2AttributeError: module ‘distutils’ has no attribute ‘version’

解决:setuptools版本过高导致的问题

pip install setuptools==58.0.4

报错3RuntimeError: Given groups=1, weight of size [8, 1, 1, 1], expected input[24, 6, 256, 704] to have 1 channels, but got 6 channels instead

解决:将 mmdet3d/models/vtransforms/base 中第38行: add_depth_features=True 改为 False ,37行也改为 False

报错4RuntimeError: CUDA out of memory. Tried to allocate 168.00 MiB (GPU 0; 23.70 GiB total capacity; 2.41 GiB already allocated; 96.50 MiB free; 2.43 GiB reserved in total by PyTorch) If reserved memory i

解决:单卡gpu不能满足,采用分布式训练,在mmdet3d/apis/train.py文件中把distributed参数设置为True,直接vs-code全局搜索找到distributed

在这里插入图片描述
(3)训练结束:

在这里插入图片描述2.3 测试

#预训练模型测试
torchpack dist-run -np 1 python tools/test.py configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/convfuser.yaml pretrained/bevfusion-det.pth --eval bbox
  • 测试完成:

在这里插入图片描述

3、实践

3.1 训练BEVFusion detection

多卡更换顺序在前面加上:CUDA_VISIBLE_DEVICES=‘3,2,1,0’

CUDA_VISIBLE_DEVICES='3,2,1,0' torchpack dist-run -np 2 python tools/train.py configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/convfuser.yaml --model.encoders.camera.backbone.init_cfg.checkpoint pretrained/swint-nuimages-pretrained.pth --run-dir train_result

训练完成后会在train_result目录下生成下面文件 结构如下:

在这里插入图片描述
configs.yaml和latest.pth在测试和可视化需要使用

3.2 测试

#生成box.pkl文档

#自己训练模型测试
torchpack dist-run -np 1 python tools/test.py train_result/configs.yaml train_result/latest.pth --eval bbox --out box.pkl

测试完成:

在这里插入图片描述

3.3 生成可视化

torchpack dist-run -np 1 python tools/visualize.py train_result/configs.yaml --mode gt --checkpoint train_result/latest.pth --bbox-score 0.5 --out-dir vis_result

报错1ModuleNotFoundError: No module named ‘torchpack.utils.tqdm’

解决:把tools/visualize.py文件中from torchpack.utils.tqdm import tqdm改成from tqdm import tqdm

解决:在mmdet3d/models/vtransforms/base.py中2个forward函数的参数都加上metas变量,加到**kwargs前

在这里插入图片描述
3.4 查看结果

在vis_result下生成可视化文件

在这里插入图片描述

可视化结果:

在这里插入图片描述

九、nuscenes正常版本

1、运行数据转换的脚本

调用根目录下的数据集

python tools/create_data.py nuscenes --root-path /data/public_dataset/nuscenes --out-dir /home/mengwen/BEV/bevfusion/data/nuscenes --extra-tag nuscenes 

2、训练BEVFusion detection

torchpack dist-run -np 4 python tools/train.py configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/convfuser.yaml --model.encoders.camera.backbone.init_cfg.checkpoint pretrained/swint-nuimages-pretrained.pth --load_from pretrained/lidar-only-det.pth 

参考:
1、复现BEVFusion遇到过的坎儿
2、BEVFusion(mit)最强环境安装,部署复现
3、BEV Fusion (MIT) 环境配置
4、BEVFusion代码复现实践

### BevFusion 使用 Kitti 数据集 实现多传感器融合 BevFusion 是一种基于鸟瞰图(Bird's Eye View, BEV)的多传感器融合方法,旨在解决自动驾驶场景下的目标检测问题。它通过将来自不同传感器的数据映射到统一的 BEV 坐标系中,从而减少因视角差异带来的歧义性[^2]。 #### 1. 多模态数据输入处理 在 BevFusion 中,LiDAR 和相机数据被分别预处理并转换为适合融合的形式。对于 LiDAR 数据,其原始点云可以直接用于构建 BEV 特征图;而对于相机数据,则可以通过卷积神经网络提取特征图,并进一步转化为伪 LiDAR 表示或直接投影至 BEV 平面[^1]。 以下是典型的预处理流程: - **LiDAR 数据**: 将点云离散化为体素网格或直接生成 BEV 投影。 - **相机数据**: 利用 CNN 提取高级语义特征,并将其映射到 BEV 空间中。 #### 2. 融合策略 为了有效融合多模态数据,BevFusion 可采用多种方式: - **早期融合**: 在特征提取之前将多源数据拼接在一起。 - **中期融合**: 对每种模态单独提取特征后再进行融合。 - **晚期融合**: 各自完成独立的目标检测后,在决策层面上进行融合。 具体实现上,考虑到计算效率和精度平衡,中期融合通常是首选方案之一。 #### 3. 示例代码 下面展示了一个简单的 Python 实现框架,演示如何加载 Kitti 数据集并通过 BevFusion 方法执行多传感器融合: ```python import numpy as np from PIL import Image import torch from torchvision.transforms import ToTensor def load_kitti_data(lidar_path, image_path): """ 加载 Kitti 数据 """ lidar_points = np.fromfile(lidar_path, dtype=np.float32).reshape(-1, 4) # 加载点云 image = Image.open(image_path) # 加载图像 return lidar_points, ToTensor()(image) def preprocess_lidar(points): """ 预处理 LiDAR 数据以生成 BEV 图像 """ bev_size = (500, 500) grid_res = 0.2 min_x, max_x = -50, 50 min_y, max_y = -50, 50 height_map = np.zeros(bev_size, dtype=np.uint8) for point in points: x, y, z = point[:3] if min_x <= x <= max_x and min_y <= y <= max_y: i = int((x - min_x) / grid_res) j = int((y - min_y) / grid_res) height_map[j, i] = max(height_map[j, i], z * 255) # 归一化高度 return height_map def fuse_features(lidar_bev, camera_feature): """ 融合 LiDAR 的 BEV 和相机特征 """ fused_feature = torch.cat([lidar_bev.unsqueeze(0), camera_feature], dim=0) return fused_feature # 主程序入口 if __name__ == "__main__": lidar_file = "path/to/kitti/lidar.bin" image_file = "path/to/kitti/image.png" lidar_points, camera_image = load_kitti_data(lidar_file, image_file) lidar_bev = preprocess_lidar(lidar_points) fused_output = fuse_features(torch.tensor(lidar_bev), camera_image) print(f"Fused feature shape: {fused_output.shape}") ``` 上述代码展示了从加载 Kitti 数据到生成融合特征的过程。其中 `preprocess_lidar` 函数负责将点云数据转换为 BEV 格式,而 `fuse_features` 函数则实现了两种模态之间的简单堆叠操作。 #### 4. 性能优化建议 针对实际应用中的挑战,可采取以下措施提升效果: - **校准误差补偿**: 解决摄像头 LiDAR 之间可能存在的位置偏差问题。 - **鲁棒性增强**: 引入注意力机制或其他先进的深度学习架构提高模型对噪声及遮挡情况的适应能力。 ---
评论 58
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值