【RustyML入门】1.1. 认识RustyML
1.1. 认识RustyMLRustyML 是一个完全用 Rust 编写的机器学习与深度学习库。它覆盖数据科学项目所需的完整流程数据预处理、特征工程、模型训练与评估。RustyML提供经典机器学习的估计器线性模型、决策树、SVM、聚类、降维、异常检测也提供Keras风格的神经网络框架。本指南对应的版本是0.14。API正在趋于稳定但次要版本仍可能引入破坏性更改。所以在生产环境里请在Cargo.toml中锁定具体版本别用*。权威的API参考在docs.rs/rustyml源码在github.com/SomeB1oody/RustyML。1.1.1. 纯 Rust端到端RustyML特性是没有任何C/C代码(不链接BLAS没有LAPACK没有CUDA)。这使得其可移植性强不需要用户手动配置复杂的环境并且不容易在编译阶段出现莫名其妙的错误非常适合生产环境和新手入门。大部分代码都是用Safe Rust写成其内存安全性因此得以保证。为了保证性能矩阵乘法使用纯Rust的gemmkitcrate经由零拷贝的gemmkit-ndarray适配器接入ndarray。它在运行时分派到当前CPU真正支持的最宽SIMD指令集AVX-512F、AVX2FMA、NEON、wasmsimd128并有标量兜底还会自行判断一次乘法值不值得开线程、开几个使得在不同硬件上都能获得极好的性能。1.1.2. 并行RustyML用Rayon并行化它的计算密集内核但不会盲目地并行化。尺寸低于某个界限时多线程的额外开销会让并行比串行还慢所以RustyML每一类内核都有一个校准过的尺寸阈值只有当并行速度实测超过串行时才切换到并行路径。这些阈值并非写死的常量可以通过rusyml::tuning在运行时覆盖这些开关而无需重新编译。当你把同一个二进制部署到核心数差异很大的机器上时这一点尤其关键。详细内容见性能调优与并行。RustyML的设计优点并行归约是确定性的分块折叠无论用多少线程都按固定顺序求和所以结果不会随核心数增加而漂移。性能可预测没有垃圾回收带来的卡顿没有JIT预热也没有全局解释器锁把线程串行化。几乎每个随机化组件都遵循一个全局种子见可复现性与随机种子一次运行在不同机器上都有可复现性。降维器里的迭代特征求解器是有意排除在外的因为无论种子取什么它们都收敛到同一个结果。1.1.3. Feature和模块RustyML划分五个模块每个都由一个Cargo feature控制prelude是共享的。你可以通过指定feature来只编译用得上的部分。machine_learning、neural_network、utils和metrics都会自动启用math。Feature / 模块包含内容machine_learning经典机器学习的估计器neural_networkSequential模型以及各种层Dense、卷积、池化、循环、dropout、归一化、激活函数、优化器SGD、Adam、AdamW、RMSprop、AdaGrad和损失函数utils预处理StandardScaler等缩放器、to_categorical等标签转化功能与数据集划分train_test_split、train_test_split_stratifiedmetrics面向回归、分类ConfusionMatrix、ROC AUC、log loss…和聚类ARI、silhouette…的评估指标math数学计算、gemmkit支持的矩阵乘积defaultfeature启用打开全部功能。另有一个独立的show_progressfeature用来显示训练进度条详见安装与 Feature 配置。1.1.4. 仿scikit-learn和Keras的API设计经典估计器仿照scikit-learn提供fit和predict等方法神经网络仿照Keras的Sequential模型以及其add/compile/fit/predict方法对于熟悉Python上数据科学生态环境的人来说更好入门。变的地方在于数据是使用ndarray数组而非NumPy (详见使用 ndarray 准备数据)可能失败的调用返回Result而不是抛异常。以下是一个经典机器学习的代码例你可以看出其API设计和scikit-learn类似userustyml::prelude::machine_learning::*;usendarray::array;fnmain(){// new(fit_intercept)默认求解器是精确的闭式解letmutmodelLinearRegression::new(true);letxarray![[1.0,2.0],[2.0,3.0],[3.0,4.0]];letyarray![6.0,9.0,12.0];model.fit(x,y).unwrap();letpredictionsmodel.predict(x).unwrap();println!(predictions: {:?},predictions);}接着是神经网络代码里你可以看出其架构设计和Keras类似userustyml::prelude::neural_network::*;usendarray::Array;fnmain(){// 4 个样本8 个输入特征1 个输出letxArray::ones((4,8)).into_dyn();letyArray::ones((4,1)).into_dyn();letmutmodelSequential::new();model.add(Dense::new(8,16,Activation::ReLU).unwrap()).add(Dense::new(16,1,Activation::Linear).unwrap()).compile(Adam::new(0.001,0.9,0.999,1e-8,0.0).unwrap(),MeanSquaredError::new(),);model.summary();// 打印网络结构就像 Keras 一样model.fit(x,y,5).unwrap();letpredictionsmodel.predict(x).unwrap();println!(prediction shape: {:?},predictions.shape());}指标计算和scikit-learn也保持相似设计每个指标都按(y_true, y_pred)这个顺序接收参数userustyml::metrics::*;usendarray::array;fnmain(){lety_truearray![1.0,0.0,0.0,1.0,1.0];lety_predarray![1.0,0.0,1.0,1.0,0.0];letcmConfusionMatrix::new(y_true,y_pred);println!(accuracy: {:.3},cm.accuracy());println!(f1 score: {:.3},cm.f1_score());}与Python不同RustyML的错误传播设计会把一个可能失败的调用的结果用ResultT, Error包裹你可以使用match来对不同的可能返回值要么是执行成功返回T要么是执行失败返回Error进行不同的处理详见错误处理。超参数在被传入的那一处就完成校验非法的数值会当场被拒。配置采用builder模式估计器的核心超参数在new里指明再通过链式的with_*方法叠加可选设置每一步各自校验自己收到的东西例如LinearRegression::new(true).with_regularization(..)?。1.1.5. 纯Rust的优势一个RustyML程序编译成单个自包含的二进制。不用装其他工具链和配置复杂的环境。训练好的经典模型和神经网络权重通过save_to_path/load_from_path序列化为二进制详见深入模型持久化。因为没有GC、没有解释器并且没有预热延迟是可预测的。1.1.6. 关于适用范围RustyML只跑在CPU上。它没有GPU或CUDA后端。这套神经网络框架适合中小规模模型以及贴近经典机器学习的深度学习不适合训练大型视觉或语言模型。经典的machine_learning和utils估计器都接收元素为f64的特征矩阵但predict吐回来的元素类型随模型而变详见使用 ndarray 准备数据里的表格。神经网络栈工作在f32上它的张量类型是Tensor ArrayDf32。这套神经网络框架不像PyTorch那样构建动态自动微分图。