Giter Club home page Giter Club logo

csiro-robotics / logg3d-net Goto Github PK

View Code? Open in Web Editor NEW
94.0 11.0 14.0 29.34 MB

[ICRA 2022] The official repository for "LoGG3D-Net: Locally Guided Global Descriptor Learning for 3D Place Recognition", In 2022 International Conference on Robotics and Automation (ICRA), pp. 2215-2221.

Home Page: https://arxiv.org/abs/2109.08336

License: Other

Python 100.00%
deep-learning place-recognition lidar-point-cloud lidar 3d learning contrastive-loss point-cloud robotics pytorch

logg3d-net's Introduction

LoGG3D-Net

This repository is an open-source implementation of the ICRA 2022 paper: LoGG3D-Net: Locally Guided Global Descriptor Learning for 3D Place Recognition that won 2nd place at the General Place Recognition: City-scale UGV 3D Localization Competition - Round 1.

We introduce a local consistency loss that can be used in an end-to-end global descriptor learning setting to enforce consistency of the local embeddings extracted from point clouds of the same location. We demonstrate how enforcing this property in the local features contributes towards better performance of the global descriptor in 3D place recognition. We formulate our approach in an end-to-end trainable architecture called LoGG3D-Net.

News

  • [2023-05] Added new general dataloaders to help with training on custom datasets (such as Wild-Places).
  • [2023-03] LoGG3D-Net has been extended for 6-DoF metric localization in SpectralGV RA-L 2023.
  • [2023-03] Added support for PyTorch 2.0.
  • [2022-05] Won 2nd place at the ICRA 2022 General Place Recognition Competition organized by AirLab, Carnegie Mellon University. Watch the invited talk here.
  • [2022-05] Training code released.
  • [2022-02] Evaluation code and pretrained models released.

Method overview

  • Joint constraints for local and global descriptors during training.
  • Inference on high-resolution point-clouds using Sparse Point-Voxel convolution to capture fine-grained detail.
  • Feature aggregation using higher-oder pooling to better capture the distribution of local features.

Usage

Set up environment

This project has been tested on a system with Ubuntu 22.04. Main dependencies include:

Set up the requirments as follows:

  • Create conda environment with python:
conda create -n logg3d_env python=3.9.4
conda activate logg3d_env
  • Install PyTorch with suitable cudatoolkit version. See here:
pip3 install torch torchvision torchaudio
# Make sure the pytorch cuda version matches your output of 'nvcc --version'
pip install -r requirements.txt
  • Install torchsparse-1.4.0
sudo apt-get install libsparsehash-dev
pip install --upgrade git+https://github.com/mit-han-lab/[email protected]
conda install mpi4py
conda install openmpi
  • Download our pre-trained models from DropBox or cloudstor. Contains 7 checkpoints (6 for Kitti and 1 for MulRan) totalling 741.4 MB. Extract the content into ./checkpoints/:
wget -O checkpoints.zip https://cloudstor.aarnet.edu.au/plus/s/G9z6VzR72TRm09S/download
unzip checkpoints.zip
  • Download the KITTI odometry dataset, the MulRan dataset and set the paths in config/eval_config.py.
  • For the KITTI odometry dataset, we are using the refined ground-truth poses provided in SemanticKITTI.
  • For the MulRan dataset, create scan_poses.csv files for each sequence using:
python ./utils/data_utils/mulran_save_scan_poses.py

Training

Before training:

  • Do offline mining of positive pairs for both datasets (at 3m and 20m):
python utils/data_utils/kitti_tuple_mining.py
python utils/data_utils/mulran_tuple_mining.py
  • Set the number of GPUs available:
_NGPU=1

Training:

  • eg. Default training parameters on Kitti:
torchpack dist-run -np ${_NGPU} python training/train.py \
    --train_pipeline 'LOGG3D' \
    --dataset 'KittiPointSparseTupleDataset'
  • eg. Default training parameters on MulRan:
torchpack dist-run -np ${_NGPU} python training/train.py \
    --train_pipeline 'LOGG3D' \
    --dataset 'MulRanPointSparseTupleDataset'
  • See config/train_config.py for all other training parameters.

Evaluation

For KITTI (eg. sequence 06):

python evaluation/evaluate.py \
    --eval_dataset 'KittiDataset' \
    --kitti_eval_seq 6 \
    --checkpoint_name '/kitti_10cm_loo/2021-09-14_06-43-47_3n24h_Kitti_v10_q29_10s6_262450.pth' \
    --skip_time 30

