PyTorch在不可微点的求导行为探究——L1正则化案例分析
PyTorch中L1正则化(绝对值函数)的梯度处理
为什么你的示例中x=0处梯度为0?
首先明确你示例里的细节:你只对y[2](也就是x=0对应的绝对值输出)执行反向传播,所以x中其他位置的梯度自然为0——因为这些位置的输出和你求导的标量y[2]无关。而x=0处的梯度为0,核心原因是绝对值函数在x=0处不可微,PyTorch用次梯度方法处理这类非光滑函数。
PyTorch的具体处理逻辑
绝对值函数abs(x)在x≠0时可微,导数是sign(x)(x>0时为1,x<0时为-1);但在x=0处,函数的左右导数分别是-1和1,不存在唯一的导数,这时候PyTorch采用次梯度(Subgradient)的概念:
- 次梯度是导数对非光滑函数的扩展,对于不可微点,次梯度是一个区间集合(比如abs(x)在x=0处的次梯度是[-1, 1]之间的任意值)。
- PyTorch选择了区间中的0作为x=0处的默认次梯度值,这种选择实现简单,且符合次梯度方法的收敛要求——只要次梯度属于对应集合,就不会影响优化过程的收敛性。
如果把你的代码改成对所有y的和求导,就能更清楚看到完整的梯度表现:
import torch x = torch.linspace(-1.0, 1.0, 5, requires_grad=True) y = torch.abs(x).sum() y.backward() print(x.grad)
输出为:tensor([-1., -1., 0., 1., 1.]),这里x≠0处的梯度是sign(x),x=0处是0,完全符合上述逻辑。
相关学术参考
次梯度方法是凸优化领域处理非光滑问题的标准技术,经典教材《Convex Optimization》(Boyd & Vandenberghe)中有专门章节讲解次梯度的定义、性质,以及在非光滑优化(包括L1正则化)中的应用。此外,随机次梯度下降(Stochastic Subgradient Descent)是处理带L1正则项的损失函数的常用算法,PyTorch的实现完全契合这一学术框架。
内容的提问来源于stack exchange,提问作者Blade
相关产品推荐
相关产品推荐

