You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch调用Optimizer后模型参数无法更新的问题求助

模型参数不更新问题的诊断与解决

核心原因:不可导操作导致梯度断裂

你的CLUSTER_L模型forward方法中使用了round()函数:

outputs = ((self.af(d_outputs)+0.1)*10).round()

round()是不可导的离散操作,反向传播时该操作的梯度为0,导致梯度无法传递到前面的线性层(self.cl中的参数),因此执行loss.backward()后,模型参数的梯度始终为0,optimiser_c.step()自然无法更新参数。

即使替换为cross_entropy,只要round()还在,梯度传递就会被阻断,参数依然不会更新。

解决方案

1. 移除或替换不可导的round()操作

训练阶段必须保证前向传播的所有操作都是可导的,建议先移除round(),仅在推理阶段对输出做离散化处理:
修改后的forward方法:

def forward(self, inputs):
    d_outputs = self.cl(inputs).view(self.n*self.lbd, self.input_size)
    # 训练阶段仅保留可导操作,移除round()
    outputs = (self.af(d_outputs)+0.1)*10
    outputs2 = outputs * inputs
    return outputs2

如果业务需求必须在训练阶段做近似离散化,可以用可导的近似函数替代round(),比如用硬sigmoid配合缩放:

# 用平滑函数近似round,保留可导性
def smooth_round(x):
    return torch.floor(x) + torch.sigmoid(10*(x - torch.floor(x) - 0.5))
outputs = smooth_round((self.af(d_outputs)+0.1)*10)

2. 其他排查要点

  • 确认cluster_L损失函数返回的是标量且requires_grad为True(可打印loss_Cluster.requires_grad验证)
  • 检查优化器绑定的c_param是否包含cluster的所有可训练参数(可打印len(c_param),对应3个线性层的权重+偏置,共6个参数)
  • 暂时注释clip_grad_norm_,验证是否因梯度裁剪阈值过大导致梯度被清零

修改后的验证步骤

  1. 移除round()后,在loss.backward()后打印cluster.cl[0].weight.grad,确认梯度不为0
  2. 执行optimiser_c.step()后,对比参数更新前后的值,确认参数已变化

内容的提问来源于stack exchange,提问作者KaraLee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:30:31