Skip to main content

Lign

Lign logo

A graph framework that can be used to implement graph convolutional networks (GCNs), geometry machine learning, continual lifelong learning on graphs and other graph-based machine learning methods alongside PyTorch

View Docs · View Examples · Report Bugs · Request Feature

Contributors Forks Stargazers Issues Mozilla License

Table of Contents

About The Project

Lign (Lifelong learning Induced by Graph Neural networks) is a framework that can be used for a wide range of graph-related problems including but not limited to graph convolutional networks (GCNs), geometry machine learning, continual lifelong learning on graphs and other graph-related machine learning methods with a tight integration to PyTorch. It was build as a component of my master thesis for a proposed lifelong learning techinique (also named Lign) that works on both graph and vector data.

Ligns currently supports a wide range of functionalities such as clustering techiniques, GCN PyTorch module, graph creation and processing, data set to graph convention, rehersal methods/retraining for GCNS and coventional neural networks, and more. Future planned additions include STL file to graph conversion, graph to STL model along with others features.

Getting Started

These are instructions for getting started with development. If only interested in the package, please install Lign via pip install lign, conda install lign -c josuecom -c pytorch or by downloading the package from github and saving it in the site-packages/ directory of your python interpreter.

For more details, please read the developer documentation

Installation

  1. Clone the repo

    git clone https://github.com/JosueCom/Lign.git
    
  2. Switch directory

    cd Lign
    
  3. Install prerequisites

    It is recommended to install PyTorch via the official site first for optimal performance

    pip install -r docs/dev/requirements.txt
    

    Or

    conda env create -f docs/dev/environment.yml -n lign
    conda activate lign
    
  4. Install package

    pip install . --upgrade
    

Usage

