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

自定义tf.keras模型定义get_grad仍报No gradients错误原因问询

核心原因

你自定义的get_grad方法不属于TensorFlow Keras Model类的官方公开接口,Keras的fit训练流程完全不会主动调用这个方法,你按照自己的习惯命名的梯度计算方法对Keras来说是无效的。

具体错误点

  • 你调用model.compile()时没有传入任何损失函数,Keras不知道你要优化的目标是什么,自然不会自动计算梯度,这是报错的直接原因。
  • 你写的get_grad方法第一行就执行了return self.auto_encoder.get_grad(X,Y),后面的梯度计算逻辑永远不会执行,属于语法逻辑错误。
  • 你在get_loss中直接使用λ变量,但你在__init__中定义的是类属性self.λ,直接写λ会抛出变量未定义的错误。
  • 你尝试自己计算梯度时,tape.gradient(L,tf.ones(self.input.shape))的第二个参数传入的是全1张量,没有指向模型的可训练权重,就算执行了也得不到网络参数的梯度。
  • 你的call方法返回两个值(自编码器输出、z变量),但fit时传入的y只有一组输入,Keras默认的损失计算逻辑无法匹配输出和标签的结构,也会导致梯度计算失败。

修复建议

如果要接入自定义损失逻辑,不需要自己实现梯度计算方法,按Keras的规范修改即可:

  1. 把自定义损失逻辑放到train_step方法中,这是Keras开放的自定义训练流程接口,fit会自动调用这个方法:
class probablistic_model(tf.keras.Model):
    def __init__(self,dimension,sigma):
        super().__init__()
        self.z=probablistic_feature(dimension,sigma)
        self.auto_encoder=keras_auto_encoder(dimension[0], 30)
        self.λ=2e-1

    def call(self,inputs):
        return self.auto_encoder(inputs),self.z

    def train_step(self, data):
        X = data
        with tf.GradientTape() as tape:
            Y, z = self(X, training=True)
            diff = (X - Y)
            diff = tf.norm(diff, ord=2, axis=1)
            diff *= 2
            diff *= z
            loss = diff - self.λ * tf.norm(diff, ord=1)
        # 计算模型可训练参数的梯度
        grads = tape.gradient(loss, self.trainable_variables)
        # 优化器更新参数
        self.optimizer.apply_gradients(zip(grads, self.trainable_variables))
        # 返回损失值用于日志打印
        return {"loss": loss}
  1. 编译时传入优化器即可,不需要额外传入损失:
model.compile(optimizer="adam")
model.fit(dataset, epochs=10)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 20:06:03