当我用 Rust 重新实现 Backprop 时,它终于变得通俗易懂。

发布: (2026年2月2日 GMT+8 14:15)
5 分钟阅读
原文: Dev.to

I’m happy to translate the article for you, but I need the full text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source line exactly as you provided and preserve all formatting, markdown, and code blocks.

Introduction

我从未使用过 PyTorch 或 TensorFlow。我的机器学习背景是 NumPy 和 scikit‑learn:我可以训练模型、调参并得到合理的结果,但在解释 为什么 有效时,我的理解很薄弱。反向传播尤其像个黑箱。我在高层面上知道步骤,却没有真正感受它们。

于是我完全停止使用机器学习库,直接用 Rust 从头重建了神经网络的核心。那时反向传播终于变得有意义。

为什么抽象会隐藏学习

问题不在于 NumPy 或 scikit‑learn——它们正如承诺的那样工作。问题在于它们把所有真正重要的理解内容抽象掉了。通过去除抽象(没有 autograd,只使用平坦缓冲区、显式索引和手写矩阵运算),谜团就消失了。

内存布局示例

let data = [1, 2, 3, 4, 5, 6];
let shape = (2, 3); // (rows, cols)

// Logical view
// [ 1  2  3 ]
// [ 4  5  6 ]

// Memory view (row‑major)
// [1][2][3][4][5][6]
//  0  1  2  3  4  5

在 Rust 中,你不能“随便”做转置——必须明确说明索引在内存中如何移动:

let index = row * cols + col;

这个限制改变了一切。你不能对梯度挥手致意;必须显式计算并存储它们。

Source:

反向传播的真实含义

当我必须自己实现反向传播时——不是符号化的,而是具体的记账方式——它不再神秘。整个过程归结为三个重复的动作:

  1. 应用链式法则
  2. 复用前向传播中的中间值
  3. 在矩阵运算中向后传递梯度

前向传播与后向传播

Forward pass:
X → [ Linear ] → [ Activation ] → ŷ → Loss

Backward pass:
∂Loss → [ dActivation ] → [ dLinear ] → ∂W, ∂X

手写这些时,几件事会变得非常清晰:

  • 梯度并不是“流动”——它们是 累加 的。
  • 形状对齐 才是真正的约束,而不是微积分。
  • 大多数 bug 源于对维度的错误假设,而不是数学本身。

简单的计算图

        ┌─── w1 ───┐
X ──► (+)         (+) ──► Loss
        └─── w2 ───┘

后向传播:

[ \frac{\partial \text{Loss}}{\partial X} = \frac{\partial \text{Loss}}{\partial \text{path}_1}

  • \frac{\partial \text{Loss}}{\partial \text{path}_2} ]

在我真正看到数值所在位置之前,反向传播感觉很难。

Rust在学习过程中的作用

Rust在这里并不是因为它快而重要;它之所以重要,是因为它毫不宽容。它迫使你面对:

  • 张量在内存中的布局
  • 数据是被复制还是被复用
  • 哪些操作会分配新缓冲区
  • 哪些梯度依赖于哪些前向值

我特意避免使用第三方 crate,只使用标准库。目标不是优雅或性能——而是透明性。如果某件事能工作,我想能够在索引和缓冲区层面解释为什么它能工作。

步骤实现

  1. 基于平面缓冲区的张量类型
  2. 元素级操作
  3. 转置、归约和矩阵乘法
  4. 线性回归
  5. 反向传播和梯度更新
  6. 端到端训练的一个小型神经网络

没有任何优化。一切都是显式的。这不是一个框架

谁应该尝试

  • 软件开发者 想要了解高层 API 之外的神经网络
  • 学习 Rust 的读者 想要一个具有挑战性的系统级项目

如果反向传播仍然让你觉得只能“接受”,而不是理解,那么重新实现一次是值得的。

进一步阅读

我将整个过程记录为章节式指南,从内存中的张量开始,一直讲到可运行的神经网络。您可以在此处阅读完整的演练:

https://ai.palashkantikundu.in

Back to Blog

相关文章

阅读更多 »