Part 2 梯度与自动微分
约 636 字大约 2 分钟
2025-05-13
1 导数和偏导数
通过非常基础的高等数学知识我们知道,导数是一元函数y=f(x)中某个点处的瞬时变化率,即:
dxdy=h→0limhf(x+h)−f(x)
而偏导数将一元函数扩展到了多元函数,对于包含n个自变量的多元函数y=f(x1,x2,⋯,xn)而言,其关于第i个自变量的偏导数为:
∂xi∂y=h→0limhf(x1,x2,⋯,xi+h,⋯xn)−f(x1,x2,⋯,xi,⋯xn)
2 梯度
每次写y=f(x1,x2,⋯,xn)都显得太冗长了。我们将其改写为这样一个表达式:
y=f(x)
这里的函数f(x)接收的并非是一组数,而是一个列向量x=[x1,x2,⋯,xn]T
对于这样一个接收n维向量为自变量的函数,它的梯度是一个包含n个偏导数的向量。
∇xf(x)=[∂x1∂y,∂x2∂y,⋯,∂xn∂y]T
3 链式法则
在深度学习中,多元函数通常是复合的。
假设函数y=f(u1,u2,⋯,um)可微,其中任意中间变量ui都可被可微函数ui=g(x1,x2,⋯,xn)表示,则y对于任意xi的导数可由下列链式法则给出:
dxidy=∂u1∂y∂xi∂u1+∂u2∂y∂xi∂u2+⋯+∂um∂y∂xi∂um
4 自动微分
深度学习框架通过自动微分计算导数。
在实际过程中,根据设计好的模型,系统会构建一个计算图,来跟踪计算哪些数据通过哪种操作组合起来产生输出。自动微分系统能够跟踪整个计算图填充每个参数的偏导数,即反向传播。
我们先对一个简单的函数y=2xTx进行求导。
import torch
x = torch.arange(4., requires_grad=True) # `requires_grad=True`用于指定需要为该张量计算梯度。
print(x.grad) # None。这是一片单独的内存空间用于存储梯度。此时因为尚未计算梯度,所以为`None`。
y = 2 * torch.dot(x, x)
y.backward() # 反向传播,计算梯度。在反向传播的过程中,PyTorch会自动计算`y`对`x`的梯度,并将结果存储在`x.grad`中。
print(x.grad) # tensor([0., 2., 4., 6.])。计算完成。