项目地址:https://github.com/Tsinghua-MARS-Lab/futr3d
论文地址:https://arxiv.org/abs/2203.10642
环境:Linux、cuda 11.1、python 3.8
1.创建虚拟环境futr
conda create -n futr python=3.8 -y
conda activate futr
2.安装pytorch的GPU版本,在这里我选择了离线安装,直接下载whl文件,然后pip安装。whl官方的地址是whl传送门,或者另一个传送门。
pip install torch-1.9.0+cu111-cp38-cp38-linux_x86_64.whl torchvision-0.10.0+cu111-cp38-cp38-linux_x86_64.whl torchaudio-0.9.0-cp38-cp38-linux_x86_64.whl
也可以用官方命令安装(你连了外网的情况下)
pip install torch==1.9.0+cu111 torchvision==0.10.0+cu111 torchaudio==0.9.0 -f https://download.pytorch.org/whl/torch_stable.html
3.准备mmcv-full 1.6.0、mmdet、mmsegmentation、nuscenes-devkit
pip install mmcv-full==1.6.0 -f https://download.openmmlab.com/mmcv/dist/cu111/torch1.9.0/index.html
pip install mmdet==2.24.0 mmsegmentation==0.29.1 nuscenes-devkit
4.clone项目并完成项目安装。
git clone https://github.com/Tsinghua-MARS-Lab/futr3d.git
cd futr3d
pip3 install -v -e .
下一步是准备数据集。
5.获取Nuscenes数据集,代码学习可以下载mini版本。下载地址:https://www.nuscenes.org/download(需要登录,没账号就注册一个),下载解压后放到data目录下,改名为nuscenes,这里用mini版本。
再次之前需要一点改动,xxx/futr3d/tools/create_data.py 第90行的部分修改为
#原代码为:create_groundtruth_database(dataset_name, root_path, info_prefix,
# 'data/nusc_new/nuscenes_infos_train.pkl')
create_groundtruth_database(dataset_name, root_path, info_prefix,'data/nuscenes/nuscenes_infos_train.pkl')
运行
python tools/create_data.py nuscenes --root-path ./data/nuscenes --out-dir ./data/nuscenes --extra-tag nuscenes --version v1.0-mini
获取pkl文件后,这里想要进行Lidar+cam的训练,需要先运行lidar only和camera only获取两种模型,用tools/fuse_model.py合并后作为预训练模型再去训练lidar、camera融合的方法。
先训练Lidar:
修改几个地方:
- plugin/futr3d/configs/lidar_only/lidar_0075v_900q.py中_base_中,为_base_中三个路径在前面多加一个…/
- plugin/futr3d/models/detectors/futr3d.py、plugin/futr3d/models/head/futr3d_head.py、plugin/futr3d/datasets/loading.py中,依次把import部分的from plugin.fudet.models.utils.grid_mask import GridMask改为from plugin.futr3d.models.utils.grid_mask import GridMask(我也不懂为什么官方给的代码还有BUG)
- 如果你显存够大,忽略这步(比如24G或者是80G显存),在/futr3d/plugin/futr3d/configs/lidar_only/lidar_0075v_900q.py中,为data的构造添加batch限制,具体如下(添加注释掉的部分代码,这里只是为了方便展示添加的代码所以故意注释掉了,batchsize根据个人情况改):
data = dict(# samples_per_gpu=1,# batch size# workers_per_gpu=0,train=dict(type='CBGSDataset',dataset=dict(type=dataset_type,data_root=data_root,ann_file=data_root + 'nuscenes_infos_train.pkl',pipeline=train_pipeline,classes=class_names,test_mode=False,use_valid_flag=True,# we use box_type_3d='LiDAR' in kitti and nuscenes dataset# and box_type_3d='Depth' in sunrgbd and scannet dataset.box_type_3d='LiDAR')),val=dict(pipeline=test_pipeline, classes=class_names, ann_file=data_root + 'nuscenes_infos_val.pkl'),test=dict(pipeline=test_pipeline, classes=class_names, ann_file=data_root + 'nuscenes_infos_val.pkl'))
运行下面代码开始训练(dist_train.sh也有问题。。。)
python tools/train.py plugin/futr3d/configs/lidar_only/lidar_0075v_900q.py --gpu-id 1 --autoscale-lr
如果报错TypeError: FormatCode() got an unexpected keyword argument ‘verify‘,yapf包的版本降低为yapf==0.40.1(pip install就行,不单独列个命令了)。我这里指定了用显卡1训练,只是为了测试项目是否能跑通。
上面这个是仅用lidar训练,现在,利用lidar预训练模型和image预训练模型经过合并后进行lidar+image的融合训练。具体在图像预训练,Lidar预训练两个地方下载模型(如果你想直接跟着我的代码运行,下载两个文件到:/futr3d/lidar-cam-pretrain/目录下),然后修改tools/fuse_model.py这个文件如下(把两个模型文件的路径换成你自己的):
import torchimg_ckpt = torch.load('./lidar-cam-pretrain/detr3d_vovnet_trainval.pth')
state_dict1 = img_ckpt['state_dict']pts_ckpt = torch.load('./lidar-cam-pretrain/lidar_0075_900q.pth')
state_dict2 = pts_ckpt['state_dict']
# pts_head in camera checkpoint will be overwrite by lidar checkpoint
state_dict1.update(state_dict2)merged_state_dict = state_dict1save_checkpoint = {'state_dict':merged_state_dict }torch.save(save_checkpoint, './checkpoint/lidar_vov_trainval.pth')
在futr3d创建checkpoint目录,然后执行该文件:
python tools/fuse_model.py
这下你的主目录下checkpoint里会多出一个权重文件,这就是融合模型训练需要的预训练模型。修改xxx/futr3d/plugin/futr3d/configs/lidar_cam/lidar_0075v_cam_vov.py模型里workers_per_gpu=0,samples_per_gpu=1,显存够大也可以把samples_per_gpu改高点,再将最后一行load_from改为’checkpoint/lidar_vov_trainval.pth’。接下来运行
python tools/train.py plugin/futr3d/configs/lidar_cam/lidar_0075v_cam_vov.py --gpu-id 2 --autoscale-lr
其中gpu-id表示gpu序号,这里指定了第2张GPU训练。注意了,这个项目代码里有.cuda()的操作,这个操作默认会在第一张显卡进行,所以最好是空出第一块显卡,要不然代码跑到这会因为张量在不同显卡上报错(心累,还得找到有BUG的地方,把tensor移到统一显卡上,还好,我只发现了一个这样的问题),训练时batch设成了1,大概占用10G显存。
推理的部分等有时间能把full数据集跑了再来更新吧,麻了