Compile-time creation of neural networks with Rust

Overview

GAMMA

License

Compile-time creation of neural networks with Rust

Description

This is for now just a showcase project of what can be done with const generics introduced in Rust 1.51. There is not a single usage of vec in this project (as of today).

GAMMA allows the developer to build neural networks at compile-time, with preallocated arrays with well defined sizes. Aside from the performance improvement at runtime, another important benefit is that any possible mistake with the layout of the neural network, for example mismatching the inputs/outputs in the chain of layers, will be raised at compilation time.

This magic is accomplished thanks to two awesome Rust features:

  1. const generics: The layer weights are defined as multi-dimensional arrays with generic sizes. Before this feature was introduced the only option was to use vec or go crazy and define different layer types for each possible number of weights!
  2. derive macro: It is impossible to define an array or any other iterable of layers because it is an hetereogeneous set (different number of weights for each layer). To perform the forward pass you need to chain all the layers and propagate the input up to the lastest layer. The NeuralNetwork derive macro defines the forward method at compile-time, doing exactly that without any iteration.

Usage

Add this to your Cargo.toml:

[dependencies]
gamma = "0.1"
gamma_derive = "0.1"

And this is a very simple example to get you started:

use rand::distributions::Uniform;

use gamma::{activations::relu, layers::Dense, NeuralNetwork};
use gamma_derive::NeuralNetwork;

// Builds a neural network with 2 inputs and 1 output
// Made of 3 feed forward layers, you can have as many as you want and with any name
#[derive(NeuralNetwork, Debug)]
struct MyNetwork {
    input: Dense<2, 4>, // <# inputs, # outputs>
    hidden: Dense<4, 2>,
    output: Dense<2, 1>,
}

impl MyNetwork {
    // Initialize layer weights with a uniform distribution and set ReLU as activation function
    fn new() -> Self {
        let mut rng = rand::thread_rng();
        let dist = Uniform::from(-1.0..=1.0);

        MyNetwork {
            input: Dense::random(&mut rng, &dist, relu),
            hidden: Dense::random(&mut rng, &dist, relu),
            output: Dense::random(&mut rng, &dist, relu),
        }
    }
}

fn main() {
    // Init the weights and perform a forward pass
    let nn = MyNetwork::new();
    println!("{:#?}", nn);

    let input = [0.0, 1.0];
    println!("Input: {:#?}", input);
    let output = nn.forward(input);
    println!("Output: {:#?}", output);
}

You may wonder how the forward method works. The NeuralNetwork derive macro defines it for you, and it looks like this for this particular example:

fn forward(&self, input: [f32; 2]) -> [f32; 1] {
    self.output.forward(self.hidden.forward(self.input.forward[input]))
}

Note how the forward method expects two input values because that's what the first (input) layer expects, and returns one single value because that's what the last layer (output) returns.

Roadmap

  • Compile-time neural network consistency check
  • Docs, CI/CD & Benchmarks
  • Backward pass
  • More layer types (convolution, dropout, lstm...)
  • More activation functions (sigmoid, softmax...)
  • Maaaybeee, CPU and/or GPU concurrency

Contributing

If you find a vulnerability, bug or would like a new feature, open a new issue.

To introduce your changes into the codebase, submit a Pull Request.

Many thanks!

License

GAMMA is distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT, and COPYRIGHT for details.

