27 个版本 (8 个重大更新)

0.9.9 2021 年 8 月 30 日
0.9.6 2021 年 7 月 31 日

#307机器学习

Download history 62/week @ 2024-02-21 15/week @ 2024-02-28 6/week @ 2024-03-06 42/week @ 2024-03-27 109/week @ 2024-04-03

每月 151 次下载

MIT 许可证

790KB
3K SLoC

柯基

一个为 Rust 实现的神经网络和动态张量自动微分。

Build: Github Workflow Download: crates.io Documentation: docs.rs Licence: MIT


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

  • 可以启用 openblasnetlib 功能。
  • 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