A neural network, and tensor dynamic automatic differentiation implementation for Rust.

Overview

Corgi

A neural network, and tensor dynamic automatic differentiation implementation for Rust.

Build: Github Workflow Download: crates.io Documentation: docs.rs Licence: MIT


BLAS

  • The BLAS feature can be enabled, and requires CBLAS if used.

Important Design Notes

  • Array values should never be modified from operations; instead, new arrays should be created.
  • Arrays are untracked by default, so if gradients are required, tracked(), or start_tracking() must be used (see the documentation for details).
  • Versions 0.y.z of Corgi are considered unstable, so check the releases page on Github for new versions.

Examples

  • For fully-connected examples, remember to call model.update().
  • Fully-connected MNIST (convolutional neural networks are in-progress).
  • Fully-connected neural network (full version):
let initializer = initializer::make_he();
let relu = activation::make_relu();
let softmax = activation::make_softmax();
let ce = cost::make_cross_entropy();
let gd = GradientDescent::new(learning_rate);
let l1 = Dense::new(input_size, hidden_size, initializer.clone(), Some(relu));
let l2 = Dense::new(hidden_size, output_size, initializer.clone(), Some(softmax));
let mut model = Model::new(vec![Box::new(l1), Box::new(l2)], Box::new(gd), ce);

for _ in 0..iterations {
    let mut input = vec![0.0; input_size * batch_size];
    let mut target = vec![0.0; output_size * batch_size];

    // set inputs, and targets

    // arrays in corgi should not be mutated after creation, so we initialise the values first
    let input = Array::from((vec![batch_size, input_size], input));
    let target = Array::from((vec![batch_size, output_size], target));

    let _result = model.forward(input.clone());
    let loss = model.backward(target.clone());
    // update the parameters, and clear gradients (backward pass only sets gradients)
    model.update();

    println!("loss: {}", loss);
}
  • Dynamic computational graph:
let a = arr![5.0].tracked();
let b = arr![2.0].tracked();
let mut c = arr![0.0].tracked();

for _ in 0..10 {
    c = &c + &(&a * &b);
    if c[0] > 50.0 {
        c = &c * &a;
    }
}

assert_eq!(c, arr![195300.0]);

c.backward(None);
assert_eq!(c.gradient(), arr![1.0]);
assert_eq!(b.gradient(), arr![97650.0]);
assert_eq!(a.gradient(), arr![232420.0]);

Design

  • Originally worked around the ergonomics of the arr! macro (which however, currently still needs more work).
  • Dynamic-as-possible computational graph.
  • Did not want to have to manage any 'graph' structures when using Corgi (the Arrays should represent the graph alone).
  • Graph became more, and more dependent on threading for the backward pass, and the use of Arc, and Mutex.
  • Graphs do note store consumers (at the moment). They store consumer counts instead.

Tracked Arrays

  • Tracked arrays are arrays which require gradients to be computed, and stored.
  • For more information, see the documentation for tracked(), and untracked() in array.rs.

