| Crates.io | neurons |
| lib.rs | neurons |
| version | 2.6.2 |
| created_at | 2024-05-18 20:25:35.457917+00 |
| updated_at | 2024-11-23 13:17:01.186952+00 |
| description | Neural networks from scratch, in Rust. |
| homepage | https://github.com/hallvardnmbu/neurons |
| repository | https://github.com/hallvardnmbu/neurons |
| max_upload_size | |
| id | 1244482 |
| size | 722,329 |
neurons is a neural network library written from scratch in Rust. It provides a flexible and efficient way to build, train, and evaluate neural networks. The library is designed to be modular, allowing for easy customization of network architectures, activation functions, objective functions, and optimization techniques.
Modular design
- Ready-to-use dense, convolutional and maxpool layers.
- Inferred input shapes when adding layers.
- Easily specify activation functions, biases, and dropout.
- Customizable objective functions and optimization techniques.
- Feedback loops and -blocks for more advanced architectures.
- Skip connections with simple accumulation specification.
- Much more!
Fast
- Leveraging Rust's performance and parallelization capabilities.
Everything built from scratch
- Only dependencies are
rayonandplotters.
Whereplottersonly is used through some of the examples (thus optional).Various examples showcasing the capabilities
- Located in the
examples/directory. With subdirectories for various tasks, showcasing the different architectures and techniques.
The package is divided into separate modules, each containing different parts of the library, everything being connected through the network.rs module.
tensor.rs
Describes the custom tensor struct and its operations.
A tensor is here divided into four main types:
Single: One-dimensional data (Vec<_>).Double: Two-dimensional data (Vec<Vec<_>>).Triple: Three-dimensional data (Vec<Vec<Vec<_>>>).Quadruple: Four-dimensional data (Vec<Vec<Vec<Vec<_>>>>).And further into two additional helper-types:
Quintuple: Five-dimensional data (Vec<Vec<Vec<Vec<Vec<(usize, usize)>>>>>). Used to hold maxpool indices.Nested: A nested tensor (Vec<Tensor>). Used through feedback blocks.Each shape following the same pattern of operations, but with increasing dimensions.
Thus, every tensor contains information about its shape and data.
The reason for wrapping the data in this way is to easily allow for dynamic shapes and types in the network.random.rs
Functionality for random number generation.
Used when initializing the weights of the network.network.rs
Describes the network struct and its operations.
The network contains a vector of layers, an optimizer, and an objective function.
The network is built layer by layer, and then trained using thelearnfunction.
See quickstart or theexamples/directory for more information.
dense.rs
Describes the dense layer and its operations.
convolution.rs
Describes the convolutional layer and its operations.
If the input is a tensor of shapeSingle, the layer will automatically reshape it into aTripletensor.deconvolution.rs
Describes the deconvolutional layer and its operations.
If the input is a tensor of shapeSingle, the layer will automatically reshape it into aTripletensor.maxpool.rs
Describes the maxpool layer and its operations.
If the input is a tensor of shapeSingle, the layer will automatically reshape it into aTripletensor.feedback.rs
Describe the feedback block and its operations.
activation.rs
Contains all the possible activation functions to be used.
objective.rs
Contains all the possible objective functions to be used.
optimizer.rs
Contains all the possible optimization techniques to be used.
plot.rs
Contains the plotting functionality for the examples.
use neurons::{activation, network, objective, optimizer, tensor};
fn main() {
// New feedforward network with input shape (1, 28, 28)
let mut network = network::Network::new(tensor::Shape::Triple(1, 28, 28));
// Convolution(filters, kernel, stride, padding, dilation, activation, Some(dropout))
network.convolution(5, (3, 3), (1, 1), (1, 1), (1, 1), activation::Activation::ReLU, None);
// Maxpool(kernel, stride)
network.maxpool((2, 2), (2, 2));
// Dense(outputs, activation, bias, Some(dropout))
network.dense(100, activation::Activation::ReLU, false, None);
// Dense(outputs, activation, bias, Some(dropout))
network.dense(10, activation::Activation::Softmax, false, None);
network.set_optimizer(optimizer::RMSprop::create(
0.001, // Learning rate
0.0, // Alpha
1e-8, // Epsilon
Some(0.01), // Decay
Some(0.01), // Momentum
true, // Centered
));
network.set_objective(
objective::Objective::MSE, // Objective function
Some((-1f32, 1f32)) // Gradient clipping
);
println!("{}", network); // Display the network
let (x, y) = { }; // Add your data here
let validation = (
x_val, // Validation data
y_val, // Validation labels
5 // Stop if val loss decreases for 5 epochs
);
let batch = 32; // Minibatch size
let epochs = 100; // Number of epochs
let print = Some(10); // Print every 10th epoch
let (train_loss, val_loss, val_acc) = network.learn(x, y, validation, batch, epochs, print);
}
Use fixed-size vectors where possible to increase performance.
Modify tensor operations to both utilise parallelisation and reduce redundant cloning.
Reduce general redundant cloning in the network etc.
Benchmarking benches/benchmark.rs (mnist version):
Note: v2.0.1 is massively outdated wrt. modularity etc., reflected through benchmarking.
Adam and AdamW optimizers.Added examples comparing the performance off different architectures.
Probes the final network by turning of skips and feedbacks, etc.
examples/compare/*Corresponding plotting functionality.
documentation/comparison.pyAdd dilation to the convolution layer.
Initial implementation of the deconvolution layer.
Created with the good help of the GitHub Copilot.
Validated against corresponding PyTorch implementation;
documentation/validation/deconvolution.pyMinor bug-fixes and example expansion.
Thorough expansion of the feedback module.
Feedback blocks automatically handle weight coupling and skip connections.
When defining a feedback block in the network's layers, the following syntax is used:
network.feedback(
vec![feedback::Layer::Convolution(
1,
activation::Activation::ReLU,
(3, 3),
(1, 1),
(1, 1),
None,
)],
2,
true,
feedback::Accumulation::Mean,
);
Add possibility of skip connections.
Limitations:
Add possibility of selecting the scaling function.
tensor::Scalefeedback::Accumulation
See implementations of the above for more information.Update maxpool logic to ensure consistency wrt. other layers.
Maxpool layers now return a tensor::Tensor (of shape tensor::Shape::Quintuple), instead of nested Vecs.
This will lead to consistency when implementing maxpool for feedback blocks.
Minor bug fixes to feedback connections.
Rename simple feedback connections to loopback connections for consistency.
Add skeleton for feedback block structure. Missing correct handling of backward pass.
How should the optimizer be handled (wrt. buffer, etc.)?
Before:
network.set_optimizer(
optimizer::Optimizer::AdamW(
optimizer::AdamW {
learning_rate: 0.001,
beta1: 0.9,
beta2: 0.999,
epsilon: 1e-8,
decay: 0.01,
// To be filled by the network:
momentum: vec![],
velocity: vec![],
}
)
);
Now:
network.set_optimizer(optimizer::RMSprop::create(
0.001, // Learning rate
0.0, // Alpha
1e-8, // Epsilon
Some(0.01), // Decay
Some(0.01), // Momentum
true, // Centered
));
Layers now automatically reshape input tensors to the correct shape. I.e., your network could be conv->dense->conv etc. Earlier versions only allowed conv/maxpool->dense connections.
Note: While this is now possible, some testing proved this to be suboptimal in terms of performance.
Combines operations to single-loop instead of repeadedly iterating over the tensor::Tensor's.
Benchmarking benches/benchmark.rs (mnist version):
Weight updates are now batched correctly.
See network::Network::learn for details.
Benchmarking examples/example_benchmark.rs (mnist version):
Optimizer step more intuitive and easy to read.
Using tensor::Tensor instead of manually handing vectors.
Network of convolutional and dense layers works.
Batched training (network::Network::learn).
Parallelization of batches (rayon).
Benchmarking examples/example_benchmark.rs (iris version):
Convolutional layer. Improved documentation.
Initial feedback connection implementation.
Improved documentation.
Custom tensor struct. Unit tests.
Dense feedforward network. Activation functions. Objective functions. Optimization techniques.
Network)NetworkTo profile, install flamegraph:
cargo install flamegraph
and include
[profile.release]
debug = true
in the Cargo.toml file.
Then run the following command:
sudo cargo flamegraph --example {{ EXAMPLE }} --release
with {{ EXAMPLE }} being the name of the example you want to profile (e.g., benchmark).