【问题标题】:Problem building a ANN Regressor model with Autoencoder in Tensorflow 2.11在 Tensorflow 2.11 中使用自动编码器构建 ANN 回归模型时出现问题
【发布时间】:2023-02-09 18:21:00
【问题描述】:

我的输入是一个 2D numpy 维度数组 (364660, 5052)。目标是 (364660, 1),一个回归变量。我试图构建一个引导式自动编码器 + ANN 回归器,其中自动编码器的编码层用作 ann 回归器的输入。我想一次性训练这两个模型。但是,自动编码器的损失应该是自动编码器损失 + ann 损失的组合。 ANN 损失保持不变。这是我的示例代码

class AutoencoderRegressor(tf.keras.Model):
    def __init__(self, encoder_layers, decoder_layers, regressor_layers, autoencoder_loss_weights):
        super(AutoencoderRegressor, self).__init__()
        self.autoencoder = tf.keras.models.Sequential(encoder_layers + decoder_layers)
        self.regressor = tf.keras.models.Sequential(regressor_layers)
        self.autoencoder_loss_weights = autoencoder_loss_weights

    def call(self, inputs, training=None, mask=None):
        autoencoder_output = self.autoencoder(inputs)
        regressor_input = self.autoencoder.get_layer(index=2).output
        regressor_output = self.regressor(regressor_input)
        return autoencoder_output, regressor_output

    def autoencoder_loss(self, autoencoder_output, inputs):
        binary_crossentropy = tf.keras.losses.BinaryCrossentropy()
        mean_squared_error = tf.keras.losses.MeanSquaredError()
        autoencoder_reconstruction_loss = binary_crossentropy(inputs, autoencoder_output)
        autoencoder_regression_loss = mean_squared_error(inputs, autoencoder_output)
        #autoencoder_loss = self.autoencoder_loss_weights[0] * autoencoder_reconstruction_loss + self.autoencoder_loss_weights[1] * autoencoder_regression_loss 
        autoencoder_loss = autoencoder_reconstruction_loss+autoencoder_regression_loss

        return autoencoder_loss

    def regressor_loss(self, regressor_output, targets):
        mean_squared_error = tf.keras.losses.MeanSquaredError()
        regressor_loss = mean_squared_error(targets, regressor_output)
        return regressor_loss

# define the encoder layers
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')]

# define the decoder layers
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')]

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

# define the
autoencoder_loss_weights = [0.8, 0.2]

autoencoder_regressor = AutoencoderRegressor(encoder_layers, decoder_layers,    regressor_layers, autoencoder_loss_weights)

autoencoder_regressor.compile(optimizer='adam', loss=[autoencoder_regressor.autoencoder_loss, autoencoder_regressor.regressor_loss])

autoencoder_regressor.fit(reduced_x_train2, [reduced_x_train2, y_train], epochs=100, 
                      batch_size=32, validation_split=0.9,shuffle =True,
                     verbose = 2)

我收到以下错误:

TypeError Traceback(最后一次调用) 在 [14] 中输入 <cell line: 60>() 第 56 章 58 autoencoder_regressor.compile(优化器='adam',损失=[autoencoder_regressor.autoencoder_loss,autoencoder_regressor.regressor_loss]) ---> 60 autoencoder_regressor.fit(reduced_x_train2, [reduced_x_train2, y_train], epochs=100, 61 batch_size=32,validation_split=0.9,shuffle=True, 62 详细 = 2)

类型错误:在用户代码中:

