跳到主要内容
AI教程

手写连接:将 JavaScript 程序转换为可微分神经网络

本教程介绍 Handwired 如何将条件语句、循环和程序状态转换为矩阵乘法及类似 ReLU 的运算。你将使用 Bun 配置项目、探索演示示例、理解算术转换过程,并了解可微分程序的适用场景。

Handwired:将 JavaScript 程序转换为可微分神经网络

什么是 Handwired?

Handwired 可以将普通 JavaScript 代码转换为类似神经网络的计算过程,而无需训练。它不再将程序表示为常规控制流,而是把条件判断、循环和状态等逻辑转换为浮点值上的矩阵乘法与 reglu 操作。

生成的程序仍然完全可微分,但其中的权重是手动编写的,而不是通过学习得到的。Handwired 可以在 JavaScript 或 WebGPU 中执行这些计算。

HandwiredOS 演示

为什么要将程序转换为神经计算?

Handwired 将程序行为归约为一组小型数学原语,主要包括加法、乘法和 ReLU 风格的操作。这种方法带来了几个有趣的特性:

  • 整个程序仍然保持可微分。
  • 权重无需训练,因为它们是手动编写的。
  • 融合、稀疏化和操作重排等 GPU 优化可以应用于这种简化后的计算。
  • 传统 JavaScript 代码以这种形式表示时,有望实现 GPU 级别的并行性。

该项目还带来了实验上的可能性。你可以解冻手动定义的权重,研究训练会产生什么结果;也可以将一个冻结的程序连接到通用神经网络,并对组合系统进行端到端训练。

设置项目

Handwired 包含可实时运行的演示,以及用于在本地探索其实现的源代码。你需要在系统中安装 Bun。

  1. 克隆 Handwired 仓库。
  2. 进入项目目录。
  3. 使用 bun install 安装依赖。
  4. 使用 bun start 启动本地演示。
git clone <handwired-repository-url>
cd handwired
bun install
bun start

启动项目后,使用 Bun 输出的本地地址查看演示。你也可以访问托管演示:chenglou.me/handwired。

理解核心转换

考虑一个简单的 JavaScript 条件表达式:

const a = 5
const result = (a > 4) ? 10 : 12

Handwired 使用算术运算来表达这个条件。对于整数值,下面两个 ReLU 操作之差会生成一个选择器:当 a > 4 时值为 1,当 a <= 4 时值为 0:

const a = 5
const above4 = Math.max(0, a - 4) - Math.max(0, a - 5)
const result = above4 * 10 + (1 - above4) * 12

两个分支都会被计算,但 above4 会选择适当的结果。当 a = 5 时,选择器的值为 1,因此最终值为 10,与原始条件表达式一致。

数学表示的工作原理

核心思路是使用连续的算术原语替代分支。条件表达式会转换为以下操作的组合:

HandwiredOS

  • 使用 ReLU 操作根据输入构造选择器。
  • 使用乘法将选择器应用于每个分支。
  • 使用加法合并各分支的结果。

收集这些操作后,Handwired 就可以使用相关的激活操作,将计算表示为大型矩阵乘法。随后,同一个程序可以使用 JavaScript 或 WebGPU 进行求值。

两个分支都会计算,选择器决定哪个结果会对输出产生贡献。

探索仓库

研究项目时,可以从 README 中重点介绍的目录开始:

  • docs/ 包含用于理解项目的文档和资料。
  • src/ 包含项目实现。
  • template/ 提供了熟悉项目的起点。
  • lab/ 包含较早的实验内容,你可以选择探索或忽略。

一种实用的工作流程是先运行演示,然后将其行为与相关源文件进行对照。这有助于将可见示例与底层的矩阵运算转换联系起来。

尝试演示

托管演示是了解 Handwired 实际效果最快的方式。项目介绍特别突出了一个 JSON 搜索演示,它可以在几毫秒内处理 100,000 份文档。该演示展示了项目旨在为原本以传统单线程风格编写的代码带来大规模并行性的目标。

通过演示,你可以观察原始程序结构与生成的数学表示之间的区别。在修改本地源代码之前,演示也是一个很好的起点。

高级思路

尝试可训练权重

Handwired 通常使用手动编写的权重,因此无需训练即可使程序运行。项目提出的一项实验是解冻这些权重,观察优化过程会产生什么结果。

将冻结程序与神经网络结合

另一种可能性是将特定的冻结 Handwired 程序连接到通用神经网络,并对组合系统进行端到端训练。这样可以让模型在学习其他行为的同时,保留一个精确定义的程序。

从原语操作的角度思考

设计实验时,应关注如何使用加法、乘法和 ReLU 风格的操作表达控制流。生成的计算越简单,就越能直接受益于融合、稀疏化和重排等技术。

结语

Handwired 展示了如何将普通的 JavaScript 逻辑重写为可微分的数学计算。通过用算术选择器替代控制流,并将结果归约为矩阵乘法和激活运算,它使传统程序能够兼容神经网络技术以及 JavaScript 或 WebGPU 执行环境。使用 Bun 安装后,探索示例,然后查看 docs/、src/ 和 template/,开始进行实验。