It is recommended to run the following instructions in a python console to view all produced output

  • Create a new graph, assign some values and view properties

    import lign as lg
    import torch as th
    
    n = 5
    g = lg.Graph()
    g.add(n)
    g['x'] = th.rand(n, 3) ## Or, g.set_data('x', th.rand(n, 3))
    
    print(g)
    print(g['x']) ## Or, g.get_data('x')
    print(g[0]) ## Or, g.get_nodes(0)
    print(g[[1, 2]]) ## Or, g.get_nodes([1, 2])
    print(g[3:]) ## Or, g.get_nodes(slice(3, None))
    print(g[(4,)]) ## Or, g.get_edges(4)
    
  • Process data with a conventional neural network

    import lign as lg
    import torch as th
    from torch import nn
    
    n = 5
    g = lg.Graph().add(n, self_loop=False, inplace=True) ## No self loop edges added since no relational data is present
    g['x'] = th.rand(n, 3)
    print(g['x'])
    
    # Data that is not relational maybe be process without the need of ligh graphs
    x = = th.rand(n, 3)
    x = linear(x)
    print(x)
    
    # However, you can use if you desire to use graph strctures
    linear = nn.Linear(3, 2)
    g['x'] = linear(g['x']) ## Or, g.apply(linear, data = 'x')
    print(g['x'])
    
  • Process relational data with a GCN

    import lign as lg
    import torch as th
    from torch import nn
    from lign.nn import GCN
    from lign.utils.functions import sum_tensors
    
    n = 5
    g = lg.Graph().add(n, inplace=True)
    g['x'] = th.rand(n, 3)
    print(g['x'])
    
    # 1^{st} Approach: Basic gcn with no message passing
    # ## It can also be processed as if it is not a graph since edge information is not used
    gcn = GCN(nn.Linear(3, 2)) 
    g['x'] = gcn(g, g['x'])
    print(g['x'])
    
    # 2^{nd} Approach: Basic gcn with message passing via neighbors data summation
    g[(2, 3, 4)] = {2, 3, 4} ## Add edges to nodes 2, 3, 4; nodes can be removed via g.remove_edges()
    gcn = GCN(nn.Linear(2, 3), aggregation = sum_tensors)
    g['x'] = gcn(g, g['x'])
    print(g['x'])
    
    # 3^{rd} Approach: Proposed GCN with discovery and inclusion layers
    gcn = GCN(nn.Linear(3, 2), aggregation = sum_tensors, inclusion = nn.Linear(2, 3))
    g['x'] = gcn(g, g['x'])
    print(g['x'])
    
  • Apply function

    import lign as lg
    import torch as th
    from torch import nn
    from lign.nn import GCN
    n = 5
    g = lg.Graph().add(n, inplace=True)
    g['x'] = th.rand(n, 3)
    
    # Use apply if involving individual nodes
    ## Adds 3 to all node's 'x' data in the data set; doesn't require neighbors
    g.apply(lambda x: x + 3, data='x')
    print(g['x'])
    
    # Use push or pull if only involving multiple nodes. Nodes will push/pull data via edges
    ## Sums neighbors 'x' value together; require neighbors
    def sum_tensors(neighs):
        return th.stack(neighs).sum(dim = 0)
    
    g[(2, 3, 4)] = {2, 3, 4}
    g.push(sum_tensors, data='x')
    print(g['x'])
    
  • Use clustering techniques for PyTorch

    from lign.utils.clustering import NN, KNN, KMeans
    import torch as th
    
    n = 20
    x = th.rand(n, 3)
    labels = (x[:, 0] > 0.5)*1
    predict = th.rand(4, 3)
    print(predict)
    
    cluster = NN(x, labels)
    print(cluster(predict))
    
    cluster = KNN(x, labels, k=3)
    print(cluster(predict))
    
    cluster = KMeans(x, k=2)
    print(cluster(predict))
    
  • Create sub graphs

    import lign as lg
    import torch as th
    n = 5
    g = lg.Graph().add(n, inplace=True)
    g['x'] = th.rand(n, 3)
    g[tuple(range(n))] = set(range(3, n)) ## Add edge from each node to 3 and 4
    print(g)
    
    # Make sub graph with all data and edges from parent; edges are updated to reflect new indexes
    sub = g.sub_graph([2, 3, 4], get_data = True, get_edges = True)
    print(sub)
    
    # Make sub graph with only edges from parent; edges are updated to reflect new indexes
    sub = g.sub_graph(2, get_edges = True)
    sub.add(2)
    print(sub)
    
    # Make sub graph with only data from parent
    ## Add nodes not known to the parent graph
    sub = g.sub_graph([3, 4], get_data = True)
    sub.add([lg.node({'x': th.rand(3)}) for i in range(2)], self_loop = False)
    print(sub)
    
    sub[(2, 3)] = sub.get_parent_edges([0, 2])
    print(sub)
    
  • Save and load created graphs

    import lign as lg
    import torch as th
    n = 5
    g = lg.Graph().add(n, inplace=True)
    g['x'] = th.rand(n, 3)
    
    # Save to file
    g.save("data/graph.lign")
    
    # Load from file
    f = lg.Graph("data/graph.lign")
    
    # Check all data are the same
    print((f['x'] == g['x']).all())
    
  • Convert common data set to lign graphs

    import lign.utils as utl
    
    g0, g0_train, g0_validate = utl.load.mnist_to_lign("datasets/CIFAR100")
    
    g1, g1_train, g1_validate = utl.load.cifar_to_lign("datasets/CIFAR100")
    
    g2, g2_train, g2_validate = utl.load.cora_to_lign("datasets/CIFAR100")
    

Please refer to the documentation for other examples

Future

See the open issues for a list of proposed features (and known issues).

Citation

Refer to CITATION.bib for BibTex citation

Contributing

Read CONTRIBUTING.md for details on how to add to this repository.

tl;dr Fork, create a new branch, commits features and make a pull request with documented changes

License

Distributed under the Mozilla Public License Version 2.0. See LICENSE for more information.

Contact

@josuecom_

Metadata

Release files for lign 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lign 0.1.1
File Size Uploaded
lign-0.1.1.tar.gz 19.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lign 0.1.1
File Interpreter ABI Platform
lign-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 43.7 kB

Release files / lign-0.1.1.tar.gz

Download URL lign-0.1.1.tar.gz
Size 19.2 kB
Tags Source
SHA-256 checksum
How to use checksums
2db9c61fe8bb479bddca42227ab70d29dc02de254dbf5b2907e5496983d7aa57
BLAKE2b-256 checksum
How to use checksums
a0fbdd6695ac3e1eaeb90117b238d842089c32a54ba7d0c37e1f01a1ccc056cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.7.6

Release files / lign-0.1.1-py3-none-any.whl

Download URL lign-0.1.1-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c374b9bacbbcbed3e9e60a74d5c9abbfbf316e2b3f366f9278d430f679706284
BLAKE2b-256 checksum
How to use checksums
1eab4ec255e82cb62dfe8611301833ef28d5862e28f041e09b515731a7b4102f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/3.10.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.7.6

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page