File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/training.py", line 1051, in train_function  *
    return step_function(self, iterator)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/training.py", line 1040, in step_function  **
    outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/training.py", line 1030, in run_step  **
    outputs = model.train_step(data)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/training.py", line 890, in train_step
    loss = self.compute_loss(x, y, y_pred, sample_weight)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/training.py", line 948, in compute_loss
    return self.compiled_loss(
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/compile_utils.py", line 215, in __call__
    metric_obj.update_state(loss_metric_value, sample_weight=batch_dim)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/utils/metrics_utils.py", line 70, in decorated
    update_op = update_state_fn(*args, **kwargs)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/metrics/base_metric.py", line 140, in update_state_fn
    return ag_update_state(*args, **kwargs)
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/metrics/base_metric.py", line 449, in update_state  **
    sample_weight = tf.__internal__.ops.broadcast_weights(
File "/user/iibi/amudireddy/.conda/envs/tfni10_py38/lib/python3.8/site-packages/keras/engine/keras_tensor.py", line 254, in __array__
    raise TypeError(

TypeError: You are passing KerasTensor(type_spec=TensorSpec(shape=(), dtype=tf.float32, name=None), name='Placeholder:0', description="created by layer 'tf.cast_15'"), an intermediate Keras symbolic input/output, to a TF API that does not allow registering custom dispatchers, such as 'tf.cond, 'tf.function', gradient tapes, or 'tf.map_fn'. Keras Functional model construction only supports TF API calls that *do* support dispatching, such as 'tf.math.add' or 'tf.reshape'. Other APIs cannot be called directly on symbolic Kerasinputs/outputs. You can work around this limitation by putting the operation in a custom Keras layer 'call' and calling that layer on this symbolic input/output.

我哪里错了?

【问题讨论】:

    标签: python tensorflow keras regression autoencoder


    【解决方案1】:

    我不完全知道为什么你的方法不起作用,尽管问题似乎出在 regressor_input =self.autoencoder.get_layer(index=2).output 行。但是,这是一个替代方案:

    import numpy as np
    import tensorflow as tf
    
    class AutoEncoderRegressor(tf.keras.Model):
        def __init__(self, encoder, decoder, regressor, loss_weights):
            super(AutoEncoderRegressor, self).__init__()
            self.encoder = encoder
            self.decoder = decoder
            self.regressor = regressor
            self.loss_weights = loss_weights
    
        def call(self, inputs, training=None, mask=None):
            encoded = self.encoder(inputs)
            decoded = self.decoder(encoded)
            regression = self.regressor(encoded)
            return decoded, regression
    
        def autoencoder_loss(self, autoencoder_output, inputs):
            autoencoder_reconstruction_loss = tf.keras.losses.BinaryCrossentropy()(inputs, autoencoder_output)
            autoencoder_regression_loss = tf.keras.losses.MeanSquaredError()(inputs, autoencoder_output)
            return autoencoder_reconstruction_loss+autoencoder_regression_loss
    
        def regressor_loss(self, regressor_output, targets):
            return tf.keras.losses.MeanSquaredError()(targets, regressor_output)
    
    
    def main():
        input_dim = 10
    
        # generate random training data
        rng = np.random.default_rng()
        X   = rng.random((100,input_dim))
        y   = [X, rng.random((100,1))]
    
        encoder = tf.keras.Sequential([
            tf.keras.layers.Dense(64, activation='relu', input_shape=(input_dim,)),
            tf.keras.layers.Dense(32, activation='relu'),
            tf.keras.layers.Dense(16, activation='relu')
        ])
    
        decoder = tf.keras.Sequential([
            tf.keras.layers.Dense(32, activation='relu'),
            tf.keras.layers.Dense(64, activation='relu'),
            tf.keras.layers.Dense(input_dim, activation='sigmoid')
        ])
    
        regressor = tf.keras.Sequential([
            tf.keras.layers.Dense(8, activation='relu', input_shape=(16,)),
            tf.keras.layers.Dense(1, activation='linear')
        ])
    
        model = AutoEncoderRegressor(encoder, decoder, regressor, loss_weights=[0.8, 0.2])
        model.compile(
            optimizer = 'adam',
            loss = [model.autoencoder_loss, model.regressor_loss],
            loss_weights = model.loss_weights
        )
    
        model.fit(X,y,
          epochs = 100,
          batch_size = 32,
          validation_split = 0.9,
          shuffle = True,
          verbose = 2
        )
    
    if __name__ == "__main__":
        main()
    

    我在这里使用较小尺寸的随机训练数据进行测试,请根据您的实际数据集进行调整。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-26
      • 2018-04-26
      • 1970-01-01
      • 2019-10-04
      • 2018-04-26
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      相关资源
      最近更新 更多