Message Passing on Cell Complexes

Related tags

Deep Learning cwn
Overview

CW Networks

example workflow

This repository contains the code used for the papers Weisfeiler and Lehman Go Cellular: CW Networks (Under review) and Weisfeiler and Lehman Go Topological: Message Passing Simplicial Networks (ICML 2021)

alt text     alt text   alt text

Graph Neural Networks (GNNs) are limited in their expressive power, struggle with long-range interactions and lack a principled way to model higher-order structures. These problems can be attributed to the strong coupling between the computational graph and the input graph structure. The recently proposed Message Passing Simplicial Networks naturally decouple these elements by performing message passing on the clique complex of the graph. Nevertheless, these models are severely constrained by the rigid combinatorial structure of Simplicial Complexes (SCs). In this work, we extend recent theoretical results on SCs to regular Cell Complexes, topological objects that flexibly subsume SCs and graphs. We show that this generalisation provides a powerful set of graph "lifting" transformations, each leading to a unique hierarchical message passing procedure. The resulting methods, which we collectively call CW Networks (CWNs), are strictly more powerful than the WL test and, in certain cases, not less powerful than the 3-WL test. In particular, we demonstrate the effectiveness of one such scheme, based on rings, when applied to molecular graph problems. The proposed architecture benefits from provably larger expressivity than commonly used GNNs, principled modelling of higher-order signals and from compressing the distances between nodes. We demonstrate that our model achieves state-of-the-art results on a variety of molecular datasets.

Installation

We use Python 3.8 and PyTorch 1.7.0 on CUDA 10.2 for this project. Please open a terminal window and follow these steps to prepare the virtual environment needed to run any experiment.

Create the environment:

conda create --name cwn python=3.8
conda activate cwn

Install dependencies:

conda install -y pytorch=1.7.0 torchvision cudatoolkit=10.2 -c pytorch
sh pyG_install.sh cu102
pip install -r requirements.txt
sh graph-tool_install.sh

Testing

We suggest running all tests in the repository to verify everything is in place. Run:

pytest -v .

All tests should pass. Note that some tests are skipped since they rely on external datasets or take a long time to run. We periodically run these tests manually.

Experiments

We prepared individual scripts for each experiment. The results are written in the exp/results/ directory and are also displayed in the terminal once the training is complete. Before the training starts, the scripts will download / preprocess the corresponding graph datasets and perform the appropriate graph-lifting procedure (this might take a while).

Molecular benchmarks

To run an experiment on a molecular benchmark with a CWN, execute:

sh exp/scripts/cwn-<benchmark>.sh

with <benchmark> one amongst zinc, zinc-full, molhiv.

Imposing the parameter budget: it is sufficient to add the suffix -small to the <benchmark> placeholder:

sh exp/scripts/cwn-<benchmark>-small.sh

For example, sh exp/scripts/cwn-zinc-small.sh will run the training on ZINC with parameter budget.

Distinguishing SR graphs

To run an experiment on the SR benchmark with a CWN, run:

sh exp/scripts/cwn-sr.sh <k>

replacing <k> with a value amongst 4, 5, 6 (<k> is the maximum ring size employed in the lifting procedure). The results, for each family, will be written under exp/results/SR-cwn-sr-<k>/.

The following command will run the MLP-sum (strong) baseline on the same ring-lifted graphs:

sh exp/scripts/cwn-sr-base.sh <k>

In order to run these experiment with clique-complex lifting (MPSNs), run:

sh exp/scripts/mpsn-sr.sh

Clique-lifting is applied up to dimension k-1, with k the maximum clique-size in the family.

The MLP-sum baseline on clique-complexes is run with:

sh exp/scripts/mpsn-sr-base.sh

Circular Skip Link (CSL) Experiments

To run the experiments on the CSL dataset (5 folds x 20 seeds), run the following script:

sh exp/scripts/cwn-csl.sh

Trajectory classification

