Geometric Vector Perceptrons --- a rotation-equivariant GNN for learning from biomolecular structure

Overview

Geometric Vector Perceptron

Implementation of equivariant GVP-GNNs as described in Learning from Protein Structure with Geometric Vector Perceptrons by B Jing, S Eismann, P Suriana, RJL Townshend, and RO Dror.

UPDATE: Also includes equivariant GNNs with vector gating as described in Equivariant Graph Neural Networks for 3D Macromolecular Structure by B Jing, S Eismann, P Soni, and RO Dror.

Scripts for training / testing / sampling on protein design and training / testing on all ATOM3D tasks are provided.

Note: This implementation is in PyTorch Geometric. The original TensorFlow code, which is not maintained, can be found here.

Requirements

  • UNIX environment
  • python==3.6.13
  • torch==1.8.1
  • torch_geometric==1.7.0
  • torch_scatter==2.0.6
  • torch_cluster==1.5.9
  • tqdm==4.38.0
  • numpy==1.19.4
  • sklearn==0.24.1
  • atom3d==0.2.1

While we have not tested with other versions, any reasonably recent versions of these requirements should work.

General usage

We provide classes in three modules:

  • gvp: core GVP modules and GVP-GNN layers
  • gvp.data: data pipelines for both general use and protein design
  • gvp.models: implementations of MQA and CPD models
  • gvp.atom3d: models and data pipelines for ATOM3D

The core modules in gvp are meant to be as general as possible, but you will likely have to modify gvp.data and gvp.models for your specific application, with the existing classes serving as examples.

Installation: Download this repository and run python setup.py develop or pip install . -e. Be sure to manually install torch_geometric first!

Tuple representation: All inputs and outputs with both scalar and vector channels are represented as a tuple of two tensors (s, V). Similarly, all dimensions should be specified as tuples (n_scalar, n_vector) where n_scalar and n_vector are the number of scalar and vector features, respectively. All V tensors must be shaped as [..., n_vector, 3], not [..., 3, n_vector].

Batching: We adopt the torch_geometric convention of absorbing the batch dimension into the node dimension and keeping track of batch index in a separate tensor.

Amino acids: Models view sequences as int tensors and are agnostic to aa-to-int mappings. Such mappings are specified as the letter_to_num attribute of gvp.data.ProteinGraphDataset. Currently, only the 20 standard amino acids are supported.

For all classes, see the docstrings for more detailed usage. If you have any questions, please contact [email protected].

Core GVP classes

The class gvp.GVP implements a Geometric Vector Perceptron.

import gvp

in_dims = scalars_in, vectors_in
out_dims = scalars_out, vectors_out
gvp_ = gvp.GVP(in_dims, out_dims)

To use vector gating, pass in vector_gate=True and the appropriate activations.

gvp_ = gvp.GVP(in_dims, out_dims,
            activations=(F.relu, None), vector_gate=True)

The classes gvp.Dropout and gvp.LayerNorm implement vector-channel dropout and layer norm, while using normal dropout and layer norm for scalar channels. Both expect inputs and return outputs of form (s, V), but will also behave like their scalar-valued counterparts if passed a single tensor.

dropout = gvp.Dropout(drop_rate=0.1)
layernorm = gvp.LayerNorm(out_dims)

The function gvp.randn returns tuples (s, V) drawn from a standard normal. Such tuples can be directly used in a forward pass.

x = gvp.randn(n=5, dims=in_dims)
# x = (s, V) with s.shape = [5, scalars_in] and V.shape = [5, vectors_in, 3]

out = gvp_(x)
out = drouput(out)
out = layernorm(out)

Finally, we provide utility functions for adding, concatenating, and indexing into such tuples.

y = gvp.randn(n=5, dims=in_dims)
z = gvp.tuple_sum(x, y)
z = gvp.tuple_cat(x, y, dim=-1) # concat along channel axis
z = gvp.tuple_cat(x, y, dim=-2) # concat along node / batch axis

node_mask = torch.rand(5) < 0.5
z = gvp.tuple_index(x, node_mask) # select half the nodes / batch at random

GVP-GNN layers

The class GVPConv is a torch_geometric.MessagePassing module which forms messages and aggregates them at the destination node, returning new node embeddings. The original embeddings are not updated.

nodes = gvp.randn(n=5, in_dims)
edges = gvp.randn(n=10, edge_dims) # 10 random edges
edge_index = torch.randint(0, 5, (2, 10), device=device)

