Gradient未反向传播至mu,mu梯度始终为零是否正常?
问题分析与解决
这个情况不正常,核心原因是你的对数似然计算中,mu没有参与到有效求导路径里:
问题拆解
看代码里的关键计算步骤:
sampled = mu + sigma * eps logp = -((sampled - mu)**2) / 2 - 0.5 * torch.log(torch.tensor(2 * torch.pi))
sampled - mu的结果是sigma * eps,这部分完全和mu无关,相当于一个常数。对mu求导时,这一项的导数为0,加上后面的常数项导数也为0,最终logp对mu的梯度就是0,反向传播后mu.grad自然为0。
修正方案
高斯分布的对数似然应该基于真实观测数据来计算,而不是用mu生成的采样来计算似然(这样相当于自己拟合自己,mu的影响被抵消了)。比如修改代码如下:
import torch torch.manual_seed(0) mu = torch.zeros(1, requires_grad=True) sigma = 1.0 # 假设有一个真实观测数据x x = torch.randn(1) # 基于真实x计算对数似然 logp = -((x - mu)**2) / (2 * sigma**2) - 0.5 * torch.log(torch.tensor(2 * torch.pi * sigma**2)) loss = -logp.sum() loss.backward() print("x:", x.item()) print("mu.grad:", mu.grad.item()) # 此时梯度为 (x - mu)/sigma²,符合预期
这样修改后,mu会出现在似然的有效项中,反向传播就能得到正确的非零梯度。
内容的提问来源于stack exchange,提问作者Oscar
相关产品推荐
相关产品推荐

