Graph Posterior Network: Bayesian Predictive Uncertainty for Node Classification (NeurIPS 2021)

Overview

Graph Posterior Network

This is the official code repository to the paper

Graph Posterior Network: Bayesian Predictive Uncertainty for Node Classification
Maximilian Stadler, Bertrand Charpentier, Simon Geisler, Daniel Zügner, Stephan Günnemann
Conference on Neural Information Processing Systems (NeurIPS) 2021.

[Paper]|Video - coming soon]

Diagram

Installation

We recommend running this code with its dependencies in a conda enviroment. To begin with, create a new conda environment with all the necessary dependencies assuming that you are in the root directory of this project:

conda env create -f gpn_environment.yml python==3.8 --force

Since the code is packaged, you will also have to setup the code accordingly. Assuming that you are in the root directory of this project, run:

conda activate gpn
pip3 install -e .

Data

Since we rely on published datasets from the Torch-Geometric package, you don't have to download datasets manually. When you run experiments on supported datasets, those will be downloaded and placed in the corresponding data directories. You can run the following datasets

  • CoraML
  • CiteSeer
  • PubMed
  • AmazonPhotos
  • AmazonComputers
  • CoauthorCS
  • CoauthorPhysics

Running Experiments

The experimental setup builds upon Sacred and configuring experiments in .yamlfiles. We will provide configurations

  • for vanilla node classification
  • leave-out-class experiments
  • experiments with isolated node perturbations
  • experiments for feature shifts
  • experiments for edge shifts

with a default fraction of perturbed nodes of 10%. We provide them for the smaller datasets (i.e. all except ogbn-arxiv) for hidden dimensions H=10 and H=16.

The main experimental script is train_and_eval.py. Assuming that you are in the root directory of this project for all further commands, you can run experiments with

Vanilla Node Classification

For the vanilla classification on the CoraML dataset with a hidden dimension of 16 or 10 respectively, run

python3 train_and_eval.py with configs/gpn/classification_gpn_16.yaml data.dataset=CoraML
python3 train_and_eval.py with configs/gpn/classification_gpn_10.yaml data.dataset=CoraML

If you have GPU-devices availale on your system, experiments will run on device 0 on default. If no CUDA-devices can be found, the code will revert back to running only on CPUs. Runs will produce assets per default. Also note that for running experiments for graphs under perturbations, you will have to run the corresponding vanilla classification experiment first.

Options for Feature Shifts

We consider random features from Unit Gaussian Distribution (normal) and from a Bernoulli Distribution (bernoulli_0.5). When using the configuration ood_features, you can change those settings (key ood_perturbation_type) in the command line together with the fraction of perturbed nodes (key ood_budget_per_graph) or in the corresponding configurations files, for example as

python3 train_and_eval.py with configs/gpn/ood_features_gpn_16.yaml data.dataset=CoraML data.ood_perturbation_type=normal data.ood_budget_per_graph=0.025
python3 train_and_eval.py with configs/gpn/ood_features_gpn_16.yaml data.dataset=CoraML data.ood_perturbation_type=bernoulli_0.5 data.ood_budget_per_graph=0.025

For experiments considering perturbations in an isolated fashion, this applies accordingly but without the fraction of perturbed nodes, e.g.

python3 train_and_eval.py with configs/gpn/ood_isolated_gpn_16.yaml data.dataset=CoraML data.ood_perturbation_type=normal
python3 train_and_eval.py with configs/gpn/ood_isolated_gpn_16.yaml data.dataset=CoraML data.ood_perturbation_type=bernoulli_0.5

Options for Edge Shifts

We consider random edge perturbations and the global and untargeted DICE attack. Those attacks can be set with the key ood_type which can be either set to random_attack_dice or random_edge_perturbations. As above, those settings can be changed in the command line or in the corresponding configuration files. While the key ood_budget_per_graph refers to the fraction of perturbed nodes in the paragraph above, it describes the fraction of perturbed edges in this case.

python3 train_and_eval.py with configs/gpn/ood_features_gpn_16.yaml data.dataset=CoraML data.ood_type=random_attack_dice data.ood_budget_per_graph=0.025
python3 train_and_eval.py with configs/gpn/ood_features_gpn_16.yaml data.dataset=CoraML data.ood_type=random_edge_perturbations data.ood_budget_per_graph=0.025

Further Options

