An open API service indexing awesome lists of open source software.

https://github.com/raskr/rust-autograd

Tensors and differentiable operations (like TensorFlow) in Rust
https://github.com/raskr/rust-autograd

autograd automatic-differentiation deep-learning machine-learning neural-networks rust tensor

Last synced: 5 months ago
JSON representation

Tensors and differentiable operations (like TensorFlow) in Rust

Awesome Lists containing this project

README

          

# autograd

[![build](https://github.com/raskr/rust-autograd/actions/workflows/rust.yml/badge.svg)](https://github.com/raskr/rust-autograd/actions/workflows/rust.yml)
[![Crates.io version](https://img.shields.io/crates/v/autograd.svg)](https://crates.io/crates/autograd)
[![docs.rs](https://docs.rs/autograd/badge.svg)](https://docs.rs/autograd/)

Tensors and differentiable operations backed by [ndarray](https://github.com/rust-ndarray/ndarray).

## Cargo.toml
If you use basic linalg operations, especially matrix multiplications, `blas` feature would be important to speed them up.
``` toml
[dependencies]
autograd = {"", features = ["blas", ""] }
```

`` must be one of the following (See also [blas-src](https://github.com/blas-lapack-rs/blas-src))
- `accelerate` macOS only
- `intel-mkl` Intel/AMD CPU only. Includes Vector Mathematics (VM) ops
- `openblas`

## Features
### Reverse-mode automatic differentiation
Here we are just computing partial derivatives of `z = 2x^2 + 3y + 1`.
```rust
use autograd as ag;
use ag::tensor_ops::*;

ag::run(|ctx: &mut ag::Context<_>| {
let x = ctx.placeholder("x", &[]);
let y = ctx.placeholder("y", &[]);
let z = 2.*x*x + 3.*y + 1.;

// dz/dy
let gy = &grad(&[z], &[y])[0];
println!("{:?}", gy.eval(ctx)); // => Ok(3.)

// dz/dx (requires to fill the placeholder `x`)
let gx = &grad(&[z], &[x])[0];
let feed = ag::ndarray::arr0(2.);
println!("{:?}", ctx.evaluator().push(gx).feed(x, feed.view()).run()[0]); // => Ok(8.)

// ddz/dx (differentiates `z` again)
let ggx = &grad(&[gx], &[x])[0];
println!("{:?}", ggx.eval(ctx)); // => Ok(4.)
});
```

### Neural networks
This crate has various low-level features inspired by tensorflow/theano to train neural networks.
Since computation graphs require only bare minimum of heap allocations, the overhead is small, even for complex networks.
```rust
// MNIST digits classification with multi-layer-perceptron
use autograd as ag;
use ag::optimizers::adam::Adam;
use ag::tensor_ops::*;
use ag::prelude::*;

let mut env = ag::VariableEnvironment::new();

let rng = ag::ndarray_ext::ArrayRng::::default();

// Register variables in this env.
env.name("w").set(rng.glorot_uniform(&[28 * 28, 10]));
env.name("b").set(ag::ndarray_ext::zeros(&[1, 10]));

let adam = Adam::default("my_adam", env.default_namespace().current_var_ids(), &mut env);

for epoch in 0..3 { // 0.11 sec/epoch on 2.7GHz Intel Core i5
env.run(|ctx| {
let x = ctx.placeholder("x", &[-1, 28*28]);
let y = ctx.placeholder("y", &[-1]);
let w = ctx.variable("w");
let b = ctx.variable("b");
let z = matmul(x, w) + b;
let mean_loss = reduce_mean(sparse_softmax_cross_entropy(z, &y), &[0], false);
let grads = &grad(&[mean_loss], &[w, b]);

// let mut feeder = ag::Feeder::new();
// feeder.push(x, x_batch).push(y, y_batch);
// adam.update(&[w, b], grads, ctx, feeder);
});
}
```

### Abstractions
```rust
use autograd as ag;
use ag::tensor_ops::*;
use ag::ndarray;

// `Tensor::map()`
ag::run(|ctx| {
let x = ones(&[2, 3], ctx);
// apply ndarray's methods
let y = x.map(|x| x.fold_axis(ndarray::Axis(0), 0.0, |acc, x| acc + x));
let z = x.map(|x| ag::ndarray_ext::zeros(x.shape()));
});

// Hooks
ag::run(|ctx| {
let x: ag::Tensor = ones(&[2, 3], ctx).show_shape();
let y: ag::Tensor = ones(&[2, 3], ctx).raw_hook(|x| println!("{}", x));
});
```

For detailed, see [documentation](https://docs.rs/autograd/) or
[examples](https://github.com/raskr/rust-autograd/tree/master/examples)