For MulRan (eg. sequence DCC03):

python evaluation/evaluate.py \
    --eval_dataset 'MulRanDataset' \
    --mulran_eval_seq 'DCC/DCC_03' \
    --checkpoint_name '/mulran_10cm/2021-09-14_08-59-00_3n24h_MulRan_v10_q29_4s_263039.pth' \
    --skip_time 90

Qualitative visualizations of top-1 retrievals on KITTI 08 and MulRan DCC 03:

Visualization of t-SNE embeddings of the local features extracted using our pre-trained model (on the CMU AirLab ALITA dataset).

Citation

If you find this work usefull in your research, please consider citing:

@inproceedings{vid2022logg3d,
  title={LoGG3D-Net: Locally Guided Global Descriptor Learning for 3D Place Recognition},
  author={Vidanapathirana, Kavisha and Ramezani, Milad and Moghadam, Peyman and Sridharan, Sridha and Fookes, Clinton},
  booktitle={2022 International Conference on Robotics and Automation (ICRA)},
  pages={2215--2221},
  year={2022}
}

Acknowledgement

Functions from 3rd party have been acknowledged at the respective function definitions or readme files. This project was mainly inspired by the following: FCGF and SPVNAS.

Contact

For questions/feedback,

logg3d-net's People

Contributors

kavisha725 avatar peymmo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

logg3d-net's Issues

error when batch size larger than one

Hello, I want to first of all thank you for your great work!

I found a problem when I trained the network with batch_size=2:

Exception has occurred: AttributeError       (note: full exception trace is shown but execution is paused at: <module>)
'list' object has no attribute 'to'
  File "/home/stud/maiy/LoGG3D-Net/training/train.py", line 100, in main
    batch_st = batch[0].to('cuda:%d' % dist.local_rank())
  File "/home/stud/maiy/LoGG3D-Net/training/train.py", line 174, in <module> (Current frame)
    main()

After I looked into the code, I think the problem lies in the collation function of dataloader which is incompatible with indexing in train.py:

if len(outputs) == 1:
return outputs[0]
else:
return outputs

Could you please check it? Any feedback is appreciated and please let me know if I misunderstood anything. Thanks again for your work!

Issues with training KITTI datset

Dear Authors,

At the outset, I would like to thank you for your great work and for making this code public.
But when I was trying to execute training for KITI dataset with the default training parameters, I am getting the following errors:
[mpiexec@node0006] match_arg (utils/args/args.c:163): unrecognized argument allow-run-as-root
[mpiexec@node0006] HYDU_parse_array (utils/args/args.c:178): argument matching returned error
[mpiexec@node0006] parse_args (ui/mpich/utils.c:1642): error parsing input array
[mpiexec@node0006] HYD_uii_mpx_get_parameters (ui/mpich/utils.c:1694): unable to parse user arguments
[mpiexec@node0006] main (ui/mpich/mpiexec.c:148): error parsing parameter

Any feedback/ insights on the same are appreciated.

Thanks for your time and your work.

Channel value error when applying the checkpoint model to a custom point cloud

I have got some CAD model point clouds. But when I applied the model to them, in some cases it succeeded but in some other cases it would report a channel value error.

Here is the code segment:

save_path = os.path.join(os.path.dirname(file), 'checkpoints')
save_path = str(save_path) + cfg.checkpoint_name
checkpoint = torch.load(save_path)
model = get_pipeline(cfg.eval_pipeline)
model.load_state_dict(checkpoint['model_state_dict'])

base_file = data_dir + '/' + sorted(os.listdir(data_dir))[1]
base_pcd = np.load(base_file)
base_pcd = np.hstack((base_pcd, np.zeros(base_pcd.shape[0]).reshape(-1, 1))).astype(np.float32) # My pcds do not have intensity.
current_input = make_sparse_tensor(base_pcd, cfg.voxel_size).cuda()
output_desc, output_feats = model(current_input)

And here is the error report:

