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

Adam优化器因tf.assign函数引发梯度为None的错误及解决方法

解决TensorFlow中梯度为None的报错

问题场景

当使用input = [self.u, self.v]配合当前loss_total计算逻辑时,触发梯度为None的错误,报错信息如下:

ValueError: No gradients provided for any variable: (['Variable_541:0', 'Variable_542:0'],). Provided `grads_and_vars` is ((None, <tf.Variable 'Variable_541:0' shape=(5, 5) dtype=float32>), (None, <tf.Variable 'Variable_542:0' shape=(5, 5) dtype=float32>)).

报错发生在optimizer_utils.filter_empty_gradients函数中。

错误原因

核心问题是loss_estimation方法里的原地赋值操作assign切断了梯度流:

self.U_padded[1:-1,1:-1].assign(self.u)
self.V_padded[1:-1,1:-1].assign(self.v)

TensorFlow的tf.GradientTape无法追踪原地修改变量的操作,导致loss_total(基于U_padded和V_padded计算)与原始变量u、v之间没有可微分的计算链路,最终无法计算出梯度。

解决方案

替换原地assign操作,改用可微分的张量填充逻辑,让U_padded、V_padded成为u、v的派生张量,从而保留梯度传递链路。

修改后的代码

1. 重写loss_estimation方法

移除assign,用tf.pad实现填充逻辑:

@tf.function
def loss_estimation(self):
    # 用tf.pad生成带padding的张量,替代原地assign
    self.U_padded = tf.pad(self.u, [[1, 1], [1, 1]], mode='CONSTANT')
    self.V_padded = tf.pad(self.v, [[1, 1], [1, 1]], mode='CONSTANT')
    self.loss_total = mean_squared_error(self.U_padded + self.V_padded, 0)
    return self.loss_total

2. 保留原train方法不变

@tf.function
def train(self, optimizer):
    with tf.GradientTape() as tape:
        input = [self.u, self.v]
        self.loss = self.loss_estimation()
    self.gradients = tape.gradient(self.loss, input)
    optimizer.apply_gradients(zip(self.gradients, input))

额外说明

如果必须保留U_padded、V_padded为类变量,无需在__init__中初始化它们,直接在loss_estimation中动态生成即可,这样既满足计算需求,又能保证梯度正常传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 08:57:14