conv = gvp.GVPConv(in_dims, out_dims, edge_dims)
out = conv(nodes, edge_index, edges)

The class GVPConvLayer is a nn.Module that forms messages using a GVPConv and updates the node embeddings as described in the paper. Because the updates are residual, the dimensionality of the embeddings are not changed.

layer = gvp.GVPConvLayer(node_dims, edge_dims)
nodes = layer(nodes, edge_index, edges)

The class also allows updates where incoming messages where src >= dst are computed using a different set of source embeddings, as in autoregressive models.

nodes_static = gvp.randn(n=5, in_dims)
layer = gvp.GVPConvLayer(node_dims, edge_dims, autoregressive=True)
nodes = layer(nodes, edge_index, edges, autoregressive_x=nodes_static)

Both GVPConv and GVPConvLayer accept arguments activations and vector_gate to use vector gating.

Loading data

The class gvp.data.ProteinGraphDataset transforms protein backbone structures into featurized graphs. Following Ingraham, et al, NeurIPS 2019, we use a JSON/dictionary format to specify backbone structures:

[
    {
        "name": "NAME"
        "seq": "TQDCSFQHSP...",
        "coords": [[[74.46, 58.25, -21.65],...],...]
    }
    ...
]

For each structure, coords should be a num_residues x 4 x 3 nested list of the positions of the backbone N, C-alpha, C, and O atoms of each residue (in that order).

import gvp.data

# structures is a list or list-like as shown above
dataset = gvp.data.ProteinGraphDataset(structures)
# dataset[i] is featurized graph corresponding to structures[i]

The returned graphs are of type torch_geometric.data.Data with attributes

  • x: alpha carbon coordinates
  • seq: sequence converted to int tensor according to attribute self.letter_to_num
  • name, edge_index
  • node_s, node_v: node features as described in the paper with dims (6, 3)
  • edge_s, edge_v: edge features as described in the paper with dims (32, 1)
  • mask: false for nodes with any nan coordinates

The gvp.data.ProteinGraphDataset can be used with a torch.utils.data.DataLoader. We supply a class gvp.data.BatchSampler which will form batches based on the number of total nodes in a batch. Use of this sampler is optional.

node_counts = [len(s['seq']) for s in structures]
sampler = gvp.data.BatchSampler(node_counts, max_nodes=3000)
dataloader = torch.utils.data.DataLoader(dataset, batch_sampler=sampler)

The dataloader will return batched graphs of type torch_geometric.data.Batch with an additional batch attibute. The attributes of the Batch will then need to be formed into (s, V) tuples before passing into a GVP-GNN layer or network.

for batch in dataloader:
    batch = batch.to(device) # optional
    nodes = (batch.node_s, batch.node_v)
    edges = (batch.edge_s, batch.edge_v)
    
    out = layer(nodes, batch.edge_index, edges)

Ready-to-use protein GNNs

We provide two fully specified networks which take in protein graphs and output a scalar prediction for each graph (gvp.models.MQAModel) or a 20-dimensional feature vector for each node (gvp.models.CPDModel), corresponding to the two tasks in our paper. Note that if you are using the unmodified gvp.data.ProteinGraphDataset, node_in_dims and edge_in_dims must be (6, 3) and (32, 1), respectively.

import gvp.models

# batch, nodes, edges as formed above

mqa_model = gvp.models.MQAModel(node_in_dim, node_h_dim, 
                        edge_in_dim, edge_h_dim, seq_in=True)
out = mqa_model(nodes, batch.edge_index, edges,
                 seq=batch.seq, batch=batch.batch) # shape (n_graphs,)

cpd_model = gvp.models.CPDModel(node_in_dim, node_h_dim, 
                        edge_in_dim, edge_h_dim)
out = cpd_model(nodes, batch.edge_index, 
                 edges, batch.seq) # shape (n_nodes, 20)

Protein design

We provide a script run_cpd.py to train, validate, and test a CPDModel as specified in the paper using the CATH 4.2 dataset and TS50 dataset. If you want to use a trained model on new structures, see the section "Sampling" below.

Fetching data

Run getCATH.sh in data/ to fetch the CATH 4.2 dataset. If you are interested in testing on the TS 50 test set, also run grep -Fv -f ts50remove.txt chain_set.jsonl > chain_set_ts50.jsonl to produce a training set without overlap with the TS 50 test set.

Training / testing