With the settings above, you can reproduce our experimental results. If you want to change different architectural settings, simply change the corresponding keys in the configuration files with most of them being self-explanatory.

Structure

If you want to have a detailed look at our code, we give a brief overview of our code structure.

  • configs: directory for model configurations
  • data: directory for datasets
  • gpn: source code
    • gpn.data: code related to loading datasets and creating ID and OOD datasets
    • gpn.distributions: code related to custom distributions similar to torch.distributions
    • experiments: main routines for running experiments, i.e. loading configs, setting up datasets and models, training and evaluation
    • gpn.layers: custom layers
    • gpn.models: implementation of reference models and Graph Posterior Network (+ablated models)
    • gpn.nn: training related utilities like losses, metrics, or training engines
    • gpn.utils: general utility code
  • saved_experiments: directory for saved models
  • train_and_eval.py: main script for training & evaluation
  • gpn_qualitative_evaluation.ipynb: jupyter notebook which evaluates the results from Graph Posterior Network in a qualitative fashion

Note that we provide the implementations of most of our used reference models. Our main Graph Posterior Network model can be found in gpn.models.gpn_base.py. Ablated models can be found in a similar fashion, i.e. PostNet in gpn.models.gpn_postnet.py, PostNet+diffusion in gpn.models.gpn_postnet_diff.py and the model diffusiong log-beta scores in gpn.models.gpn_log_beta.py.

We provide all basic configurations for reference models in configs/reference. Note that some models have dependencies with others, e.g. running classification_gcn_dropout.yaml or classification_gcn_energy.yaml would require training the underlying GCN first by running classification_gcn.yaml first, running classification_gcn_ensemble.yaml would require training 10 GCNs first with init_no in 1...10, and running classification_sgcn.yaml (GKDE-GCN) would require training the teacher-GCN first by running classification_gcn.yaml and computing the kernel values by running classification_gdk.yaml first.

Cite

Please cite our paper if you use the model or this code in your own work.

@incollection{graph-postnet,
title={Graph Posterior Network: Bayesian Predictive Uncertainty for Node Classification},
author={Stadler, Maximilian and Charpentier, Bertrand and Geisler, Simon and Z{\"u}gner, Daniel and G{\"u}nnemann, Stephan},
booktitle = {Advances in Neural Information Processing Systems},
volume = {34},
publisher = {Curran Associates, Inc.},
year = {2021}
}
You might also like...
Companion code for the paper "An Infinite-Feature Extension for Bayesian ReLU Nets That Fixes Their Asymptotic Overconfidence" (NeurIPS 2021)

ReLU-GP Residual (RGPR) This repository contains code for reproducing the following NeurIPS 2021 paper: @inproceedings{kristiadi2021infinite, title=

git git《Transformer Meets Tracker: Exploiting Temporal Context for Robust Visual Tracking》(CVPR 2021) GitHub:git2] 《Masksembles for Uncertainty Estimation》(CVPR 2021) GitHub:git3]
git git《Transformer Meets Tracker: Exploiting Temporal Context for Robust Visual Tracking》(CVPR 2021) GitHub:git2] 《Masksembles for Uncertainty Estimation》(CVPR 2021) GitHub:git3]

Transformer Meets Tracker: Exploiting Temporal Context for Robust Visual Tracking Ning Wang, Wengang Zhou, Jie Wang, and Houqiang Li Accepted by CVPR

PyTorch Code of "Memory In Memory: A Predictive Neural Network for Learning Higher-Order Non-Stationarity from Spatiotemporal Dynamics"

Memory In Memory Networks It is based on the paper Memory In Memory: A Predictive Neural Network for Learning Higher-Order Non-Stationarity from Spati

Self-supervised learning on Graph Representation Learning (node-level task)

graph_SSL Self-supervised learning on Graph Representation Learning (node-level task) How to run the code To run GRACE, sh run_GRACE.sh To run GCA, sh

Node-level Graph Regression with Deep Gaussian Process Models

Node-level Graph Regression with Deep Gaussian Process Models Prerequests our implementation is mainly based on tensorflow 1.x and gpflow 1.x: python

Node for thenewboston digital currency network.
Node for thenewboston digital currency network.

Project setup For project setup see INSTALL.rst Community Join the community to stay updated on the most recent developments, project roadmaps, and ra