Comments
  • RUSTSEC-2020-0071: Potential segfault in the time crate

    RUSTSEC-2020-0071: Potential segfault in the time crate

    Potential segfault in the time crate

    | Details | | | ------------------- | ---------------------------------------------- | | Package | time | | Version | 0.1.44 | | URL | https://github.com/time-rs/time/issues/293 | | Date | 2020-11-18 | | Patched versions | >=0.2.23 | | Unaffected versions | =0.2.0,=0.2.1,=0.2.2,=0.2.3,=0.2.4,=0.2.5,=0.2.6 |

    Impact

    Unix-like operating systems may segfault due to dereferencing a dangling pointer in specific circumstances. This requires an environment variable to be set in a different thread than the affected functions. This may occur without the user's knowledge, notably in a third-party library.

    The affected functions from time 0.2.7 through 0.2.22 are:

    • time::UtcOffset::local_offset_at
    • time::UtcOffset::try_local_offset_at
    • time::UtcOffset::current_local_offset
    • time::UtcOffset::try_current_local_offset
    • time::OffsetDateTime::now_local
    • time::OffsetDateTime::try_now_local

    The affected functions in time 0.1 (all versions) are:

    • at
    • at_utc
    • now

    Non-Unix targets (including Windows and wasm) are unaffected.

    Patches

    Pending a proper fix, the internal method that determines the local offset has been modified to always return None on the affected operating systems. This has the effect of returning an Err on the try_* methods and UTC on the non-try_* methods.

    Users and library authors with time in their dependency tree should perform cargo update, which will pull in the updated, unaffected code.

    Users of time 0.1 do not have a patch and should upgrade to an unaffected version: time 0.2.23 or greater or the 0.3 series.

    Workarounds

    No workarounds are known.

    References

    time-rs/time#293

    See advisory page for additional details.

    vulnerability 
    opened by github-actions[bot] 3
  • feat!: implement convolutional 2D layer

    feat!: implement convolutional 2D layer

    Convolutional layers with output dimensions inferred at compile time! This required a refactor of the project to be able to make it work, see: https://stackoverflow.com/questions/72742278/satisfying-a-trait-bound-with-a-const-generic-expression-is-it-possible

    Unfortunately this requires nightly until the const equality and expressions are stabilized.

    enhancement 
    opened by c0dearm 1
  • Create discussion forum / discord / matrix

    Create discussion forum / discord / matrix

    Hi! Would it be possible to create a forum to discuss about the API and the philosophy of this project? The idea of this project is really nice, but there may be people who want to contribute with code or with their opinions on the current state of the project and its future.

    This way it'll be much easier to discuss about what kind of API works best for the general consumers of the library.

    documentation 
    opened by znx3p0 1
  • change!: variable and constant tensors are now different types

    change!: variable and constant tensors are now different types

    Constant and variable tensors are now different types, which means, after getting lost on many computations the developer can know which of the resulting tensors are still constants or variables. Another benefit from this is that code is clearer now, as we don't need to assert at runtime if a tensor is a constant, for example when deciding if computing a gradient or not.

    Aside from this, I've also spent 10 minutes designing a logo for the library, given I have 0 skill for this I am quite happy with the result!

    opened by c0dearm 1
  • feat!: this is now an automatic differentiation library

    feat!: this is now an automatic differentiation library

    Building neural networks at compile time was a very fun idea, but in practice it lacked a lot of flexibility.

    For instance, you could only build sequential and static models, vs the directional acyclic and dynamic graphs that are required in most of the machine learning applications nowadays. Coding the derive macro to build the backward/reverse pass was also a feat not for the faint of heart, and I have a history!

    This new approach takes the library closer to what a sane person would do, i.e. something like Tensorflow or PyTorch, and it works wonderfully!

    opened by c0dearm 1
  • Implementing the softmax activation function

    Implementing the softmax activation function

    opened by Kerollmops 1
  • Implementing backpropagation

    Implementing backpropagation

    opened by Kerollmops 1
  • add CI github action and fix clippy warnings

    add CI github action and fix clippy warnings

    Hi @c0dearm I saw your post on reddit and thought It could be helpful to add a basic CI to your project :smile:

    Here's the action's run on my fork: https://github.com/yonip23/gamma/runs/2291263094?check_suite_focus=true

    opened by yonip23 0
  • Note for followers!

    Note for followers!

    Mushin is undergoing a major refactor, in order to provide a better API (experience) to users creating their own Deep Learning models. During the implementation of the MNIST digit recognition example I found some difficulties to ergonomically express the convolutional model. You might not see commits often until I iterate over a few different implementation possibilities. Until then, just letting you know I am working on it!

    Thank you all for your patience :heart:

    enhancement 
    opened by c0dearm 0
  • ML examples

    ML examples

    Hi there!

    This is a really cool library and I'm excited to try it out (especially after spending several hours fighting my environment to get tch-rs working >_> - still haven't, suspect it's easier to rewrite in mushin instead!)

    That being said, I'm still a bit of a novice at ML, and would appreciate some applied examples to see how you might port e.g. one of the PyTorch examples over. (I'm particularly interested in making a GAN or a VAE, but don't let that influence your choice!)

    No rush on this, but it'd be nice to have, especially for other people who'd like to better understand how to use the library 🙂

    (Unrelated: is there any kind of roadmap for what you're planning on implementing next / would like to see implemented?)

    question 
    opened by philpax 2
  • Making Arrayfire optional

    Making Arrayfire optional

    Do you think it would be possible to make arrayfire optional? The benefits of arrayfire are enormous, but it also seems like a huge handicap that anyone using the crate will be forced to download and install the arrayfire binaries. This also means that if I use mushin in my crate, my crate will also dependent on arrayfire, which is kind of a turn off.

    I guess making it optional would require making several versions of all operations and complicating the code with some abstraction over arrayfire/alternative, which would be a lot of work.

    enhancement 
    opened by albertsgarde 3
Releases(0.5.0)
  • 0.5.0(Jun 8, 2022)

    What's Changed

    • feat!: this is now an automatic differentiation library by @c0dearm in https://github.com/c0dearm/mushin/pull/4
    • change!: variable and constant tensors are now different types by @c0dearm in https://github.com/c0dearm/mushin/pull/6
    • feat: initial version of nn module by @c0dearm in https://github.com/c0dearm/mushin/pull/9

    Full Changelog: https://github.com/c0dearm/mushin/commits/0.5.0

    Source code(tar.gz)
    Source code(zip)
Owner
Aitor Ruano
Aitor Ruano
Neural networks in Rust

deeplearn-rs Deep learning in Rust! This is my first shot at this. It's mostly just a proof of concept right now. The API will change. Status We have

Theodore DeRego 199 Oct 23, 2022
Rust implementation of real-coded GA for solving optimization problems and training of neural networks

revonet Rust implementation of real-coded genetic algorithm for solving optimization problems and training of neural networks. The latter is also know

Yury Tsoy 19 Aug 11, 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
Neural Networks in Rust, without backpropagation. WIP

Deep Thought As of right now, this crate is far from a usable state. This crate implements feedforward-neural Networks in rust. Unlike the vast majori

null 5 Apr 10, 2022
Toy library for neural networks in Rust using Vulkan compute shaders

descent Toy library for neural networks in Rust using Vulkan compute shaders. Features Multi-dimensional arrays backed by Vulkan device memory Use Rus

Simon Brown 71 Dec 16, 2022
đź”­ interactively explore `onnx` networks in your CLI.

nnli Interactively explore onnx networks in your CLI. Get nnli ?? From Cargo cargo install nnli From Github git clone https://github.com/drbh/nnli.git

drbh 18 Nov 27, 2023
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
A neural network, and tensor dynamic automatic differentiation implementation for Rust.

Corgi A neural network, and tensor dynamic automatic differentiation implementation for Rust. BLAS The BLAS feature can be enabled, and requires CBLAS

Patrick Song 20 Nov 7, 2022
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

null 6 Jul 1, 2022
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

Alexandru Olaru 3 Dec 26, 2022
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

Gabriel Miranda 11 Dec 26, 2022
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

Mohammad Rahhal 6 Dec 29, 2022
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

Kurt Schelfthout 44 May 6, 2023
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

Masahiro Sakuta 6 Jun 12, 2023
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

Jack Montgomery 316 Dec 29, 2022
A simple neural net implementation.

PROPHET - Neural Network Library Linux Windows Codecov Coveralls Docs Crates.io A simple neural net implementation written in Rust with a focus on cac

Robin Freyler 41 Sep 16, 2022
SelfOrgMap 5 Nov 4, 2020
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