To train a model, simply run python run_cpd.py --train. To test a trained model on both the CATH 4.2 test set and the TS50 test set, run python run_cpd --test-r PATH for perplexity or with --test-p for perplexity. Run python run_cpd.py -h for more detailed options.

$ python run_cpd.py -h

usage: run_cpd.py [-h] [--models-dir PATH] [--num-workers N] [--max-nodes N] [--epochs N] [--cath-data PATH] [--cath-splits PATH] [--ts50 PATH] [--train] [--test-r PATH] [--test-p PATH] [--n-samples N]

optional arguments:
  -h, --help          show this help message and exit
  --models-dir PATH   directory to save trained models, default=./models/
  --num-workers N     number of threads for loading data, default=4
  --max-nodes N       max number of nodes per batch, default=3000
  --epochs N          training epochs, default=100
  --cath-data PATH    location of CATH dataset, default=./data/chain_set.jsonl
  --cath-splits PATH  location of CATH split file, default=./data/chain_set_splits.json
  --ts50 PATH         location of TS50 dataset, default=./data/ts50.json
  --train             train a model
  --test-r PATH       evaluate a trained model on recovery (without training)
  --test-p PATH       evaluate a trained model on perplexity (without training)
  --n-samples N       number of sequences to sample (if testing recovery), default=100

Confusion matrices: Note that the values are normalized such that each row (corresponding to true class) sums to 1000, with the actual number of residues in that class printed under the "Count" column.

Sampling

To sample from a CPDModel, prepare a ProteinGraphDataset, but do NOT pass into a DataLoader. The sequences are not used, so placeholders can be used for the seq attributes of the original structures dicts.

protein = dataset[i]
nodes = (protein.node_s, protein.node_v)
edges = (protein.edge_s, protein.edge_v)
    
sample = model.sample(nodes, protein.edge_index,  # shape = (n_samples, n_nodes)
                      edges, n_samples=n_samples)

The output will be an int tensor, with mappings corresponding to those used when training the model.

ATOM3D

We provide models and dataloaders for all ATOM3D tasks in gvp.atom3d, as well as a training and testing script in run_atom3d.py. This also supports loading pretrained weights for transfer learning experiments.

Models / data loaders

The GVP-GNNs for ATOM3D are supplied in gvp.atom3d and are named after each task: gvp.atom3d.MSPModel, gvp.atom3d.PPIModel, etc. All of these extend the base class gvp.atom3d.BaseModel. These classes take no arguments at initialization, take in a torch_geometric.data.Batch representation of a batch of structures, and return an output corresponding to the task. Details vary based on the exact task---see the docstrings.

psr_model = gvp.atom3d.PSRModel()

gvp.atom3d also includes data loaders to produce torch_geometric.data.Batch objects from an underlying atom3d.datasets.LMDBDataset. In the case of all tasks except PPI and RES, these are in the form of callable transform objects---gvp.atom3d.SMPTransform, gvp.atom3d.RSRTransform, etc---which should be passed into the constructor of a atom3d.datasets.LMDBDataset:

psr_dataset = atom3d.datasets.LMDBDataset(path_to_dataset,
                    transform=gvp.atom3d.PSRTransform())

On the other hand, gvp.atom3d.PPIDataset and gvp.atom3d.RESDataset take the place of / are wrappers around the atom3d.datasets.LMDBDataset:

ppi_dataset = gvp.atom3d.PPIDataset(path_to_dataset)
res_dataset = gvp.atom3d.RESDataset(path_to_dataset, path_to_split) # see docstring

All datasets must be then wrapped in a torch_geometric.data.DataLoader:

psr_dataloader = torch_geometric.data.DataLoader(psr_dataset, batch_size=batch_size)

The dataloaders can be directly iterated over to yield torch_geometric.data.Batch objects, which can then be passed into the models.

for batch in psr_dataloader:
    pred = psr_model(batch) # pred.shape = (batch_size,)

Training / testing

To run training / testing on ATOM3D, download the datasets as described here. Modify the function get_datasets in run_atom3d.py with the paths to the datasets. Then run:

$ python run_atom3d.py -h

usage: run_atom3d.py [-h] [--num-workers N] [--smp-idx IDX]
                     [--lba-split SPLIT] [--batch SIZE] [--train-time MINUTES]
                     [--val-time MINUTES] [--epochs N] [--test PATH]
                     [--lr RATE] [--load PATH]
                     TASK

positional arguments:
  TASK                  {PSR, RSR, PPI, RES, MSP, SMP, LBA, LEP}

