A gpu accelerated (optional) neural network Rust crate.

Overview

Intricate

Crates.io Crates.io github.com github.com github.com

A GPU accelerated library that creates/trains/runs neural networks in pure safe Rust code.

Architechture overview

Intricate has a layout very similar to popular libraries out there such as Keras.

Models

As said before, similar to Keras from Tensorflow, Intricate defines Models as basically a list of Layers and the definition for "layer" is as follows.

Layers

Every layer receives inputs and returns outputs, they must also implement a back_propagate method that will mutate the layer if needed and then return the derivatives of the loss function with respected to the inputs, written with I as the inputs of the layer, E as the loss and O as the outputs of the layer:

dE/dI <- Model <- dE/dO

These layers can be anything you want and just propagates the previous inputs to the next inputs for the next layer or for the outputs of the whole Model.

There are a few activations already implemented, but still many to be implemented.

XoR using Intricate

If you look at the examples/ in the repository you will find XoR implemented using Intricate. The following is basically just that example with some separate explanation.

Setting up the training data

let training_inputs = Vec::from([
    Vec::from([0.0, 0.0]),
    Vec::from([0.0, 1.0]),
    Vec::from([1.0, 0.0]),
    Vec::from([1.0, 1.0]),
]);

let expected_outputs = Vec::from([
    Vec::from([0.0]),
    Vec::from([1.0]),
    Vec::from([1.0]),
    Vec::from([0.0]),
]);

Setting up the layers

let mut layers: Vec<Box<dyn Layer<f64>>> = Vec::new();

//                      inputs_amount|outputs_amount
layers.push(Box::new(DenseF64::new(2, 3)));
layers.push(Box::new(TanHF64::new())); // activation functions are layers
layers.push(Box::new(DenseF64::new(3, 1)));
layers.push(Box::new(TanHF64::new()));

Creating the model with the layers

// Instantiate our model using the layers
let mut xor_model = ModelF64::new(layers);
// mutable because the 'fit' method lets the layers tweak themselves

Fitting our model

xor_model.fit(
    &training_inputs, 
    &expected_outputs, 
    TrainingOptionsF64 {
        learning_rate: 0.1,
        loss_algorithm: Box::new(MeanSquared), // The Mean Squared loss function
        should_print_information: true, // Should be verbose
        instantiate_gpu: false, // Should initialize WGPU Device and Queue for GPU layers
        epochs: 10000,
    },
).await;

As you can see it is extremely easy creating these models, and blazingly fast as well.

Although if you wish to do (just like in the actual XoR example) you could write this using the F32 version of numbers which is 30% faster overall and uses half the RAM but at the price of less precision.

How to save and load models

Intricate implements a few functions for each layer that saves and loads the necessary layer information to some file using the savefile crate.

But a layer can save and load the data anyway it sees fit, as long as it does what the trait Layer requires.

Saving the model

To load and save data, as an example, say for the XoR model we trained above, we can just call the save function as such:

xor_model.layers[0].save("xor-model-first-dense.bin", 0).unwrap();
xor_model.layers[2].save("xor-model-second-dense.bin", 0).unwrap();

And we save only the Dense layers here because the Activation layers don't really hold any valuable information, only the Dense layers do.

Loading the model

As for the loading of the data we must create some dummy dense layers and tell them to load their data from the paths created above

let mut first_dense: Box<DenseF32> = Box::new(DenseF32::dummy());
first_dense.load("xor-model-first-dense.bin", 0).unwrap();
let mut second_dense: Box<DenseF32> = Box::new(DenseF32::dummy()); 
second_dense.load("xor-model-second-dense.bin", 0).unwrap();

let mut new_layers: Vec<Box<dyn Layer<f32>>> = Vec::new();
new_layers.push(first_dense);
new_layers.push(Box::new(TanHF32::new()));
new_layers.push(second_dense);
new_layers.push(Box::new(TanHF32::new()));

let loaded_xor_model = ModelF32::new(new_layers);

Things to be done still

  • writing some kind of macro to generate the code for f32 and f64 versions of certain structs and traits to not have duplicated code.
  • improve the GPU shaders, perhaps finding a way to send the full unflattened matrices to the GPU instead of sending just a flattened array.
  • create GPU accelerated activations and loss functions as to make everything GPU accelerated.
  • perhaps write some shader to calculate the Model loss to output gradient (derivatives).
  • implement convolutional layers and perhaps even solve some image classification problems in a example
  • add a example that uses GPU acceleration
You might also like...
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

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

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

Build neural network models in Cairo 1.0

Explore ML in Cairo 1.0 Build neural network models in Cairo 1.0 to perform inference. The calculations are performed using i33 values, and the outcom

The CBNF neural network header format.

cbnf The CBNF neural network header format. What is CBNF? CBNF is a neural network header format for use with efficiently updatable neural networks fo

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

Rust implementation of real-coded GA for solving optimization problems and training of neural networks
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

