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

TensorFlow 2.11中Autoencoder结合ANN回归器训练报错及实现疑问

问题与解决方案

问题背景

输入为(364660, 5052)的2D numpy特征数组,目标变量是(364660, 1)的回归值。需要实现一个联合训练的引导式Autoencoder+ANN回归模型:

  • Autoencoder损失 = 重构损失(输入与重构输出的误差) + 加权的回归损失(目标值与回归器输出的误差)
  • 回归器单独计算MSE损失,同时参与联合训练

原代码运行触发TypeError,核心问题在于中间层符号张量的错误调用,以及多输出模型的损失计算逻辑不符合Keras要求。

错误原因

  1. 中间层输出获取方式错误:原代码通过self.autoencoder.get_layer(index=2).output直接获取Sequential模型的中间层输出,这是符号化的KerasTensor,无法直接在训练流程中传递给回归器,导致TF API无法处理。
  2. 损失函数逻辑不完整:原Autoencoder损失函数没有接收回归目标值和回归器输出,无法实现"重构损失+回归损失"的组合逻辑。

修正后的代码

import tensorflow as tf
import numpy as np

# 模拟数据(替换为你的真实数据)
reduced_x_train2 = np.random.rand(364660, 5052).astype(np.float32)
y_train = np.random.rand(364660, 1).astype(np.float32)

class AutoencoderRegressor(tf.keras.Model):
    def __init__(self, encoder_layers, decoder_layers, regressor_layers, autoencoder_loss_weights):
        super(AutoencoderRegressor, self).__init__()
        # 拆分Encoder、Decoder为独立模型,方便获取编码输出
        self.encoder = tf.keras.models.Sequential(encoder_layers)
        self.decoder = tf.keras.models.Sequential(decoder_layers)
        self.regressor = tf.keras.models.Sequential(regressor_layers)
        self.autoencoder_loss_weights = autoencoder_loss_weights
        # 预定义损失函数实例,避免重复初始化
        self.bce_loss = tf.keras.losses.BinaryCrossentropy()
        self.mse_loss = tf.keras.losses.MeanSquaredError()

    def call(self, inputs, training=None, mask=None):
        # 前向传播:先编码,再分别解码、回归
        encoded = self.encoder(inputs, training=training)
        decoded = self.decoder(encoded, training=training)
        regressed = self.regressor(encoded, training=training)
        return decoded, regressed

    def train_step(self, data):
        # 拆分输入数据:特征x,重构目标x,回归目标y
        x, (x_target, y_target) = data

        with tf.GradientTape() as tape:
            # 前向传播得到两个输出
            decoded_output, regressed_output = self(x, training=True)
            
            # 计算Autoencoder的组合损失:重构损失 + 加权回归损失
            recon_loss = self.bce_loss(x_target, decoded_output)
            reg_loss_for_ae = self.mse_loss(y_target, regressed_output)
            autoencoder_total_loss = (self.autoencoder_loss_weights[0] * recon_loss 
                                     + self.autoencoder_loss_weights[1] * reg_loss_for_ae)
            
            # 计算回归器单独的损失
            regressor_loss = self.mse_loss(y_target, regressed_output)
            
            # 总损失:Autoencoder组合损失 + 回归器损失(可按需调整权重)
            total_loss = autoencoder_total_loss + regressor_loss

        # 计算梯度并更新模型权重
        trainable_vars = self.trainable_variables
        gradients = tape.gradient(total_loss, trainable_vars)
        self.optimizer.apply_gradients(zip(gradients, trainable_vars))

        # 更新训练指标,用于监控过程
        self.compiled_metrics.update_state([x_target, y_target], [decoded_output, regressed_output])
        return {m.name: m.result() for m in self.metrics}

# 定义各层结构
encoder_layers = [
    tf.keras.layers.Dense(64, activation='relu', input_shape=(reduced_x_train2.shape[1],)),
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(16, activation='relu')
]

decoder_layers = [
    tf.keras.layers.Dense(32, activation='relu'),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dense(reduced_x_train2.shape[1], activation='sigmoid')
]

regressor_layers = [
    tf.keras.layers.Dense(8, activation='relu', input_shape=(16,)),
    tf.keras.layers.Dense(1, activation='linear')
]

autoencoder_loss_weights = [0.8, 0.2]

# 初始化模型并编译
model = AutoencoderRegressor(encoder_layers, decoder_layers, regressor_layers, autoencoder_loss_weights)
model.compile(optimizer='adam', 
              loss=[None, None],  # 自定义train_step,无需指定默认损失
              metrics={'decoder_output': tf.keras.metrics.BinaryCrossentropy(),
                       'regressor_output': tf.keras.metrics.MeanSquaredError()})

# 启动训练
model.fit(reduced_x_train2, [reduced_x_train2, y_train], 
          epochs=100, batch_size=32, 
          validation_split=0.1, shuffle=True, verbose=2)

关键修正点

  1. 拆分Encoder与Decoder:将原Autoencoder拆分为独立的encoder和decoder模型,在call方法中先得到编码输出,再分别传入Decoder和Regressor,避免直接获取中间层符号张量的错误。
  2. 自定义train_step:手动实现训练步骤,在梯度带内同时计算Autoencoder的组合损失(重构损失+回归损失)和回归器的单独损失,确保所有张量操作符合Keras训练流程。
  3. 损失逻辑对齐需求:Autoencoder损失中同时引入了重构损失(输入与解码输出)和回归损失(目标值与回归输出),并通过权重参数控制两者的贡献。
  4. 指标配置:编译时指定对应输出的指标,方便训练过程中监控各部分损失的变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:16:24