For the Ocean Dataset experiments, the data must be downloaded from here. The file must be placed in datasets/OCEAN/raw/.

For running the experiments use the following scripts:

sh ./exp/scripts/mpsn-flow.sh [id/relu/tanh]
sh ./exp/scripts/mpsn-ocean.sh [id/relu/tanh]
sh ./exp/scripts/gnn-inv-flow.sh
sh ./exp/scripts/gnn-inv-ocean.sh

TUDatasets

For experiments on TUDatasets first download the raw data from here. Please place the downloaded archive on the root of the repository and unzip it (e.g. unzip ./datasets.zip).

Here we provide the scripts to run CWN on NCI109 and MPSN on REDDITBINARY. This script can be customised to run additional experiments on other datasets.

sh ./exp/scripts/cwn-nci109.sh
sh ./exp/scripts/mpsn-redditb.sh

Credits

For attribution in academic contexts, please cite the following papers

@InProceedings{pmlr-v139-bodnar21a,
  title = 	 {Weisfeiler and Lehman Go Topological: Message Passing Simplicial Networks},
  author =       {Bodnar, Cristian and Frasca, Fabrizio and Wang, Yuguang and Otter, Nina and Montufar, Guido F and Li{\'o}, Pietro and Bronstein, Michael},
  booktitle = 	 {Proceedings of the 38th International Conference on Machine Learning},
  pages = 	 {1026--1037},
  year = 	 {2021},
  editor = 	 {Meila, Marina and Zhang, Tong},
  volume = 	 {139},
  series = 	 {Proceedings of Machine Learning Research},
  month = 	 {18--24 Jul},
  publisher =    {PMLR},
}
@article{bodnar2021b,
  title={Weisfeiler and Lehman Go Cellular: CW Networks},
  author={Bodnar, Cristian and Frasca, Fabrizio and Otter, Nina and Wang, Yu Guang and Li{\`o}, Pietro and Mont{\'u}far, Guido and Bronstein, Michael},
  journal={arXiv preprint arXiv:2106.12575},
  year={2021}
}

TODOs

  • Add support for coboundary adjacencies.
  • Refactor the way empty cochains are handled for batching.
  • Remove redundant parameters from the models (e.g. msg_up_nn in the top dimension.)
  • Refactor data classes so to remove setters for __num_xxx_cells__ like attributes.
  • Address other TODOs left in the code.
Comments
  • How to get result of test data? or what is the model's save path?

    How to get result of test data? or what is the model's save path?

    Previously I trained the model with my own data and it looks okay. but I can't find how to get test result(not accuracy metric but the result model returns). Is there any tools? or should I make one of it?

    opened by parkhy0106 8
  • # of Parameters on ZINC-500k

    # of Parameters on ZINC-500k

    Hi,

    I'm currently researching on graph representation, and want to compare the performance between SOTAs. I'm curious about the performance and the number of parameters for CIN on ZINC-500k. I just want to check whether # of parameters for MAE=0.079 (CIN) is about 1.7M and MAE=0.094 (CIN-small) is about 130k. BTW, I want to know whether you have conducted experiment that # of parameters approximately equal to 500k. Thanks

    opened by b05901024 2
  • no space left on device while processing Ocean dataset

    no space left on device while processing Ocean dataset

    Hi, Thanks for the interesting paper and for sharing the code.

    I tried to reproduce the Trajectory classification. When I run sh ./exp/scripts/mpsn-flow.sh, there is an error No space left on device as follows. I cannot figure out what uses all the space and what space it is talking about. I have enough disk space and the top command show the memory is not used much.

    $ sh ./exp/scripts/mpsn-flow.sh tanh WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.2. ========================================================== Using device cuda:0 Fold: None Seed: 0 ======================== Args =========================== Namespace(batch_size=64, dataset='FLOW', device=0, drop_position='lin2', drop_rate=0.0, dump_curves=True, early_stop=False, emb_dim=64, epochs=100, eval_metric='accuracy', exp_name='flow_mpsn', final_readout='sum', flow_classes=3, flow_points=1000, fold=None, folds=None, fully_orient_invar=False, graph_norm='bn', indrop_rate=0.0, init_method='sum', iso_eps=0.01, jump_mode=None, lr=0.001, lr_scheduler='StepLR', lr_scheduler_decay_rate=0.5, lr_scheduler_decay_steps=20, lr_scheduler_min=1e-05, lr_scheduler_patience=10, max_dim=2, max_ring_size=None, minimize=False, model='edge_orient', nonlinearity='tanh', num_layers=4, num_workers=0, paraid=0, preproc_jobs=4, readout='sum', readout_dims=(0, 1, 2), result_folder='/home/xyz/code/cwn/exp/results', seed=0, simple_features=False, start_seed=0, stop_seed=4, task_type='classification', test_orient='random', train_eval_period=10, train_orient='default', tune=False, untrained=False, use_coboundaries='False', use_edge_features=False) =================================================== Processing... 0%| | 0/1000 [00:00<?, ?it/s]WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.2. WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.2. WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.2. WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.2. 22%|█████████████████████████████▎ | 224/1000 [00:45<02:37, 4.92it/s] joblib.externals.loky.process_executor._RemoteTraceback: """ Traceback (most recent call last): File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/numpy_pickle.py", line 480, in dump NumpyPickler(f, protocol=protocol).dump(value) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/pickle.py", line 487, in dump self.save(obj) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/numpy_pickle.py", line 279, in save wrapper.write_array(obj, self) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/numpy_pickle.py", line 103, in write_array pickler.file_handle.write(chunk.tobytes('C')) OSError: [Errno 28] No space left on device

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last): File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/externals/loky/backend/queues.py", line 153, in feed obj = dumps(obj, reducers=reducers) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/externals/loky/backend/reduction.py", line 271, in dumps dump(obj, buf, reducers=reducers, protocol=protocol) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/externals/loky/backend/reduction.py", line 264, in dump _LokyPickler(file, reducers=reducers, protocol=protocol).dump(obj) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/externals/cloudpickle/cloudpickle_fast.py", line 563, in dump return Pickler.dump(self, obj) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/_memmapping_reducer.py", line 442, in call for dumped_filename in dump(a, filename): File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/numpy_pickle.py", line 480, in dump NumpyPickler(f, protocol=protocol).dump(value) OSError: [Errno 28] No space left on device """

    The above exception was the direct cause of the following exception:

    Traceback (most recent call last): File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/home/xyz/code/cwn/exp/run_mol_exp.py", line 105, in exp_main(passed_args) File "/home/xyz/code/cwn/exp/run_mol_exp.py", line 26, in exp_main curves = main(parsed_args) File "/home/xyz/code/cwn/exp/run_exp.py", line 77, in main dataset = load_dataset(args.dataset, max_dim=args.max_dim, fold=args.fold, File "/home/xyz/code/cwn/data/data_loading.py", line 150, in load_dataset dataset = FlowDataset(os.path.join(root, name), name, num_points=kwargs['flow_points'], File "/home/xyz/code/cwn/data/datasets/flow.py", line 24, in init super(FlowDataset, self).init(root, max_dim=1, File "/home/xyz/code/cwn/data/datasets/dataset.py", line 140, in init super(InMemoryComplexDataset, self).init(root, transform, pre_transform, pre_filter, File "/home/xyz/code/cwn/data/datasets/dataset.py", line 62, in init super(ComplexDataset, self).init(root, transform, pre_transform, pre_filter) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/torch_geometric/data/dataset.py", line 92, in init self._process() File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/torch_geometric/data/dataset.py", line 165, in _process self.process() File "/home/xyz/code/cwn/data/datasets/flow.py", line 50, in process train, val, G = load_flow_dataset(num_points=self._num_points, File "/home/xyz/code/cwn/data/datasets/flow_utils.py", line 321, in load_flow_dataset train_samples = parallel(delayed(generate_flow_cochain)( File "/home/xyz/code/cwn/data/parallel.py", line 14, in call return Parallel.call(self, *args, **kwargs) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/parallel.py", line 1054, in call self.retrieve() File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/parallel.py", line 933, in retrieve self._output.extend(job.get(timeout=self.timeout)) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/site-packages/joblib/_parallel_backends.py", line 542, in wrap_future_result return future.result(timeout=timeout) File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/concurrent/futures/_base.py", line 437, in result return self.__get_result() File "/home/xyz/miniconda3/envs/cwn/lib/python3.8/concurrent/futures/_base.py", line 389, in __get_result raise self._exception _pickle.PicklingError: Could not pickle the task to send it to the workers. ld not pickle the task to send it to the workers.

    opened by cxw-droid 2
  • issue in running the code

    issue in running the code

    Traceback (most recent call last): File "/Users/sirihu/.conda/envs/envcwn/lib/python3.8/runpy.py", line 194, in _run_module_as_main return _run_code(code, main_globals, None, File "/Users/sirihu/.conda/envs/envcwn/lib/python3.8/runpy.py", line 87, in _run_code exec(code, run_globals) File "/Users/sirihu/data/cwn/exp/run_mol_exp.py", line 105, in exp_main(passed_args) File "/Users/sirihu/data/cwn/exp/run_mol_exp.py", line 26, in exp_main curves = main(parsed_args) File "/Users/sirihu/data/cwn/exp/run_exp.py", line 90, in main train_loader = DataLoader(dataset.get_split('train'), batch_size=args.batch_size, File "/Users/sirihu/data/cwn/data/datasets/dataset.py", line 370, in get_split if self.indices is not None: AttributeError: 'OGBDataset' object has no attribute 'indices'

    def get_split(self, split): if split not in ['train', 'valid', 'test']: raise ValueError(f'Unknown split {split}.') idx = self.get_idx_split()[split] if idx is None: raise AssertionError("No split information found.") 370: if self.indices is not None: raise AssertionError("Cannot get the split for a subset of the original dataset.") return self[idx]

    opened by jeffreyhusc 2
  • Tu scripts

    Tu scripts

    • Adds scripts for NCI109 and IMDBB for, resp., CWN and MPSN
    • Removes tuning config files and adds some comments
    • Removes old sh script for mol exps
    • Adds support for NCI109 data loading
    opened by Noired 2
  • Format of TUDataset txt file

    Format of TUDataset txt file

    Hi I'm currently working on running TUDatasets (REDDITBINRARY & NCI109) by running following command

    sh ./exp/scripts/cwn-nci109.sh
    sh ./exp/scripts/mpsn-redditb.sh
    

    I checked REDDITBINARY & NCI109 from here but noticed that they have multiple types of txt file such as.. [ REDDITBINARY ]

    • REDDIT-BINARY_A.txt
    • REDDIT-BINARY_graph_indicator.txt
    • REDDIT-BINARY_graph_labels.txt

    [ NCI109_A ]

    • NCI109_A.txt
    • NCI109_graph_indicator.txt
    • NCI109_graph_labels.txt
    • NCI109_node_labels.txt

    However I found that data/tu_utils.py ->def load_data(path, dataset, degree_as_tag): only takes one txt file.

    ## data/tu_utils.py
    def load_data(path, dataset, degree_as_tag):
        """
            dataset: name of dataset
            test_proportion: ratio of test train split
            seed: random seed for random splitting of dataset
        """
    
        print('loading data')
        g_list = []
        label_dict = {}
        feat_dict = {}
    
        with open('%s/%s.txt' % (path, dataset), 'r') as f: ## <- only takes one txt file..
            n_g = int(f.readline().strip())
            for i in range(n_g):
                row = f.readline().strip().split()
                n, l = [int(w) for w in row]
                if not l in label_dict:
                    mapped = len(label_dict)
                    label_dict[l] = mapped
                g = nx.Graph()
                node_tags = []
                node_features = []
                n_edges = 0
                for j in range(n):
                    g.add_node(j)
                    row = f.readline().strip().split()
                    tmp = int(row[1]) + 2
                    if tmp == len(row):
                        # no node attributes
                        row = [int(w) for w in row]
                        attr = None
    ...
    

    So I want to ask what txt file this code requires.. Thank you :)

    opened by icecream126 1
  • fix graph tool segmentation fault

    fix graph tool segmentation fault

    This pull request fixes a SIGSEGV from graph-tool=2.44 when calling gt.stats in function cwn.data.utils.get_rings

    as noted in graph_tool doc:

    # import numpy and scipy before everything to avoid weird segmentation faults # depending on the order things are imported.

    I haven't run an exhaustive debugging but importing numpy or torch before graph_tool leads to a segfault while computing the rings of a graph.

    This code will reproduce the error:

    Schermata 2022-05-01 alle 12 28 57

    After changing the position of import graph_tool as gt

    Schermata 2022-05-01 alle 12 30 17

    (I set the matrix-style terminal many years ago and never changed, sorry for that ahah)

    opened by lrnzgiusti 1
  • Working on QM9 dataset

    Working on QM9 dataset

    Hi! So I have modified relevant parts of the datasets/zinc.py to work on QM9 dataset.

    The initial conversion to cell complexes is working however while training I get an assertion error - Screenshot 2022-04-01 at 11 30 38

    Any idea how to resolve this?

    Thanks in advance!

    opened by AdarshMJ 1
  • RDTB script

    RDTB script

    • Adds the script to run mpsn on Reddit Binary
    • Updates the README accordingly

    We are able to replicate RDTB with mpsn with just 150 epochs:

    Dataset:        REDDITBINARY
    Accuracy:       0.922 ± 0.022494443758403974
    Best epoch:     148
    -------------------------------
    

    ... but I am currently running again with 200 epochs – the original value used in tuning.

    opened by Noired 1
  • Fix Orientations

    Fix Orientations

    • Fixes some bugs in the orientation equivariant models
    • Adds tests for orientation invariance and equivariance
    • Modifies the FLOW and OCEAN datasets to use different orientations on the train and test splits. The new experiments use random orientations on the test set.
    opened by crisbodnar 1
  • Timings

    Timings

    • Adds timings on training and evaluation
    • Adds prints for these data at the end of each experiment
    • Adds support to save these data along with other curves
    • Adds experiment to perform timings on data conversion
    opened by Noired 1
Owner
Twitter Research
Twitter #opensource projects related to our published research
Twitter Research
A PyTorch implementation of "Pathfinder Discovery Networks for Neural Message Passing"

A PyTorch implementation of "Pathfinder Discovery Networks for Neural Message Passing" (WebConf 2021). Abstract In this work we propose Pathfind

Benedek Rozemberczki 49 Dec 1, 2022
Official implementation of Rethinking Graph Neural Architecture Search from Message-passing (CVPR2021)

Rethinking Graph Neural Architecture Search from Message-passing Intro The GNAS can automatically learn better architecture with the optimal depth of

Shaofei Cai 48 Sep 30, 2022
BRepNet: A topological message passing system for solid models

BRepNet: A topological message passing system for solid models This repository contains the an implementation of BRepNet: A topological message passin

Autodesk AI Lab 42 Dec 30, 2022
Neural Message Passing for Computer Vision

Neural Message Passing for Quantum Chemistry Implementation of different models of Neural Networks on graphs as explained in the article proposed by G

Pau Riba 310 Nov 7, 2022
Interpretation of T cell states using reference single-cell atlases

Interpretation of T cell states using reference single-cell atlases ProjecTILs is a computational method to project scRNA-seq data into reference sing

Cancer Systems Immunology Lab 139 Jan 3, 2023
7th place solution of Human Protein Atlas - Single Cell Classification on Kaggle

kaggle-hpa-2021-7th-place-solution Code for 7th place solution of Human Protein Atlas - Single Cell Classification on Kaggle. A description of the met

null 8 Jul 9, 2021
A scanpy extension to analyse single-cell TCR and BCR data.

Scirpy: A Scanpy extension for analyzing single-cell immune-cell receptor sequencing data Scirpy is a scalable python-toolkit to analyse T cell recept

ICBI 145 Jan 3, 2023
Learning cell communication from spatial graphs of cells

ncem Features Repository for the manuscript Fischer, D. S., Schaar, A. C. and Theis, F. Learning cell communication from spatial graphs of cells. 2021

Theis Lab 77 Dec 30, 2022
pcnaDeep integrates cutting-edge detection techniques with tracking and cell cycle resolving models.

pcnaDeep: a deep-learning based single-cell cycle profiler with PCNA signal Welcome! pcnaDeep integrates cutting-edge detection techniques with tracki

ChanLab 8 Oct 18, 2022
LIVECell - A large-scale dataset for label-free live cell segmentation

LIVECell dataset This document contains instructions of how to access the data associated with the submitted manuscript "LIVECell - A large-scale data

Sartorius Corporate Research 112 Jan 7, 2023
A lightweight Python-based 3D network multi-agent simulator. Uses a cell-based congestion model. Calculates risk, loudness and battery capacities of the agents. Suitable for 3D network optimization tasks.

AMAZ3DSim AMAZ3DSim is a lightweight python-based 3D network multi-agent simulator. It uses a cell-based congestion model. It calculates risk, battery

Daniel Hirsch 13 Nov 4, 2022
Kaggle: Cell Instance Segmentation

Kaggle: Cell Instance Segmentation The goal of this challenge is to detect cells in microscope images. with simple view on how many cels have been ann

Jirka Borovec 9 Aug 12, 2022
A Parameter-free Deep Embedded Clustering Method for Single-cell RNA-seq Data

A Parameter-free Deep Embedded Clustering Method for Single-cell RNA-seq Data Overview Clustering analysis is widely utilized in single-cell RNA-seque

AI-Biomed @NSCC-gz 3 May 8, 2022
Solution of Kaggle competition: Sartorius - Cell Instance Segmentation

Sartorius - Cell Instance Segmentation https://www.kaggle.com/c/sartorius-cell-instance-segmentation Environment setup Build docker image bash .dev_sc

null 68 Dec 9, 2022
Single Red Blood Cell Hydrodynamic Traps Via the Generative Design

Rbc-traps-generative-design - The generative design for single red clood cell hydrodynamic traps using GEFEST framework

Natural Systems Simulation Lab 4 Jun 16, 2022
FIRA: Fine-Grained Graph-Based Code Change Representation for Automated Commit Message Generation

FIRA is a learning-based commit message generation approach, which first represents code changes via fine-grained graphs and then learns to generate commit messages automatically.

Van 21 Dec 30, 2022
Torchlight2 lan game server tool - A message forwarding tool for Torchlight 2 lan game

Torchlight 2 Lan Game Server Tool A message forwarding tool for Torchlight 2 lan

Huaijun Jiang 3 Nov 1, 2022
Message Encrypt and decrypt software // allows you to encrypt the secrete message and decrypt Another Encryption Message. |

Message-Encrypy-Decrypt-App Message Encrypt and decrypt software // allows you to encrypt the secrete message and decrypt Another Encryption Message.

Abdulrahman-Haji 2 Dec 16, 2021
Graph neural network message passing reframed as a Transformer with local attention

Adjacent Attention Network An implementation of a simple transformer that is equivalent to graph neural network where the message passing is done with

Phil Wang 49 Dec 28, 2022
A PyTorch implementation of "Pathfinder Discovery Networks for Neural Message Passing"

A PyTorch implementation of "Pathfinder Discovery Networks for Neural Message Passing" (WebConf 2021). Abstract In this work we propose Pathfind

Benedek Rozemberczki 49 Dec 1, 2022