Compile-time creation of neural networks with Rust

GAMMA 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 i

Comments
  • 0.6.0

    0.6.0

    • fix the categorical cross entropy to compute loss and derivatives as it is normally defined to compute
    • fix the sum buffer operation that had a problem when setting the local buffer
    • add the Mean Bias loss function
    • add the Mean Absolute loss function
    • improve Intricate's internal code overall to run better and sometimes faster
    • add the Nesterov Accelerated Gradient optimizer
    • add the Momentum-based optimizer
    • add the Adagrad optimizer
    opened by gabrielmfern 0
  • Feature/halting condition

    Feature/halting condition

    • add a way to print the accuracy and use them after training if calculated
    • add a halting condition in the TrainingOptions that lets you stop the training process before the amount of defined epochs is reached if the certain condition is met, such as a minimum loss or minimum acc.
    • add a verbosity option to print a warning that the training stopped because of the halting condition
    opened by gabrielmfern 0
  • v0.4.0

    v0.4.0

    • implement optimizers
    • improve the README a lot
    • implement different methods for layers to compute things instead of just doing it on the back_propagate method
    • improve verbosity much more even with a indicatif progress bar
    • improve Intricate error handling much more instead of panicking in most places
    • improve the way Intricate deals with OpenCL kernels and programs
    • make it so that all of the required Intricate OpenCL programs are compiled when the setup_opencl method is called
    • write documentation for Intricate everywhere as well
    opened by gabrielmfern 0
