27 个版本 (8 个重大更新)
0.9.9 | 2021 年 8 月 30 日 |
---|---|
0.9.6 | 2021 年 7 月 31 日 |
#307 在 机器学习 中
每月 151 次下载
790KB
3K SLoC
柯基
一个为 Rust 实现的神经网络和动态张量自动微分。
for _ in 0..iterations {
// array operations are never in-place for corgi, so values never change
let input = Array::from((vec![batch_size, input_size], vec![...]));
let target = Array::from((vec![batch_size, output_size], vec![...]));
let _result = model.forward(input);
let loss = model.backward(target);
// update the parameters, and clear gradients (backward pass only sets gradients)
model.update();
println!("loss: {}", loss);
}
设计
- 数组操作永不原地,意味着数组值永远不会被修改。
- 急切执行。
- 尽可能动态的计算图。
for _ in 0..10 {
c = &c + &(&a * &b);
if c[0] > 50.0 {
c = &c * &a;
}
}
c.backward(None);
- 数组负责对它执行的运算进行反向传播的微分。
- 没有图结构以提高易用性 - 一个
Array
只包含其子节点。 - 数组(目前)不存储消费者。它们存储消费者计数。
BLAS
- 可以启用
openblas
或netlib
功能。 - Corgi 0.9.7 之前的版本没有优先考虑优化,因此会较慢。
跟踪数组
- 数组默认不跟踪,因此如果需要梯度,必须使用
tracked()
或start_tracking()
(请参阅文档以获取详细信息)。 - 跟踪数组是需要计算和存储梯度的数组。
- 有关详细信息,请参阅
tracked()
和untracked()
的文档,它们位于array.rs
中。
示例
- 全连接神经网络(完整版本)
let initializer = initializer::he();
let relu = activation::relu();
let softmax = activation::softmax();
let ce = cost::cross_entropy();
let gd = GradientDescent::new(learning_rate);
let l1 = Dense::new(input_size, hidden_size, &initializer, Some(&relu));
let l2 = Dense::new(hidden_size, output_size, &initializer, Some(&softmax));
let mut model = Model::new(vec![&mut l1, &mut l2], &gd, &ce);
for _ in 0..iterations {
let mut input = vec![0.0; input_size * batch_size];
let mut target = vec![0.0; output_size * batch_size];
// set inputs, and targets
// arrays in corgi should not be mutated after creation, so we initialise the values first
let input = Array::from((vec![batch_size, input_size], input));
let target = Array::from((vec![batch_size, output_size], target));
let _result = model.forward(input);
let loss = model.backward(target);
// update the parameters, and clear gradients (backward pass only sets gradients)
model.update();
println!("loss: {}", loss);
}
- 动态计算图
let a = arr![5.0].tracked();
let b = arr![2.0].tracked();
let mut c = arr![0.0].tracked();
for _ in 0..10 {
c = &c + &(&a * &b);
if c[0] > 50.0 {
c = &c * &a;
}
}
assert_eq!(c, arr![195300.0]);
c.backward(None);
assert_eq!(c.gradient(), arr![1.0]);
assert_eq!(b.gradient(), arr![97650.0]);
assert_eq!(a.gradient(), arr![232420.0]);
- 自定义操作(还需要做一些工作)。
资源
- 徽章来自 shields.io。
- OpenCourseWare 上的 MIT 6.034,介绍了反向传播的基础知识。
- CS231n YouTube 录像,介绍了卷积神经网络的基础知识。
许多库都是围绕尽可能动态构建的,这意味着如果选择得当,一些设计选择可能与其他动态计算图库相似。
使用了第三方库,可以在 Cargo.toml
中找到。
许可
- MIT
依赖项
~1–12MB
~148K SLoC