optional arguments:
  -h, --help            show this help message and exit
  --num-workers N       number of threads for loading data, default=4
  --smp-idx IDX         label index for SMP, in range 0-19
  --lba-split SPLIT     identity cutoff for LBA, 30 (default) or 60
  --batch SIZE          batch size, default=8
  --train-time MINUTES  maximum time between evaluations on valset,
                        default=120 minutes
  --val-time MINUTES    maximum time per evaluation on valset, default=20
                        minutes
  --epochs N            training epochs, default=50
  --test PATH           evaluate a trained model
  --lr RATE             learning rate
  --load PATH           initialize first 2 GNN layers with pretrained weights

For example:

# train a model
python run_atom3d.py PSR

# train a model with pretrained weights
python run_atom3d.py PSR --load PATH

# evaluate a model
python run_atom3d.py PSR --test PATH

Acknowledgements

Portions of the input data pipeline were adapted from Ingraham, et al, NeurIPS 2019. We thank Pratham Soni for portions of the implementation in PyTorch.

Citation

@inproceedings{
    jing2021learning,
    title={Learning from Protein Structure with Geometric Vector Perceptrons},
    author={Bowen Jing and Stephan Eismann and Patricia Suriana and Raphael John Lamarre Townshend and Ron Dror},
    booktitle={International Conference on Learning Representations},
    year={2021},
    url={https://openreview.net/forum?id=1YLJDvSx6J4}
}

@article{jing2021equivariant,
  title={Equivariant Graph Neural Networks for 3D Macromolecular Structure},
  author={Jing, Bowen and Eismann, Stephan and Soni, Pratham N and Dror, Ron O},
  journal={arXiv preprint arXiv:2106.03843},
  year={2021}
}
Comments
  • What's torch_sparse version?

    What's torch_sparse version?

    I didn't see it in the requirements, but torch_sparse seems to require it, so I installed 0.6.12, but I get the following error: torch_sparse seems to have the same problem, but I want to know what version configuration is in this repository. Please let me know the results of pip list or conda list or something like that .

    Traceback (most recent call last):
      File "/home/gvp-pytorch/run_cpd.py", line 32, in <module>
        import gvp.data, gvp.models
      File "/home/gvp-pytorch/gvp/__init__.py", line 4, in <module>
        from torch_geometric.nn import MessagePassing
      File "/home/.pyenv/versions/gvp-pytorch/lib/python3.6/site-packages/torch_geometric/__init__.py", line 5, in <module>
        import torch_geometric.data
      File "/home/.pyenv/versions/gvp-pytorch/lib/python3.6/site-packages/torch_geometric/data/__init__.py", line 1, in <module>
        from .data import Data
      File "/home/.pyenv/versions/gvp-pytorch/lib/python3.6/site-packages/torch_geometric/data/data.py", line 8, in <module>
        from torch_sparse import coalesce, SparseTensor
      File "/home/.pyenv/versions/gvp-pytorch/lib/python3.6/site-packages/torch_sparse/__init__.py", line 16, in <module>
        f'{library}_{suffix}', [osp.dirname(__file__)]).origin)
    AttributeError: 'NoneType' object has no attribute 'origin'
    
    opened by blacktanktop 1
  • Vector gated models for Proteins vs Atom3D

    Vector gated models for Proteins vs Atom3D

    Thank you for releasing the code and for making it well documented! I'm really fascinated by this recent line of work on Atom3D, GVP, and the recent vector gating extension.

    I was wondering if vector gating always improves performance over the original GVP design, even for tasks from the ICLR'21 paper?

    opened by chaitjo 0
  • Pretrained Tensorflow model reloading

    Pretrained Tensorflow model reloading

    In Tensorflow implementation of gvp, a pretrained model is mentioned:

    Our training pipeline uses the CATH 4.2 dataset curated by [Ingraham, et al, NeurIPS 2019](https://github.com/jingraham/neurips19-graph-protein-design). We provide code to train, validate, and test the model on this dataset. We also provide a pretrained model in models/cath_pretrained. If you want to test a trained model on new structures, see the section "Using the CPD model" below.
    

    Is there any way to reload this Tensorflow version pretrained model in PyTorch version?

    opened by popfido 1
  • Training time on the Residue (RES) Dataset

    Training time on the Residue (RES) Dataset

    Hi Bowen,

    thanks for sharing this nice code base of the GVP model in combination with the Atom3D benchmark. I am currently running the Residue https://www.atom3d.ai/res.html benchmark and noticed that the dataset is quite large with 3,733,710 samples in the training set (See Appendix D.3 in https://arxiv.org/pdf/2012.04035.pdf) - I was wondering how long you trained the GVP-GNN on the RES dataset? In the default arguments, the maximum training time per epoch is set to 120 minutes.https://github.com/drorlab/gvp-pytorch/blob/82af6b22eaf8311c15733117b0071408d24ed877/run_atom3d.py#L16-L17

    I am currently training a similar model to GVP using batch-size 32 on the RES dataset and require ~5.5hours on an NVIDIA V100 GPU per epoch. Could you tell me, how long you trained your model to obtain 0.527 ± 0.003 test accuracy?

    Thanks!

    opened by tuanle618 0
  • Equal variance test failed

    Equal variance test failed

    Hi, I tried to run test_equalvariance.py after configuring the environment, but the output says that all tests failed. The output is shown in the figure below, and the configured environment is also given.

    1659670284744

    `Package Version


    ase 3.22.1 atom3d 0.2.1 biopython 1.79 cached-property 1.5.2 certifi 2022.6.15 charset-normalizer 2.0.12 click 8.0.4 cycler 0.11.0 dataclasses 0.8 decorator 4.4.2 dill 0.3.4 easy-parallel 0.1.6 freesasa 2.1.0 googledrivedownloader 0.4 h5py 3.1.0 idna 3.3 importlib-metadata 4.8.3 importlib-resources 5.4.0 isodate 0.6.1 Jinja2 3.0.3 joblib 1.1.0 kiwisolver 1.3.1 llvmlite 0.36.0 lmdb 1.3.0 MarkupSafe 2.0.1 matplotlib 3.3.4 msgpack 1.0.4 multiprocess 0.70.12.2 networkx 2.5.1 numba 0.53.1 numexpr 2.8.1 numpy 1.19.4 packaging 21.3 pandas 1.1.5 pathos 0.2.8 Pillow 8.4.0 pip 21.2.4 pox 0.3.0 ppft 1.6.6.4 pyparsing 3.0.9 python-dateutil 2.8.2 python-dotenv 0.20.0 python-louvain 0.16 pytz 2022.1 rdflib 5.0.0 requests 2.27.1 scikit-learn 0.24.2 scipy 1.5.4 setuptools 49.6.0.post20210108 six 1.16.0 sklearn 0.0 tables 3.7.0 threadpoolctl 3.1.0 torch 1.8.1+cu111 torch-cluster 1.5.9 torch-geometric 1.7.0 torch-scatter 2.0.6 torch-sparse 0.6.10 torchaudio 0.8.1 torchvision 0.9.1+cu111 tqdm 4.38.0 typing_extensions 4.1.1 urllib3 1.26.10 wheel 0.37.1 zipp 3.6.0 `

    Is it the GVP-GNN problem of the pytorch version?

    opened by zyk19981118 0
  • atom3d.datasets.ppi.neighbors not in atom3d codebase

    atom3d.datasets.ppi.neighbors not in atom3d codebase

    I am unable to do import atom3d.datasets.ppi.neighbors as nb as described in the atom3d.py file. I tried installing the atom3d version specified in setup.py as well as the most recent but neither appear to have a ppi submodule of datasets. Thanks!

    opened by hnisonoff 4
  • Implementation inconsistency

    Implementation inconsistency

    Hello, I was looking over the Tensorflow and Pytorch versions of the CPD model and realized they are inconsistent.

    In Tensorflow version when we are converting input to the features there is an extra GVP layer. Here is the node embedding and edge embedding functions defined under StructuralFeatures which is called here. Right after this we apply another set of GVP layers for both edge and vertex embeddings.

    Meanwhile in Pytorch version we are missing the GVP layers under StructuralFeatures. Instead edge and vertex features only normalize while converting the inputs to features under ProteinGraphDataset. Then just like in Tensorflow version GVP layers applied to normalized vertex and edge features.

    Can you please clarify this issue?

    opened by fmocking 1
Owner
Dror Lab
Ron Dror's computational biology laboratory at Stanford University
Dror Lab
Implementation of Geometric Vector Perceptron, a simple circuit for 3d rotation equivariance for learning over large biomolecules, in Pytorch. Idea proposed and accepted at ICLR 2021

Geometric Vector Perceptron Implementation of Geometric Vector Perceptron, a simple circuit with 3d rotation equivariance for learning over large biom

Phil Wang 59 Nov 24, 2022
The official implementation of our CVPR 2021 paper - Hybrid Rotation Averaging: A Fast and Robust Rotation Averaging Approach

Graph Optimizer This repo contains the official implementation of our CVPR 2021 paper - Hybrid Rotation Averaging: A Fast and Robust Rotation Averagin

Chenyu 109 Dec 23, 2022
Official code of the paper "ReDet: A Rotation-equivariant Detector for Aerial Object Detection" (CVPR 2021)

ReDet: A Rotation-equivariant Detector for Aerial Object Detection ReDet: A Rotation-equivariant Detector for Aerial Object Detection (CVPR2021), Jiam

csuhan 334 Dec 23, 2022
You Only Hypothesize Once: Point Cloud Registration with Rotation-equivariant Descriptors

You Only Hypothesize Once: Point Cloud Registration with Rotation-equivariant Descriptors In this paper, we propose a novel local descriptor-based fra

Haiping Wang 80 Dec 15, 2022
Vector Neurons: A General Framework for SO(3)-Equivariant Networks

Vector Neurons: A General Framework for SO(3)-Equivariant Networks Created by Congyue Deng, Or Litany, Yueqi Duan, Adrien Poulenard, Andrea Tagliasacc

Congyue Deng 332 Dec 29, 2022
Vector AI — A platform for building vector based applications. Encode, query and analyse data using vectors.

Vector AI is a framework designed to make the process of building production grade vector based applications as quickly and easily as possible. Create

Vector AI 267 Dec 23, 2022
[CIKM 2019] Code and dataset for "Fi-GNN: Modeling Feature Interactions via Graph Neural Networks for CTR Prediction"

FiGNN for CTR prediction The code and data for our paper in CIKM2019: Fi-GNN: Modeling Feature Interactions via Graph Neural Networks for CTR Predicti

Big Data and Multi-modal Computing Group, CRIPAC 75 Dec 30, 2022
QA-GNN: Question Answering using Language Models and Knowledge Graphs

QA-GNN: Question Answering using Language Models and Knowledge Graphs This repo provides the source code & data of our paper: QA-GNN: Reasoning with L

Michihiro Yasunaga 434 Jan 4, 2023
Distance Encoding for GNN Design

Distance-encoding for GNN design This repository is the official PyTorch implementation of the DEGNN and DEAGNN framework reported in the paper: Dista

null 172 Nov 8, 2022
A graph neural network (GNN) model to predict protein-protein interactions (PPI) with no sample features

A graph neural network (GNN) model to predict protein-protein interactions (PPI) with no sample features

null 2 Jul 25, 2022
GNN-based Recommendation Benchma

GRecX A Fair Benchmark for GNN-based Recommendation Preliminary Comparison DiffNet-Yelp dataset (featureless) Algo nDCG@5 nDCG@10 nDCG@15 MF 0.158707

null 73 Oct 17, 2022
DIR-GNN - Discovering Invariant Rationales for Graph Neural Networks

DIR-GNN "Discovering Invariant Rationales for Graph Neural Networks" (ICLR 2022)

Ying-Xin (Shirley) Wu 70 Nov 13, 2022
Equivariant Imaging: Learning Beyond the Range Space

[Project] Equivariant Imaging: Learning Beyond the Range Space Project about the

Georges Le Bellier 3 Feb 6, 2022
A series of convenience functions to make basic image processing operations such as translation, rotation, resizing, skeletonization, and displaying Matplotlib images easier with OpenCV and Python.

imutils A series of convenience functions to make basic image processing functions such as translation, rotation, resizing, skeletonization, and displ

Adrian Rosebrock 4.3k Jan 8, 2023
Rotation Robust Descriptors

RoRD Rotation-Robust Descriptors and Orthographic Views for Local Feature Matching Project Page | Paper link Evaluation and Datasets MMA : Training on

Udit Singh Parihar 25 Nov 15, 2022
Rotation-Only Bundle Adjustment

ROBA: Rotation-Only Bundle Adjustment Paper, Video, Poster, Presentation, Supplementary Material In this repository, we provide the implementation of

Seong 51 Nov 29, 2022
Patch Rotation: A Self-Supervised Auxiliary Task for Robustness and Accuracy of Supervised Models

Patch-Rotation(PatchRot) Patch Rotation: A Self-Supervised Auxiliary Task for Robustness and Accuracy of Supervised Models Submitted to Neurips2021 To

null 4 Jul 12, 2021