解析梯度是什么?用求导公式精确算出的梯度
解析梯度(Analytic Gradient)是指通过数学推导,根据求导法则得到导数的公式,再直接代入数值计算出来的梯度。与之相对的是数值梯度,它是用很小的数值差分来近似估计的梯度。在机器学习中,模型的训练依赖于计算损失函数对参数的梯度,这两种计算方式各有用途。
两种计算梯度的方式
梯度描述的是函数在某一点上沿各个方向变化的快慢,告诉我们参数应该朝哪个方向调整,才能让损失下降得最快。
数值梯度:根据导数的定义来近似计算。对于某一个参数,把它增加一个很小的量,比如 0.00001,计算函数值的变化,再除以这个小量,就得到了这个方向上导数的近似值。更精确的做法是中心差分:分别把参数增加和减少一个很小的量,用两次函数值之差除以两倍的小量。这种方法非常简单,不需要任何数学推导,对任何函数都适用。但它有两个明显的缺点:一是只是近似值,存在误差,小量取得太大,近似不准确,取得太小,又会因为计算机的浮点数精度有限而产生很大的舍入误差;二是计算非常慢,每一个参数都要单独计算一到两次函数值,对于一个有一百万个参数的神经网络,计算一次梯度就要计算一两百万次损失函数,这是完全不现实的。
解析梯度:先用微积分的求导法则推导出梯度的数学公式,再直接计算。比如对于函数 x 的平方,导数就是 2x,在 x 等于 3 时,导数精确地等于 6。解析梯度的优点是精确、没有近似误差,而且计算速度快,一次计算就能得到所有参数的梯度。它的缺点是需要进行数学推导,对于复杂的函数,手工推导既繁琐又容易出错。
深度学习中的自动微分
神经网络是由大量简单的运算一层层组合起来的极其复杂的函数,手工推导它的梯度几乎是不可能的。现代的深度学习框架,比如 PyTorch、TensorFlow 和 JAX,都使用了自动微分技术来解决这个问题:框架会记录下模型计算过程中的每一步基本运算,比如加法、乘法、矩阵乘法、激活函数,每一种基本运算的导数都是已知的;然后利用链式法则,从输出开始反向地把这些导数组合起来,自动地算出损失对每一个参数的精确梯度。神经网络训练中的反向传播算法就是自动微分的一种形式。自动微分得到的是解析梯度,既精确又高效:计算全部参数梯度的代价,大约只相当于计算几次损失函数本身。这让开发者只需要定义模型的前向计算过程,就能自动获得梯度,大大降低了开发深度学习模型的难度。
梯度检验
数值梯度虽然不能用于实际的训练,但它在检查代码是否正确方面非常有用。当研究者自己实现一种新的网络层或者自定义的损失函数,手工编写了计算梯度的代码时,很可能写错。这时,可以在一些随机的参数上,分别计算解析梯度和数值梯度,比较两者是否足够接近,通常用它们的相对误差来衡量。如果相差很大,就说明解析梯度的代码很可能有错误。这个方法叫梯度检验,斯坦福大学的 CS231n 等经典课程中都专门介绍了它。