Backward Pass

  • An informal UML sequence diagram (it's not entirely up to specs, but should give an overview of the process):

Informal UML sequence diagram

Name

  • Original name was going to be 'cog-(something)', since Rust's logo is a cog, and since cognition (get it?). But as it turns out, many AI libraries are named 'cog-(something)'. Attempts at permutations of 'cog' with other words sounded awkward, such as 'cogi', for 'cog-intelligence', so the name Corgi was chosen.

Acknowledgements

Licence

  • MIT
You might also like...
Simple Neural Network on rust

Simple Artificial Neural Network A crate that implements simple usage of dense neural networks. Instalation Add this to your dependencies on Cargo.tom

Machine learning Neural Network in Rust

vinyana vinyana - stands for mind in pali language. Goal To implement a simple Neural Network Library in order to understand the maths behind it. This

A gpu accelerated (optional) neural network Rust crate.

Intricate A GPU accelerated library that creates/trains/runs neural networks in pure safe Rust code. Architechture overview Intricate has a layout ver

Neural network implementations from scratch in Rust.

Neural Network from Scratch Neural network implementations from scratch in Rust. Setup & Run Dataset used is mnist. Download the 4 archives and extrac

A fun, hackable, GPU-accelerated, neural network library in Rust, written by an idiot

Tensorken: A Fun, Hackable, GPU-Accelerated, Neural Network library in Rust, Written by an Idiot (work in progress) Understanding deep learning from t

An experimental Neural Network trainer/visualizer in Rust
An experimental Neural Network trainer/visualizer in Rust

DeepRender An experimental Neural Network trainer/visualizer in Rust Try it on your browser! https://msakuta.github.io/DeepRender/ Training on a funct

A neural network crate

RustNN An easy to use neural network library written in Rust. Crate Documentation Description RustNN is a feedforward neural network library. The libr

A neural network model that can approximate any non-linear function by using the random search algorithm for the optimization of the loss function.

random_search A neural network model that can approximate any non-linear function by using the random search algorithm for the optimization of the los

Comments
  • Broadcasting with single dimension is currently not implemented

    Broadcasting with single dimension is currently not implemented

    Describe the bug Broadcasting, such as in matrix multiplying a tensor with dimensions [2], with one with dimensions [2, 2] will not backpropagate as expected.

    • This impacts Dense layers if inputs are not given with the expected dimensions.

    To Reproduce

    let w = arr![arr![1.0, 2.0], arr![8.0, 2.0]].tracked();
    let x = arr![5.0, 3.0];
    
    let mut result = Array::matmul((&x, false), (&w, true));
    result.backward(None);
    assert_eq!(w.gradient().unwrap(), arr![arr![5.0, 3.0], arr![5.0, 3.0]]);
    

    Will fail, and the gradient for w will be [[5.0, 0.0], [5.0, 0.0]].

    This also means when inputting a tensor x = arr![x_1, ..., x_n] to a Dense layer with n inputs, the gradient will be incorrect.

    • Workaround: input tensors with the proper dimensions, that is x = arr![[x_1, ..., x_n]] instead.
    • This affects training, but only on first-layer weights for models with inputs which need to be broadcasted.
    • This does not affect models which are trained using batch gradient descent, since such models have the proper dimensions specified.

    Additional context Tests have been added, and regressions will be easier to detect, given the addition of numerical gradient checking as well.

    bug 
    opened by patricksongzy 0
Releases(v0.9.9)
  • v0.9.9(Aug 30, 2021)

  • v0.9.8(Aug 9, 2021)

  • v0.9.7(Aug 6, 2021)

    https://crates.io/crates/corgi

    • Further optimise library, which is now considered in a mostly optimised state, and much quicker than before
    Source code(tar.gz)
    Source code(zip)
  • v0.9.6(Jul 31, 2021)

  • v0.9.5(Jul 24, 2021)

    https://crates.io/crates/corgi

    • Remove threading
    • Change BLAS to use crate, instead of writing bindings
      • Now use the features openblas, or netlib, instead of blas
    Source code(tar.gz)
    Source code(zip)
  • v0.9.3(Jul 24, 2021)

  • v0.9.2(Jul 4, 2021)

  • v0.9.1(May 16, 2021)

  • v0.9.0(May 9, 2021)

    https://crates.io/crates/corgi

    • Backward operations now take in an extra parameter to specify which children gradients should be tracked.
    • It is now suggested that taking into account tracking be done in the backward op itself, as opposed to specifying different backward operations. This should cut down in code repetitiveness.
    • See the array module, such as arithmetic for example operation implementations.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.8(May 2, 2021)

  • v0.8.7(May 2, 2021)

    https://crates.io/crates/corgi

    • Take mean for batched cross entropy loss, rather than just the sum.
    • Refactor array module internals.
    • Arrays::new is now deprecated in favour for Array::from.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.5(Apr 27, 2021)

    https://crates.io/crates/corgi

    • Optimise flatten_to, resulting in massive performance improvements.
    • Deprecate Arrays::new in favour for Array::from.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.4(Apr 19, 2021)

  • v0.8.3(Apr 16, 2021)

  • v0.8.2(Apr 16, 2021)

  • v0.8.1(Apr 15, 2021)

    https://crates.io/crates/corgi

    • Add full broadcasting for single-dimension arrays.
    • Note that Corgi treats matrix multiplication transposes of single-dimension arrays as if there were a leading 1 in the dimension, meaning the array will be converted to a column vector.
    • Add gradient checking.
    • Make sure to call model.update() to update the parameters of the model.
    Source code(tar.gz)
    Source code(zip)
  • v0.8.0(Apr 15, 2021)

    https://crates.io/crates/corgi

    • Implement softmax, and cross-entropy loss (and respective required functions, such as exp, ln, element-wise division, and reciprocals).
    • Activations, initializers, and costs have now moved to nn_functions.
    Source code(tar.gz)
    Source code(zip)
  • v0.7.3(Apr 14, 2021)

    https://crates.io/crates/corgi

    • Fix problem where consumer counts would be double-counted
    • Implement Softmax, exponentiation, and division operators
    Source code(tar.gz)
    Source code(zip)
  • v0.7.2(Apr 14, 2021)

    https://crates.io/crates/corgi

    • Fix issue where multiple graphs would not be differentiable, because root nodes would remain in memory (not be dropped).
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Apr 13, 2021)

    https://crates.io/crates/corgi

    • Implement basic broadcasting (may not work as expected for single dimension matrix multiplications)
    • Implement batch gradient descent
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Apr 13, 2021)

    https://crates.io/crates/corgi

    • Make arrays untracked by default.
    • Changed usage of tracked(), to follow a more builder-like pattern.
    • Arrays can now be made like: let a = arr![1.0, 2.0, 3.0].tracked();
    • For previous tracked(), and untracked() functionality, start_tracking(), and stop_tracking() are used.
    • See documentation for tracked, and untracked arrays.
    Source code(tar.gz)
    Source code(zip)
  • v0.5.2(Apr 10, 2021)

    https://crates.io/crates/corgi

    • Fix critical performance issue with propagating consumers during backward pass
    • Previous releases have been yanked due to this performance issue
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Apr 9, 2021)

  • v0.4.0(Apr 9, 2021)

  • v0.3.0(Apr 7, 2021)