A PyTorch implementation of
A PyTorch implementation of "Semi-Supervised Graph Classification: A Hierarchical Graph Perspective" (WWW 2019)

SEAL ⠀⠀⠀ A PyTorch implementation of Semi-Supervised Graph Classification: A Hierarchical Graph Perspective (WWW 2019) Abstract Node classification an

On Size-Oriented Long-Tailed Graph Classification of Graph Neural Networks

On Size-Oriented Long-Tailed Graph Classification of Graph Neural Networks We provide the code (in PyTorch) and datasets for our paper "On Size-Orient

Hl classification bc - A Network-Based High-Level Data Classification Algorithm Using Betweenness Centrality
Hl classification bc - A Network-Based High-Level Data Classification Algorithm Using Betweenness Centrality

A Network-Based High-Level Data Classification Algorithm Using Betweenness Centr

Comments
  • ResolvePackageNotFound for installing the conda environment

    ResolvePackageNotFound for installing the conda environment

    Hi, I tried to install the conda environment for the repo and encountered this problem:

    (base) viet@cad660901:~/work/Graph-Posterior-Network$ conda env create -f gpn_environment.yml python==3.8 --force
    Collecting package metadata (repodata.json): done
    Solving environment: failed
    
    ResolvePackageNotFound: 
      - python==3.8.3=hcff3b4d_2c
    

    I wonder if there is any change from your side that I should follow? Thank you.

    opened by vietngth 6
  • Epistemic uncertainty with and without effects

    Epistemic uncertainty with and without effects

    Hi, I ran the experiments for ood_loc_gpn_{10,16} to reproduce the results. The metrics are logged after training as follows:

    | | val | test | |:----------------------------------------|-------------:|--------------:| | accuracy | 0.923077 | 0.889306 | | brier_score | 0.280527 | 0.269254 | | ECE | 0.10638 | 0.0702577 | | confidence_aleatoric_apr | 0.966722 | 0.980251 | | confidence_epistemic_apr | 0.95776 | 0.962611 | | confidence_structure_apr | nan | nan | | confidence_aleatoric_auroc | 0.706276 | 0.864282 | | confidence_epistemic_auroc | 0.635031 | 0.772384 | | confidence_structure_auroc | nan | nan | | CE | 0.37979 | 0.339846 | | avg_prediction_confidence_aleatoric | 0.816697 | 0.819579 | | avg_prediction_confidence_epistemic | 14919.8 | 14410.5 | | avg_sample_confidence_aleatoric | 0.816697 | 0.819579 | | avg_sample_confidence_epistemic | 16556.9 | 15927.3 | | avg_sample_confidence_features | 15835.7 | 16779.6 | | avg_sample_confidence_neighborhood | nan | nan | | average_entropy | 0.513569 | 0.501767 | | ood_detection_aleatoric_apr | 0.801985 | 0.78415 | | ood_detection_aleatoric_auroc | 0.833289 | 0.836685 | | ood_detection_epistemic_apr | 0.80048 | 0.788122 | | ood_detection_epistemic_auroc | 0.852889 | 0.855747 | | ood_detection_features_apr | 0.75896 | 0.748484 | | ood_detection_features_auroc | 0.81794 | 0.8237 | | ood_detection_neighborhood_apr | nan | nan | | ood_detection_neighborhood_auroc | nan | nan | | ood_detection_structure_apr | nan | nan | | ood_detection_structure_auroc | nan | nan | | ood_accuracy | 0 | 0 | | ood_avg_prediction_confidence_aleatoric | 0.556919 | 0.558297 | | ood_avg_prediction_confidence_epistemic | 2879.92 | 2808.5 | | ood_avg_sample_confidence_aleatoric | 0.556919 | 0.558297 | | ood_avg_sample_confidence_epistemic | 4068.24 | 4109.26 | | ood_avg_sample_confidence_neighborhood | nan | nan | | ood_avg_sample_confidence_features | 2063.81 | 1759.3 | | ood_average_entropy | 1.03177 | 1.03767 | | id_accuracy | 0.923077 | 0.889306 | | id_avg_prediction_confidence_aleatoric | 0.816697 | 0.819579 | | id_avg_prediction_confidence_epistemic | 14919.8 | 14410.5 | | id_avg_sample_confidence_aleatoric | 0.816697 | 0.819579 | | id_avg_sample_confidence_epistemic | 16556.9 | 15927.3 | | id_avg_sample_confidence_features | 15835.7 | 16779.6 | | id_average_entropy | 0.513569 | 0.501767 |

    Is this experiment exclusive for the With Effect case? I would like to reproduce 3 cases: aleatoric w/Net, Epist w/Net and Epist w/o Net as table 1 in the paper. Could you provide me with some guidance? Thank you.

    opened by vietngth 0
  • AttributeError: Can't get attribute 'DataEdgeAttr'

    AttributeError: Can't get attribute 'DataEdgeAttr'

    Hi, I followed the environment creation and when I tried to direct run the vanilla classification with the given yml, the error happened. I spent some time but still have no clue how to fix this. Could you help to look into this and help me out? Thank you so much!

    (gpn) labcluster@lambda-:/data/xueyingy/Graph-Posterior-Network$ python3 train_and_eval.py with configs/gpn/classification_gpn_10.yaml data.dataset=CoraML
    WARNING:root:The OGB package is out of date. Your version is 1.3.1, while the latest version is 1.3.4.
    Using backend: pytorch
    2022-10-25 23:30:22.619741: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
    WARNING:root:Added new config entry: "data.dataset"
    WARNING:root:Added new config entry: "data.ood_flag"
    WARNING:root:Added new config entry: "data.root"
    WARNING:root:Added new config entry: "data.split"
    WARNING:root:Added new config entry: "data.split_no"
    WARNING:root:Added new config entry: "data.test_samples_per_class"
    WARNING:root:Added new config entry: "data.train_samples_per_class"
    WARNING:root:Added new config entry: "data.val_samples_per_class"
    WARNING:root:Added new config entry: "model.K"
    WARNING:root:Added new config entry: "model.add_self_loops"
    WARNING:root:Added new config entry: "model.alpha_evidence_scale"
    WARNING:root:Added new config entry: "model.alpha_teleport"
    WARNING:root:Added new config entry: "model.approximate_reg"
    WARNING:root:Added new config entry: "model.dim_hidden"
    WARNING:root:Added new config entry: "model.dim_latent"
    WARNING:root:Added new config entry: "model.dropout_prob"
    WARNING:root:Added new config entry: "model.entropy_reg"
    WARNING:root:Added new config entry: "model.flow_weight_decay"
    WARNING:root:Added new config entry: "model.gaussian_layers"
    WARNING:root:Added new config entry: "model.init_no"
    WARNING:root:Added new config entry: "model.loss_reduction"
    WARNING:root:Added new config entry: "model.maf_layers"
    WARNING:root:Added new config entry: "model.model_name"
    WARNING:root:Added new config entry: "model.pre_train_mode"
    WARNING:root:Added new config entry: "model.radial_layers"
    WARNING:root:Added new config entry: "model.seed"
    WARNING:root:Added new config entry: "model.use_batched_flow"
    WARNING:root:Added new config entry: "run.eval_mode"
    WARNING:root:Added new config entry: "run.experiment_directory"
    WARNING:root:Added new config entry: "run.experiment_name"
    WARNING:root:Added new config entry: "run.gpu"
    WARNING:root:Added new config entry: "run.job"
    WARNING:root:Added new config entry: "run.save_model"
    WARNING:root:Added new config entry: "training.epochs"
    WARNING:root:Added new config entry: "training.finetune_epochs"
    WARNING:root:Added new config entry: "training.lr"
    WARNING:root:Added new config entry: "training.stopping_metric"
    WARNING:root:Added new config entry: "training.stopping_minimize"
    WARNING:root:Added new config entry: "training.stopping_mode"
    WARNING:root:Added new config entry: "training.stopping_patience"
    WARNING:root:Added new config entry: "training.stopping_restore_best"
    WARNING:root:Added new config entry: "training.warmup_epochs"
    WARNING:root:Added new config entry: "training.weight_decay"
    WARNING:train_and_eval:No observers have been added to this run
    ERROR:train_and_eval:Failed after 0:00:00!
    Traceback (most recent calls WITHOUT Sacred internals):
      File "train_and_eval.py", line 65, in run_experiment
        results = experiment.run()
      File "/data/xueyingy/Graph-Posterior-Network/gpn/experiments/multiple_run_experiment.py", line 50, in run
        results = self.run_transductive_experiment()
      File "/data/xueyingy/Graph-Posterior-Network/gpn/experiments/multiple_run_experiment.py", line 75, in run_transductive_experiment
        experiment = TransductiveExperiment(
      File "/data/xueyingy/Graph-Posterior-Network/gpn/experiments/transductive_experiment.py", line 96, in __init__
        self.dataset = ExperimentDataset(data_cfg, to_sparse=data_cfg.to_sparse)
      File "/data/xueyingy/Graph-Posterior-Network/gpn/experiments/dataset.py", line 58, in __init__
        dataset = DatasetManager(**data_cfg.to_dict())
      File "/data/xueyingy/Graph-Posterior-Network/gpn/data/dataset_manager.py", line 124, in DatasetManager
        data = D.CitationFull(root, 'Cora_ML', default_transform, None)
      File "/home/labcluster/.local/lib/python3.8/site-packages/torch_geometric/datasets/citation_full.py", line 39, in __init__
        self.data, self.slices = torch.load(self.processed_paths[0])
      File "/home/labcluster/.local/lib/python3.8/site-packages/torch/serialization.py", line 607, in load
        return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
      File "/home/labcluster/.local/lib/python3.8/site-packages/torch/serialization.py", line 882, in _load
        result = unpickler.load()
      File "/home/labcluster/.local/lib/python3.8/site-packages/torch/serialization.py", line 875, in find_class
        return super().find_class(mod_name, name)
    AttributeError: Can't get attribute 'DataEdgeAttr' on <module 'torch_geometric.data.data' from '/home/labcluster/.local/lib/python3.8/site-packages/torch_geometric/data/data.py'>
    
    opened by xyang2316 1
Pytorch Implementation of Adversarial Deep Network Embedding for Cross-Network Node Classification

Pytorch Implementation of Adversarial Deep Network Embedding for Cross-Network Node Classification (ACDNE) This is a pytorch implementation of the Adv

陈志豪 8 Oct 13, 2022
Automatically replace ONNX's RandomNormal node with Constant node.

onnx-remove-random-normal This is a script to replace RandomNormal node with Constant node. Example Imagine that we have something ONNX model like the

Masashi Shibata 1 Dec 11, 2021
A PyTorch Implementation of "Watch Your Step: Learning Node Embeddings via Graph Attention" (NeurIPS 2018).

Attention Walk ⠀⠀ A PyTorch Implementation of Watch Your Step: Learning Node Embeddings via Graph Attention (NIPS 2018). Abstract Graph embedding meth

Benedek Rozemberczki 303 Dec 9, 2022
Bayesian-Torch is a library of neural network layers and utilities extending the core of PyTorch to enable the user to perform stochastic variational inference in Bayesian deep neural networks

Bayesian-Torch is a library of neural network layers and utilities extending the core of PyTorch to enable the user to perform stochastic variational inference in Bayesian deep neural networks. Bayesian-Torch is designed to be flexible and seamless in extending a deterministic deep neural network architecture to corresponding Bayesian form by simply replacing the deterministic layers with Bayesian layers.

Intel Labs 210 Jan 4, 2023
LBK 20 Dec 2, 2022
TensorFlow implementation of "A Simple Baseline for Bayesian Uncertainty in Deep Learning"

TensorFlow implementation of "A Simple Baseline for Bayesian Uncertainty in Deep Learning"

YeongHyeon Park 7 Aug 28, 2022
TensorFlow implementation for Bayesian Modeling and Uncertainty Quantification for Learning to Optimize: What, Why, and How

Bayesian Modeling and Uncertainty Quantification for Learning to Optimize: What, Why, and How TensorFlow implementation for Bayesian Modeling and Unce

Shen Lab at Texas A&M University 8 Sep 2, 2022
G-NIA model from "Single Node Injection Attack against Graph Neural Networks" (CIKM 2021)

Single Node Injection Attack against Graph Neural Networks This repository is our Pytorch implementation of our paper: Single Node Injection Attack ag

Shuchang Tao 18 Nov 21, 2022
aka "Bayesian Methods for Hackers": An introduction to Bayesian methods + probabilistic programming with a computation/understanding-first, mathematics-second point of view. All in pure Python ;)

Bayesian Methods for Hackers Using Python and PyMC The Bayesian method is the natural approach to inference, yet it is hidden from readers behind chap

Cameron Davidson-Pilon 25.1k Jan 2, 2023