可微分编程是什么?让整个程序都能自动求导和优化
可微分编程(Differentiable Programming)是一种编程范式,在这种范式中,计算机程序可以通过自动微分进行完整的求导。这使得程序中的参数可以用基于梯度的方法来优化,通常是梯度下降。简单地说,就是写出的程序不只能计算出结果,还能自动算出“结果如何随着每个参数的变化而变化”,从而可以像训练神经网络一样去调整和优化整个程序。
先说自动微分
在机器学习中,训练模型的核心是计算梯度:损失函数对每一个参数的导数,告诉我们每个参数应该往哪个方向调整、调整多少,才能让损失下降。手工推导这些导数既繁琐又容易出错,尤其是对于有数百万个参数的复杂模型。自动微分技术能够自动、精确地计算出程序中任意计算结果对输入和参数的导数:它把程序分解成一系列基本的运算,比如加减乘除、指数、三角函数,每种基本运算的导数都是已知的,再按照链式法则把它们组合起来。神经网络训练中的反向传播,就是自动微分的一种形式。自动微分和数值近似求导不同,它能得到精确的结果;也和符号求导不同,它直接作用于程序的执行过程,效率很高。
从深度学习到可微分编程
深度学习本质上就是可微分编程最成功的例子:神经网络是一个由大量可微分运算组成的程序,通过自动微分计算梯度、用梯度下降来优化其中的参数。图灵奖得主杨立昆曾表示,“深度学习”这个说法可以被更广义的“可微分编程”所替代:重要的不是“神经网络”这个特定的结构,而是“用可微分的组件搭建程序,再通过梯度来优化它”这一思想。
可微分编程把这个思想扩展到了更广泛的程序中:不只是神经网络,各种包含循环、条件判断、递归等控制流的复杂程序,甚至传统的科学计算程序,都可以被变成可微分的,从而能够通过梯度来优化。
应用
可微分物理仿真:让物理模拟器变得可微分,就可以反过来求解问题,比如根据想要的结果,优化机器人的控制参数,或者根据观测数据反推物理模型的参数。可微分渲染:让把三维场景渲染成二维图像的过程可微分,就能根据照片反向优化三维模型的形状、材质和光照,神经辐射场等三维重建技术就依赖于此。科学计算和工程设计:在气候模型、分子模拟、流体力学、电路设计中,用梯度来优化参数或进行反演。将传统算法与神经网络结合:把一些经典的算法模块,比如排序、优化求解器,做成可微分的,嵌入神经网络中端到端地训练。
常用的可微分编程工具包括 PyTorch、TensorFlow,以及谷歌的 JAX,后者以函数式的设计和强大的自动微分、编译加速能力,在科学计算领域尤其受欢迎;Julia 语言也有丰富的可微分编程生态。