Owner
Patrick Song
Patrick Song
Generic Automatic Differentiation library for Rust (aka "autograd")

GAD: Generic Automatic Differentiation for Rust This project aims to provide a general and extensible framework for tape-based automatic differentiati

Facebook Research 24 Dec 20, 2022
Automatic differentiation in pure Rust.

Niura is an automatic differentiation library written in Rust. Add niura to your project [dependencies] niura = { git = "https://github.com/taminki/n

null 10 Jun 16, 2022
High-performance automatic differentiation of LLVM.

The Enzyme High-Performance Automatic Differentiator of LLVM Enzyme is a plugin that performs automatic differentiation (AD) of statically analyzable

William Moses 870 Jan 2, 2023
l2 is a fast, Pytorch-style Tensor+Autograd library written in Rust

l2 • ?? A Pytorch-style Tensor+Autograd library written in Rust Installation • Contributing • Authors • License • Acknowledgements Made by Bilal Khan

Bilal Khan 163 Dec 25, 2022
Tensors and dynamic neural networks in pure Rust.

Neuronika is a machine learning framework written in pure Rust, built with a focus on ease of use, fast prototyping and performance. Dynamic neural ne

Neuronika 851 Jan 3, 2023
n2 is a library implementation of a feedforward, backpropagation artificial neural network.

n2 is a library implementation of a feedforward, backpropagation artificial neural network. Usage Add the following to the [dependencies] section o

Søren Mortensen 0 Feb 21, 2021
Rust Auto-Differentiation.

RustAD - Rust Auto-Differentiation A super restrictive rough WIP beginnings of a library attempting to implement auto-differentiation in Rust. forward

Jonathan Woollett-Light 10 Dec 9, 2022
A light wheight Neural Network library with a focus on ease of use and speed.

Smarty Pants This goal of this library is to: Produce NeuralNetworks that will always give the same result when given the same input. Provide methods

Coding Wizard 3 Mar 7, 2022
Simple neural network library for classification written in Rust.

Cogent A note I continue working on GPU stuff, I've made some interesting things there, but ultimately it made me realise this is far too monumental a

Jonathan Woollett-Light 41 Dec 25, 2022
Rust wrapper for the Fast Artificial Neural Network library

fann-rs Rust wrapper for the Fast Artificial Neural Network (FANN) library. This crate provides a safe interface to FANN on top of the low-level bindi

Andreas Fackler 12 Jul 17, 2022