Expand description
§RustyML: Machine Learning and Deep Learning in Pure Rust
RustyML is a machine learning and deep learning library written entirely in Rust. It implements classical ML algorithms, neural networks, and data-processing utilities
§Overview
The crate covers a full workflow: preprocessing, feature engineering, model training, and evaluation. It validates input and reports errors
Estimator defaults, score orientations, and metric conventions follow scikit-learn and are checked numerically against it, so a ported pipeline produces the same numbers. Where the crate departs from scikit-learn, the item’s own documentation says so. Known departures:
metricspanics instead of returningResultroc_curvealways returns the full threshold sweepMeanShifthas an opt-in Gaussian kernel
§Architecture
The crate splits into 5 modules. A feature flag gates each one:
§machine_learning
Classical machine learning algorithms for supervised and unsupervised learning:
- Regression: Linear Regression with L1/L2 regularization, solved in closed form by default or by gradient descent
- Classification: Logistic Regression, KNN, Decision Tree, SVC, Linear SVC, LDA
- Clustering: KMeans, DBSCAN, MeanShift. All 3 label samples as
Array1<isize>, with-1for noise or unassigned points - Dimensionality Reduction: PCA, Kernel PCA, t-SNE
- Anomaly Detection: Isolation Forest, scoring in
[-1, 0)where lower is more anomalous and predicting-1(outlier) /+1(inlier)
§neural_network
Neural network framework built around a sequential model. Tensors are channels-last, and kernel shapes match Keras, so a layout carried over from Keras needs no permutation:
- Layers: Dense, SimpleRNN, LSTM, GRU, Convolution, Pooling, Dropout
- Optimizers: SGD, Adam, AdamW, RMSprop, AdaGrad
- Loss Functions: MSE, MAE, Binary/Categorical/Sparse Categorical Cross-Entropy
- Models: Sequential architecture for feed-forward networks.
fitandfit_with_batchesreturn aHistoryof one loss per epoch. A hand-written loop can call the publictrain_batchinstead, andevaluatescores the model without training it
§utils
Data preprocessing and dataset-splitting utilities:
- Preprocessing: one-shot
standardize/normalize, the stateful scaler family (StandardScaler,MinMaxScaler,MaxAbsScaler,RobustScaler,Normalizer) for reusing training statistics on later batches, and label encoding - Dataset Splitting: train/test split (optionally stratified)
§metrics
Evaluation metrics for model performance. Unlike the rest of the crate, these functions panic
on a precondition violation instead of returning a Result, which keeps this leaf module
dependency-light:
- Regression: MSE, RMSE, MAE, R^2 score
- Classification: Accuracy, Confusion Matrix, AUC-ROC, F1-score
- Clustering: Adjusted Rand Index, Normalized/Adjusted Mutual Information, Silhouette
Score. Every one of them takes
isizelabels, the type the clustering estimators return
§math
Low-level numeric primitives shared across modules:
- Distance Metrics: Euclidean, Manhattan, Minkowski, plus the
DistanceCalculationMetricdispatcher - Matrix Products:
gemmkit-backed GEMM/GEMV with automatic parallelism - Reductions: deterministic blocked parallel reductions
§Quick Start
§Machine Learning Example
Add RustyML to your Cargo.toml:
[dependencies]
rustyml = "*"
# The default feature set is `full`. To slim the build, set `default-features = false` and
# list the features you need, e.g. `features = ["machine_learning"]`
# Add `"show_progress"` to show progress bars during trainingIn your Rust code, write:
use rustyml::machine_learning::LinearRegression;
use rustyml::machine_learning::linear_model::LeastSquaresSolver;
use ndarray::{Array1, Array2};
// Create a linear regression model
let mut model = LinearRegression::new(true).with_solver(LeastSquaresSolver::GradientDescent { learning_rate: 0.01, max_iter: 1000, tol: 1e-6 }).unwrap();
// Prepare training data
let raw_x = vec![vec![1.0, 2.0], vec![2.0, 3.0], vec![3.0, 4.0]];
let raw_y = vec![6.0, 9.0, 12.0];
// Convert Vec to ndarray types
let x = Array2::from_shape_vec((3, 2), raw_x.into_iter().flatten().collect()).unwrap();
let y = Array1::from_vec(raw_y);
// Train the model
model.fit(&x.view(), &y.view()).unwrap();
// Make predictions
let new_data = Array2::from_shape_vec((1, 2), vec![4.0, 5.0]).unwrap();
let _predictions = model.predict(&new_data.view());
// Save the trained model to a file
model.save_to_path("linear_regression_model.bin").unwrap();
// Load the model from the file
let loaded_model = LinearRegression::load_from_path("linear_regression_model.bin").unwrap();
// Use the loaded model for predictions
let _loaded_predictions = loaded_model.predict(&new_data.view());
// Clone is implemented
let _model_copy = model.clone();
// Debug is implemented
println!("{:?}", model);§Neural Network Example
Add RustyML to your Cargo.toml:
[dependencies]
rustyml = "*"
# The default feature set is `full`. To slim the build, set `default-features = false` and
# list the features you need, e.g. `features = ["neural_network"]`
# Add `"show_progress"` to show progress bars during trainingIn your Rust code, write:
use rustyml::neural_network::{
sequential::Sequential,
layers::{Activation, Dense},
optimizers::Adam,
losses::CategoricalCrossEntropy,
};
use ndarray::Array;
// Create training data
let x = Array::ones((32, 784)).into_dyn(); // 32 samples, 784 features
let y = Array::ones((32, 10)).into_dyn(); // 32 samples, 10 classes
// Build a neural network
let mut model = Sequential::new();
model
.add(Dense::new(784, 128, Activation::ReLU).unwrap())
.add(Dense::new(128, 64, Activation::ReLU).unwrap())
.add(Dense::new(64, 10, Activation::Softmax).unwrap())
.compile(Adam::new(0.001, 0.9, 0.999, 1e-8, 0.0).unwrap(), CategoricalCrossEntropy::new(false));
// Display model structure
model.summary();
// Train the model
// The returned History holds one loss per epoch, measured during that epoch, not after it
let history = model.fit(&x, &y, 10).unwrap();
println!("Per-epoch loss: {:?}", history.loss());
// Score the model's current weights, an inference-mode pass that changes nothing
println!("Loss after training: {}", model.evaluate(&x, &y).unwrap());
// Save model weights to file
model.save_to_path("model.bin").unwrap();
// Create a new model with the same architecture
let mut new_model = Sequential::new();
new_model
.add(Dense::new(784, 128, Activation::ReLU).unwrap())
.add(Dense::new(128, 64, Activation::ReLU).unwrap())
.add(Dense::new(64, 10, Activation::Softmax).unwrap());
// Load weights from file
new_model.load_from_path("model.bin").unwrap();
// Compile before using (required for training, optional for prediction)
new_model.compile(Adam::new(0.001, 0.9, 0.999, 1e-8, 0.0).unwrap(), CategoricalCrossEntropy::new(false));
// Make predictions with loaded model
let predictions = new_model.predict(&x).unwrap();
println!("Predictions shape: {:?}", predictions.shape());§Feature Flags
The crate uses feature flags for modular compilation:
| Feature | Description |
|---|---|
machine_learning | Classical ML algorithms |
neural_network | Neural network framework |
utils | Data preprocessing and dataset splitting |
metrics | Evaluation metrics |
math | Numerical primitives (distances, matrix products, parallel reductions) |
full | Enables all of the above |
default | Enables full |
show_progress | Show progress bars when training |
machine_learning, neural_network, utils, and metrics each enable math.
The default enables everything. A scikit-learn workflow reaches across modules
(utils::train_test_split -> machine_learning -> metrics), so a fresh cargo add rustyml
should have all of it. Features are additive. Naming one does not turn the rest off, so to
restrict a build, set default-features = false and list what you need.
Re-exports§
pub use random::clear_global_seed;pub use random::set_global_seed;
Modules§
- error
- The crate’s unified error type (
error::Error) and its result alias (error::RustymlResult) Error types for RustyML - machine_
learning - Classical supervised and unsupervised estimators: regression, classification, clustering, dimensionality reduction, and anomaly detection Machine learning models for clustering, classification, regression, dimensionality reduction, and anomaly detection
- math
- Shared low-level numeric primitives: distance metrics,
gemmkit-backed matrix products, and deterministic parallel reductions Shared low-level numeric primitives used across estimators and metrics - metrics
- Model-evaluation metrics for regression, classification, and clustering Model-evaluation metrics for classification, clustering, and regression
- neural_
network - Neural-network framework: layers, optimizers, loss functions, and the sequential model Neural network primitives: layers, loss functions, optimizers, the sequential model, and the traits that tie them together
- prelude
- Single-import re-export of the crate’s most commonly used types, traits, and functions Prelude that re-exports the crate’s machine learning, metrics, neural network, and utility items
- random
- Crate-wide control of pseudo-random number generation for reproducibility Crate-wide control of pseudo-random number generation for reproducibility
- traits
- Every model and stateful transformer in the crate implements the shared estimator contract
(
Fit,Predict,Transform,FitTransform) Estimator traits shared by every model and stateful transformer in the crate - tuning
- Runtime overrides for the crate’s parallel and serial gate thresholds Runtime overrides for the crate’s parallel and serial gate thresholds
- utils
- Data preprocessing (normalize, standardize, the stateful scaler family, label encoding) and train/test dataset splitting Utilities for preprocessing and dataset splitting