【论文复现】End-to-end Pseudo-LiDAR for Image-Based 3D Object Detection训练环境搭建

End-to-end Pseudo-LiDAR for Image-Based 3D Object Detection 是发表在CVPR2020的单目目标检测模型,它通过对双目摄像头图片进行深度估计,然后将深度图从image view转换成欧氏空间,再通过现成的3D目标检测模型进行检测。
【论文复现】End-to-end Pseudo-LiDAR for Image-Based 3D Object Detection训练环境搭建_第1张图片
一些细节:

  • Depth Estimation和3D object detection模型全部使用pre-trained的模型,分别是SDN(ICLR2020)和PointRCNN(CVPR2019)以及PIXOR(CVPR2018)
  • 作者完成了Change of Representation模块,以及对应的back-propagation部分
  • SDN的训练过程比较复杂,scene flow数据集上训练,然后在KITTI上进行fine tune,由于KITTI object detection并不提供深度图,它使用point cloud映射的深度图来fine tune。也就是说,这个深度图只有大约4%的pixel有valid value

训练环境安装
对应Github Repo如下:https://github.com/mileyan/pseudo-LiDAR_e2e,作者选取了两个对于点云特征采取不同提取方式的目标检测网络来测试,这里我们采用PointRCNN来讲解训练环境的搭建。主要参考两个repo (1) mileyan/Pseudo_Lidar_V2,需要注意的是,虽然在pseudo-LiDAR_e2e中作者说KITTI数据的存放方式和Pseudo_Lidar_V2一样,但实际中并非如此,这一点下面会详细说。另一方面,我们需要使用Pseudo_Lidar_V2的代码来生成depth map(2)sshaoshuai/PointRCNN,PointRCNN中使用的是CUDA9.0,但如果照搬到pseudo-LiDAR_e2e中出导致很多问题的出现,尤其对于RTX系列的GPU。在pseudo-LiDAR_e2e中,作者使用了TITAN RTX GPU,说明CUDA版本大于等于10.0。

以下是环境建立的具体步骤:

  1. 数据集下载:需要下载的数据,包括双目的图片,点云数据,calibration数据以及label。并解压缩到KITTI文件夹中
    【论文复现】End-to-end Pseudo-LiDAR for Image-Based 3D Object Detection训练环境搭建_第2张图片
  2. 数据存放结构:此处应该按照PointRCNN来存放数据,这里和Pseudo_Lidar_V2的数据存放方式不同,否则会报错。KITTI/ImageSets中的文件也可以从PointRCNN的repo中获得。
PointRCNN
|-- data
|   |-- KITTI
|   |   |-- ImageSets
|   |   |-- object
|   |   |   |-- training
|   |   |       |-- calib & velodyne & image_2 & image_3 & label_2 
|   |   |   |-- testing
|   |   |       |-- calib & velodyne & image_2 & image_3
  1. Depth map数据生成:训练pseudo-LiDAR_e2e需要depth map(即velodyne的点云下采样至16线,然后映射到image view)。这里使用的代码位于pseudo_lidar_v2/src/preprocess/generate_depth_map.py,运行以下命令行在KITTI/object/training下生成文件夹depth_map
python ./src/preprocess/generate_depth_map.py --data_path <path-to-KITTI> --split_file ./split/trainval.txt

出来的depth map长这样
【论文复现】End-to-end Pseudo-LiDAR for Image-Based 3D Object Detection训练环境搭建_第3张图片

  1. 下载pytorch源代码和torchvision源代码:如果直接使用pip或者conda安装的话,会报出类似于如下的错误
THCudaCheck FAIL file=/pytorch/aten/src/THC/THCGeneral.cpp line=383 error=11 : invalid argument

在以下网页下载对应的wheel代码,https://download.pytorch.org/whl/torch_stable.html
此处我使用python3.6和CUDA10.0的wheel

