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

PyTorch神经网络训练调用loss.backward()报张量无grad及grad_fn错误

错误原因

这个报错的直接原因是反向传播所需的计算图被提前中断,问题出在这行代码:
y_ = (y_>0.5).float()
大于阈值判断和强制转float的操作属于不可导的离散操作,执行后生成的新y_张量会自动丢失梯度属性:requires_grad变为False,也没有记录计算路径的grad_fn,后续基于这个张量计算得到的loss自然也没有梯度信息,执行反向传播时就会触发该错误。

补充说明:你代码里使用的Variable是PyTorch 0.4版本之前的旧API,现在版本的PyTorch已经将Tensor和Variable合并,不需要额外用Variable包裹张量,这个不是本次报错的直接原因,但属于可优化的冗余写法。另外你原代码漏了每次迭代前清零梯度的optimizer.zero_grad()操作,会导致梯度累加,也会影响训练效果。

解决方法
  • 损失计算必须使用模型输出的原始张量,不能使用二值化后的结果。(y_>0.5).float()属于后处理逻辑,仅用于计算准确率、输出预测结果等不需要梯度的场景,要放到损失计算、梯度更新之后执行。
  • 移除冗余的Variable包裹逻辑,补充梯度清零的步骤。
修改后的核心代码示例
for epoch in range(N_EPOCHS):
    model.train()
    for i,(im1, im2, labels) in enumerate(train_dl):
        # 每次迭代前清零梯度
        optimizer.zero_grad()
        i1 = torch.flatten(im1,1)
        i2 = torch.flatten(im2,1)
        inp = torch.cat([i1,i2],1)
        
        b_y = labels
        y_ = model(inp).squeeze()
        # 损失计算使用原始输出,不做二值化
        loss = criterion(y_, b_y)
        loss.backward()
        optimizer.step()

        # 二值化后处理放到梯度更新之后,仅用于统计指标
        pred = (y_>0.5).float()
        print(loss.item())

内容的提问来源于stack exchange,提问作者Muhammad Muneeb Ur Rahman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 22:24:05