Releases(v0.7.0)
  • v0.7.0(Dec 21, 2022)

    This new release took some time but it also offers a junk load of new features and bug fixes.

    What's changed

    • Implement a way to get the MNIST dataset;
    • implement initiliazers and make it possible to choose each initializer for each Layer's parameter
    • Implement the ADAM optimizer which works wonders compared with other optimizers already implemented
    • Implement a builder pattern to set training options
    • Fix some problems with the Categorical Cross Entropy loss function and optimize it for softmax
    • Implement a Conv2D layer with some limitations and that still needs optimization
    • Implement a MNIST example in the examples/ folder of the repo
    • Made a logo for Intricate which is pretty cool

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.6.4...v0.7.0

    Source code(tar.gz)
    Source code(zip)
  • v0.6.4(Sep 5, 2022)

    Just some minor bug fixes.

    • Fix a problem with the epoch progress bar that was not properly printing the estimated time to finish
    • Remove a dbg! I left on the code

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.6.3...v0.6.4

    Source code(tar.gz)
    Source code(zip)
  • v0.6.3(Sep 5, 2022)

    Just removed the way to preprocess the training data that was added in the previous versions and keep a minor bugfix. The reason for removing it was because it just was plain bad and slow.

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.6.2...v0.6.3

    Source code(tar.gz)
    Source code(zip)
  • v0.6.2(Sep 5, 2022)

  • v0.6.1(Sep 4, 2022)

    What's Changed

    • make any input and output type possible to be given into the fit method of the Model
    • make it so that there is a parsing function that can be used for preprocessing the training inputs and outputs into matrices of floats as to make it possible for training models like bag of words on a very large training data by just passing into the fit method the texts and converting them through the function

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.6.0...v0.6.1

    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 2, 2022)

    What's Changed

    • 0.6.0 by @gabrielmfern in https://github.com/gabrielmfern/intricate/pull/5
    • fix the categorical cross entropy to compute loss and derivatives as it is normally defined to compute
    • fix the sum buffer operation that had a problem when setting the local buffer
    • add the Mean Bias loss function
    • add the Mean Absolute loss function
    • improve Intricate's internal code overall to run better and sometimes faster
    • add the Nesterov Accelerated Gradient optimizer
    • add the Momentum-based optimizer
    • add the Adagrad optimizer

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.5.0...v0.6.0

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Aug 26, 2022)

    What's Changed

    • Feature/halting condition by @gabrielmfern in https://github.com/gabrielmfern/intricate/pull/4
    • add a way to print the accuracy and use them after training if calculated
    • add a halting condition in the TrainingOptions that lets you stop the training process before the amount of defined epochs is reached if the certain condition is met, such as a minimum loss or minimum acc.
    • add a verbosity option to print a warning that the training stopped because of the halting condition

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/Rv0.4.0...v0.5.0

    Source code(tar.gz)
    Source code(zip)
  • Rv0.4.0(Aug 26, 2022)

    What's Changed

    • v0.4.0 by @gabrielmfern in https://github.com/gabrielmfern/intricate/pull/3
    • implement optimizers
    • improve the README a lot
    • implement different methods for layers to compute things instead of just doing it on the back_propagate method
    • improve verbosity much more even with a indicatif progress bar
    • improve Intricate error handling much more instead of panicking in most places
    • improve the way Intricate deals with OpenCL kernels and programs
    • make it so that all of the required Intricate OpenCL programs are compiled when the setup_opencl method is called
    • write documentation for Intricate everywhere as well

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.3.2...Rv0.4.0

    Source code(tar.gz)
    Source code(zip)
  • v0.3.2(Aug 20, 2022)

    What's Changed

    This new update there were mostly just internal things done, some bugs fixed and some new tests written.

    • Fix a bug with the Categorical Cross Entropy because it wasn't really being initialized correctly.
    • Make it so that the programs and kernels are all compiled when OpenCL is setup as to make things much easier to deal with.
    • Write some more docs because of the deny(missing_docs) complaining about missing docs.
    • Fix the deny missing docs in the lib.rs file that was only denying for the lib.rs file instead of for the whole project.
    • Can't remember much more of what I did... lol

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.3.1...v0.3.2

    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Aug 16, 2022)

    What's Changed

    • Remove f32/f64 different structs convention and just have f32.
    • Remove all Rayon computations using just Rust operations and start using OpenCL everywhere.
    • Solve several bugs in calculations.
    • Add many more unit tests.
    • Add documentation everywhere, and add a #[deny(missing_docs)] in the lib.rs file to force documentation everywhere.
    • Make all tests pass, even when running using the GPU and the CPU.
    • Create some utilities that help writing code on some places of the crate.
    • Create another crate called intricate-macros that has two macros for now to help creating things like activation layers without having to duplicate code.
    • Remove boxed dyn ...'s as to not have static references to everything and use Enum's instead, the new method in the layers create a instance of that enum by default making the creation of a list of layers and stuff like that much simpler.
    • Because of the removed Box's now Intricate can save models directly instead of having to save layer by layer which was really annoying me before.
    • Now I'm having even more fun than before! 😁👍

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.2.2...v0.3.1

    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Aug 2, 2022)

    • Solve a small miscalculation in the tanh activation function differential

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.2.1...v0.2.2

    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Jul 31, 2022)

    • Remove a small if statement that would panic for graphics cards of a certain type of vendor that I got from the wgpu compute example, not sure why it was there.

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.2.0...v0.2.1

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Jul 31, 2022)

    • Add the possibility to save and load layers
    • Update the README to explain somethings about the saving and loading as well as somethings about it behind the scenes
    • Make the 'get_last_inputs' and 'get_last_outputs' of the layers return references instead of copying things
    • Implement an approximate equal for matrices and vectors to use in tests like Softmax for it not to fail when it works

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.1.4...v0.2.0

    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Jul 30, 2022)

    • Make the workgroup sizes for all current shaders be (16, 16, 1) to work at its most.

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.1.3...v0.1.4

    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(Jul 30, 2022)

    • Make the ModelF64 instantiate the GPU device the same way ModelF32 does it.
    • Fix the Categorical Cross Entropy differential that was being calculated as the negative of what it should've been.
    • Fix a small problem in the XoR example that was using TrainingOptionsF64 instead of TrainingOptionsF32.

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.1.2...v0.1.3

    Source code(tar.gz)
    Source code(zip)
  • v0.1.2(Jul 30, 2022)

    • Add a Dense CPU layer that computes f32 numbers
    • Implement Matrix Operations for Vec<Vec>

    Full Changelog: https://github.com/gabrielmfern/intricate/compare/v0.1.1...Latest

    Source code(tar.gz)
    Source code(zip)
  • v0.1.1(Jul 30, 2022)

  • v0.1.0(Jul 30, 2022)

    Added GPU acceleration and F32 versions of things.

    Some cool things that still need to be done are:

    • writing some kind of macro to generate the code for f32 and f64 versions of certain structs and traits to not have duplicated code.
    • making so that the 'get' methods implemented return slices instead of copies of the vectors as to not duplicate things in RAM and save as much RAM as possible for very large models.
    • improve the GPU shaders, perhaps finding a way to send the full unflattened matrices to the GPU instead of sending just a flattened array.
    • create GPU accelerated activations and loss functions as to make everything GPU accelerated.
    • perhaps write some shader to calculate the Model loss to output gradient (derivatives).
    • implement convolutional layers and perhaps even solve some image classification problems in a example
    • add a example that uses GPU acceleration So still a lot of work to do.
    Source code(tar.gz)
    Source code(zip)
Owner
Gabriel Miranda
My name is Gabriel, I'm pretty much a front-end developer but I can actually pull off some very good back-ends. Sometimes I am working with Python as well.
Gabriel Miranda
Wonnx - a GPU-accelerated ONNX inference run-time written 100% in Rust, ready for the web

Wonnx is a GPU-accelerated ONNX inference run-time written 100% in Rust, ready for the web. Supported Platforms (enabled by wgpu) API Windows Linux &

WebONNX 354 Jan 6, 2023
A library implementing GPU-accelerated cryptographic functionality for the zkSync prover.

zkSync Era: A ZK Rollup For Scaling Ethereum zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on

Matter Labs 3 Sep 24, 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
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
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
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