wget https://download.pytorch.org/whl/cu100/torch-1.1.0-cp36-cp36m-linux_x86_64.whl
wget https://download.pytorch.org/whl/cu100/torchvision-0.3.0-cp36-cp36m-linux_x86_64.whl
  1. 数据准备:此处需要将PointRCNN下的pointnet2_lib文件夹移至pseudo-LiDAR_e2e/PointRCNN
  2. docker镜像并建立容器:此处需要下载没有预装torch的docker镜像,以防止安装环境被污染。运行docker容器,-p命令12222号端口桥接容器的22号端口来使用ssh,–mount来加载容器以外的文件夹,此处将*/mnt/VOL_5/下的name文件夹加载至容器系统下/name*位置。
docker pull ufoym/deepo:py36-cu100
docker run --gpus 'device=6' -p 12222:22 -it --name=lbaiPrcnn --mount type=bind,source=/mnt/VOL_5/name/,target=/name ufoym/deepo:py36-cu100 bash
  1. 进入docker之后,首先安装torch和torchvision
python -m pip install torch-1.1.0-cp36-cp36m-linux_x86_64.whl 
python -m pip install torchvision-0.3.0-cp36-cp36m-linux_x86_64.whl
  1. 安装PointRCNN和pseudo-LiDAR_e2e所需的python库
pip install easydict tqdm tensorboardX fire scikit-image numba torch-scatter==1.3.1 ipdb

运行pseudo-LiDAR_e2e/PointRCNN下的build_and_install.sh来安装所需的库

  1. 使用ln -s建立软链接来使用KITTI数据集

  2. (可选)设置ssh

apt install openssh-server

编辑文件*/etc/ssh/sshd_config*,修改文件中的以下三行

PermitRootLogin yes # 可以登录 root 用户
PubkeyAuthentication yes # 可以使用 ssh 公钥许可
AuthorizedKeysFile  .ssh/authorized_keys # 公钥信息保存到该文件中

重启sshd

/etc/init.d/ssh restart
  1. 下载所需的预训练weights:作者在github repo中已经给出,主要是detector
  2. 开始训练,此处我将batch_size改为1,并且删除了–ckpt部分,至此,训练可以正常运行
python train_rcnn_depth.py --gt_database "" --cfg_file cfgs/e2e.yaml  --batch_size 1 --train_mode end2end --ckpt_save_interval 1 --epochs 10 --mgpus --finetune

下一步
我将使用作者提供的pre-trained的SDN模型来重新训练,看是否可以得到和论文中近似的结果。

几个疑问
作者在Section4.2的第一段中提到,这个网络的训练方法是先训练stereo depth estimation network (SDN),然后固定这个depth network,并从头训练3D object detector。最后再使用balanced loss weights来joint train这两部分。其中,depth correction部分在Pseudo_Lidar_V2中有叙述。

  1. 在pseudo-LiDAR_e2e的repo中,并没有详细说明SDN的训练方法,我怀疑是直接使用了Pseudo_Lidar_V2的训练结果,depth correction使用的是64线LiDAR的点云。这一点需要向原作者确认。
    2020.11.02 更新:通过询问作者,depth estimation network是直接使用Pseudo_Lidar_V2中的SDN的pretrained权重,其中使用了4线LiDAR point cloud做校正(通过提取64线LiDAR point cloud中的5,7,9,11获得)。
  2. 作者说在第二步固定depth network之后回从头训练3D object detector,但是在github repo中,作者给出的训练命令行中需要给出checkpoint,可能不是必须,但似乎作者是直接拿来PointRCNN的pretrianed weights来做fine tune的。这一点仍需要向原作者求证。
    2020.11.02 更新:通过询问作者,最后一步做end2end训练的时候,需要添加depth estimation network和PointRCNN两个网络的pretrained权重。
  3. depth_map在pseudo-LiDAR_e2e的训练中起什么作用?如果在训练SDN时,使用点云来做correction,那还算是stereo camera only吗?
  4. 2020.11.02 更新:如何做第二步PointRCNN训练(固定depth estimation,从头训练PointRCNN)?似乎是给出depth_ckpt但不提供ckpt参数。但我并没有找到固定权重的参数设定。

你可能感兴趣的:(3D目标检测,深度学习)