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

TensorFlow 2.11.0中Adam优化器报无get_updates属性错误求助

问题排查与解决方案

错误原因分析

AttributeError: 'Adam' object has no attribute 'get_updates' 并非单纯版本不匹配问题,而是自定义损失/指标的写法不符合TensorFlow 2.x规范:

  • TensorFlow 2.x的tf.keras.optimizers.Adam确实没有get_updates方法(该方法属于旧版独立Keras的优化器),如果你的自定义损失/指标函数内部直接调用了这个方法,就会触发错误。
  • 你的编译代码中,metrics列表里的calculate_kl_loss(self)是直接调用函数并传入实例,这不符合要求——metrics需要传入的是可调用的函数对象,而非函数执行后的结果。

具体修复步骤

1. 修正VAE损失的处理方式(推荐方案)

VAE的KL散度损失通常通过add_loss方法添加到模型中,而非作为metrics传入,更符合tf.keras的设计逻辑:

class VAE(tf.keras.Model):
    def __init__(self, latent_dim):
        super(VAE, self).__init__()
        self.latent_dim = latent_dim
        self.encoder = self.build_encoder()
        self.decoder = self.build_decoder()

    def build_encoder(self):
        # 示例编码器结构,可根据你的任务调整
        inputs = tf.keras.Input(shape=(28,28,1))
        x = tf.keras.layers.Flatten()(inputs)
        x = tf.keras.layers.Dense(256, activation='relu')(x)
        z_mean = tf.keras.layers.Dense(self.latent_dim)(x)
        z_log_var = tf.keras.layers.Dense(self.latent_dim)(x)
        z = self.sampling(z_mean, z_log_var)
        return tf.keras.Model(inputs, [z_mean, z_log_var, z])

    def sampling(self, z_mean, z_log_var):
        epsilon = tf.random.normal(shape=tf.shape(z_mean))
        return z_mean + tf.exp(0.5 * z_log_var) * epsilon

    def build_decoder(self):
        # 示例解码器结构,可根据你的任务调整
        latent_inputs = tf.keras.Input(shape=(self.latent_dim,))
        x = tf.keras.layers.Dense(256, activation='relu')(latent_inputs)
        x = tf.keras.layers.Dense(784, activation='sigmoid')(x)
        outputs = tf.keras.layers.Reshape((28,28,1))(x)
        return tf.keras.Model(latent_inputs, outputs)

    def call(self, inputs):
        z_mean, z_log_var, z = self.encoder(inputs)
        reconstruction = self.decoder(z)
        
        # 计算KL损失并添加到模型
        kl_loss = -0.5 * tf.reduce_mean(1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var))
        self.add_loss(kl_loss)
        
        return reconstruction

2. 修正compile方法

此时compile方法只需指定重建损失,KL损失会自动被模型纳入总损失计算:

def compile(self, learning_rate=0.0001):
    optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
    # 用MSE或交叉熵作为重建损失,根据你的任务选择
    self.compile(optimizer=optimizer, loss=tf.keras.losses.MSE)
    # 如果需要监控重建损失,可添加对应metrics
    # self.compile(optimizer=optimizer, loss=tf.keras.losses.MSE, metrics=[tf.keras.losses.MSE])

3. 检查自定义损失函数(若需保留)

如果坚持使用自定义的_calculate_combined_loss,确保它的签名符合tf.keras损失函数要求,且内部没有调用optimizer.get_updates:

def _calculate_combined_loss(self, y_true, y_pred):
    # 计算重建损失
    recon_loss = tf.keras.losses.MSE(y_true, y_pred)
    recon_loss = tf.reduce_mean(recon_loss)
    # 获取KL损失(需确保模型中已计算并存储)
    kl_loss = self.kl_loss  # 假设你在call方法中把kl_loss存在实例变量里
    return recon_loss + kl_loss

同时,metrics列表要传入函数对象,而非调用后的结果:

# 错误写法:calculate_kl_loss(self)
# 正确写法:传入函数(若该函数不需要实例参数,需调整实现)
self.model.compile(optimizer=optimizer,
                   loss=self._calculate_combined_loss,
                   metrics=[_calculate_reconstruction_loss, calculate_kl_loss])

额外注意事项

  • 避免在自定义损失/指标中直接操作优化器,tf.keras会自动处理梯度更新流程。
  • TensorFlow 2.x中,tf.keras和独立keras的API存在差异,确保全程使用tf.keras下的类和方法,避免混用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 17:15:42