Traceback (most recent call last):
File "/media/uds/extra_space/LoGG3D-Net/Calc_Logg3D_Descs.py", line 50, in
output_desc, output_feats = model(current_input)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/models/pipelines/LOGG3D.py", line 25, in forward
x = self.spvcnn(x)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/models/backbones/spvnas/core/models/semantic_kitti/spvcnn.py", line 197, in forward
x4 = self.stage4(x3)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/container.py", line 217, in forward
input = module(input)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/models/backbones/spvnas/core/models/semantic_kitti/spvcnn.py", line 27, in forward
out = self.net(x)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/container.py", line 217, in forward
input = module(input)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/module.py", line 1501, in _call_impl
return forward_call(*args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torchsparse/nn/modules/norm.py", line 13, in forward
return fapply(input, super().forward)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torchsparse/nn/utils/apply.py", line 12, in fapply
feats = fn(input.feats, *args, **kwargs)
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/modules/batchnorm.py", line 171, in forward
return F.batch_norm(
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/functional.py", line 2448, in batch_norm
_verify_batch_size(input.size())
File "/media/uds/extra_space/LoGG3D-Net/venv/lib/python3.10/site-packages/torch/nn/functional.py", line 2416, in _verify_batch_size
raise ValueError("Expected more than 1 value per channel when training, got input size {}".format(size))
ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 81])

Error SparseTensor during PointNetVLAD training

Hi,

I'm currently trying to train PointNetVLAD on different dataset (KittiSparseTupleDataset and KittiTupleDataset).
I have no problems for LoGG3D-net training but I have those two errors for PointNetVLAD:

Command number 1 :

python training/train.py --train_pipeline 'PointNetVLAD' --train_num_workers 8 --point_loss_weight 0 --dataset "KittiSparseTupleDataset"
Error :
Traceback (most recent call last):
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/train.py", line 161, in
main()
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/train.py", line 98, in main
output = model(batch_st)
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
return forward_call(*input, **kwargs)
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/nn/parallel/distributed.py", line 886, in forward
output = self.module(*inputs[0], **kwargs[0])
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
return forward_call(*input, **kwargs)
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/../models/pipelines/PointNetVLAD.py", line 19, in forward
x = self.point_net(x)
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/nn/modules/module.py", line 1102, in _call_impl
return forward_call(*input, **kwargs)
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/../models/backbones/PointNet.py", line 86, in forward
batchsize = x.size()[0]
AttributeError: 'SparseTensor' object has no attribute 'size'

Command number 2 :

python training/train.py --train_pipeline 'PointNetVLAD' --train_num_workers 8 --point_loss_weight 0 --dataset "KittiTupleDataset"
Error :
Traceback (most recent call last):
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/train.py", line 161, in
main()
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/train.py", line 93, in main
for i, batch in enumerate(train_loader, 0):
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 521, in next
data = self._next_data()
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 1203, in _next_data
return self._process_data(data)
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/utils/data/dataloader.py", line 1229, in _process_data
data.reraise()
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/_utils.py", line 434, in reraise
raise exception
AttributeError: Caught AttributeError in DataLoader worker process 0.
Original Traceback (most recent call last):
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/utils/data/_utils/worker.py", line 287, in _worker_loop
data = fetcher.fetch(index)
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torch/utils/data/_utils/fetch.py", line 52, in fetch
return self.collate_fn(data)
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/../utils/data_loaders/pointcloud_dataset.py", line 126, in call
return self.collation_fn(list_data)
File "/gpfs7kw/linkhome/rech/genvsy01/ufm44cu/code/LoGG3D-Net/training/../utils/data_loaders/pointcloud_dataset.py", line 143, in collate_tuple
outputs.append(sparse_collate(contrastive_tuple))
File "/gpfslocalsup/pub/anaconda-py3/2021.05/envs/pytorch-gpu-1.10.1+py3.9.7/lib/python3.9/site-packages/torchsparse/utils/collate.py", line 13, in sparse_collate
stride = inputs[0].stride
AttributeError: 'numpy.ndarray' object has no attribute 'stride'

Problems

=> Even when I change the dataset to be "non-sparse", the code call the function sparse_collate
def sparse_collate(inputs: List[SparseTensor]) -> SparseTensor:
in Torchsparse.

collate_tuple (in pointcloud_dataset.py) call sparse_collate, which need a SparseTensor object as an input,
Shouldn't I call the sparse_collate_fn function instead?
def sparse_collate_fn(inputs: List[Any]) -> Any:

And, kitti_dataset.py don't return a pytorch tensor but a numpy.ndarray, is it normal?

Originally posted by @Chahine-Nicolas in #2 (comment)

Sensor Requirement

Hi, thanks for your great job!

I am gonna to test your work in our project. We have done some investigation before. In some lidar-based place recognition method, lidar with 360 degree data with at least 36 lines is recommended. So how about the adaptability to different lidar sensor of your method?

Thank your for your attention and keep waiting for kind response!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.