Input (X) and output layers (Y) of Keras variational autoencoder don't match, can't run model

I am trying to work on building an variational autoencoder in Keras, with an input shape of X= (1,50) and Y= (1,20).

I made 2 inputs, one for pritection of Y, and the second for reconstruction and I will use it to generate new simples. The reconstruction train very well however, the model can’t learn. The val_predictor_loss stack in 0.77 What is the problem ?

This is my code:

# %% [code]
from keras.layers import Lambda, Input, Dense, Reshape, RepeatVector, Dropout
from keras.models import Model
from keras.datasets import mnist
from keras.losses import mse, binary_crossentropy
from keras.utils import plot_model
from keras import backend as K
from keras.constraints import unit_norm, max_norm
import tensorflow as tf

from scipy import stats
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import argparse
import os
from sklearn.manifold import MDS
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import mean_squared_error, r2_score
from keras.layers import Input, Dense, Flatten, Lambda,Conv1D, BatchNormalization, MaxPooling1D, Activation
from keras.models import Model
import keras.backend as K
import numpy as np

from mpl_toolkits.mplot3d import Axes3D



# reparameterization trick
# instead of sampling from Q(z|X), sample eps = N(0,I)
# z = z_mean + sqrt(var)*eps
def sampling(args):
    """Reparameterization trick by sampling fr an isotropic unit Gaussian.
    # Arguments:
        args (tensor): mean and log of variance of Q(z|X)
    # Returns:
        z (tensor): sampled latent vector
    """

    z_mean, z_log_var = args
    batch = K.shape(z_mean)[0]
    dim = K.int_shape(z_mean)[1]
    # by default, random_normal has mean=0 and std=1.0
    epsilon = K.random_normal(shape=(batch, dim))
    thre = K.random_uniform(shape=(batch,1))
    return z_mean + K.exp(0.5 * z_log_var) * epsilon


# Load my Data
training_feature = X
ground_truth_r = Y

np.random.seed(seed=0)
original_dim = 32

# Define VAE model components
input_shape_x = (32, )
input_shape_r = (16, )
intermediate_dim = 32
latent_dim = 32

# Encoder network
inputs_x = Input(shape=input_shape_x, name='encoder_input')
inputs_x_dropout = Dropout(0.25)(inputs_x)
inter_x1 = Dense(128, activation='tanh')(inputs_x_dropout)
inter_x2 = Dense(intermediate_dim, activation='tanh')(inter_x1)
z_mean = Dense(latent_dim, name='z_mean')(inter_x2)
z_log_var = Dense(latent_dim, name='z_log_var')(inter_x2)
z = Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var])
encoder = Model(inputs_x, [z_mean, z_log_var, z], name='encoder')

# Decoder network for reconstruction
latent_inputs = Input(shape=(latent_dim,), name='z_sampling')
inter_y1 = Dense(intermediate_dim, activation='tanh')(latent_inputs)
inter_y2 = Dense(128, activation='tanh')(inter_y1)
outputs_reconstruction = Dense(original_dim)(inter_y2)
decoder = Model(latent_inputs, outputs_reconstruction, name='decoder')

# Separate network for prediction from latent space
outputs_prediction = Dense(Y.shape[1])(inter_y2)  # Adjust Y.shape[1] as per your data
predictor = Model(latent_inputs, outputs_prediction, name='predictor')

# Instantiate VAE model with two outputs
outputs_vae = [decoder(encoder(inputs_x)[2]), predictor(encoder(inputs_x)[2])]
vae = Model(inputs_x, outputs_vae, name='vae_mlp')
vae.compile(optimizer='adam', loss=['mean_squared_error', 'mean_squared_error'])

# Train the model
history = vae.fit(X, [X, Y], epochs=200, batch_size=64, shuffle=True,validation_data=(XX,[XX, YY]))

@DrBrm17

  1. Ensure that the input data (X and Y) is preprocessed correctly. It’s crucial to normalize or scale the data appropriately, especially if the features have different scales.
from sklearn.preprocessing import StandardScaler

# Assuming X and Y are your input features
scaler_x = StandardScaler()
X_scaled = scaler_x.fit_transform(X)

scaler_y = StandardScaler()
Y_scaled = scaler_y.fit_transform(Y)
  1. Confirm that the input shapes of X and Y match the expected input shapes of the model. The model is defined with an input shape of (32,) for X and (16,) for Y. Make sure your data conforms to these shapes.
  2. Adjust Dropout Rate: The dropout layer is applied to the input features (inputs_x). The dropout rate of 0.25 might be too high, causing information loss. You can try reducing the dropout rate or removing it altogether to see if it improves the model’s learning.
inputs_x_dropout = Dropout(0.25)(inputs_x)
  1. Experiment with different architectures and hyperparameters. You may adjust the number of layers, units per layer, or activation functions. It might be beneficial to add more complexity or simplify the model based on the characteristics of your data.
  2. Instead of using 'mean_squared_error' for both reconstruction and prediction losses, consider using different loss functions based on the nature of the task. For example, mean squared error may be suitable for reconstruction, but you might want to use a different loss function for prediction.
vae.compile(optimizer='adam', loss=['mean_squared_error', 'other_loss_function'])
  1. Consider monitoring and adjusting the learning rate during training. A high learning rate might cause the model to converge too quickly or overshoot the optimal solution.
from keras.optimizers import Adam

optimizer = Adam(learning_rate=0.001)
vae.compile(optimizer=optimizer, loss=['mean_squared_error', 'mean_squared_error'])
  1. Ensure that you have an adequate amount of training data. Insufficient data can lead to overfitting, and the model may struggle to generalize well.
  2. If possible, try training the model on a smaller subset of your data to quickly identify and debug any potential issues.

Apply these suggestions iteratively, and monitor the training process to see if it resolves the problem. If the issue persists, let me know and we can work it out.

Thank u so much, THis is my inputs:

I think I am correct right ? :

import pandas as pd

import sys

import keras.backend as K

from sklearn.model_selection import train_test_split

from keras.models import load_model

NumberOfTraining= 0.7

NumberOfValidation= 0.15

NumberOfTesting=0.15

AllData=Data;

AllData= AllData.sample(frac=1);

TrainData , TestData=train_test_split(AllData, train_size=0.8);

Number of columns and rows

All = TrainData

XAll = All.iloc[:, :32]

YAll = All.iloc[:, 32:]

TrainData , ValidationData=train_test_split(TrainData, train_size=0.8);

XTrainData = TrainData.iloc[:, :32]

YTrainData = TrainData.iloc[:, 32:]

XValidationData= ValidationData.iloc[:, :32]

YValidationData= ValidationData.iloc[:, 32:]

XTestData = TestData.iloc[:, :32]

YTestData = TestData.iloc[:, 32:]

from keras.layers import Input, Dense, Flatten, Conv2D,Dropout

from keras.models import Model, load_model

import time

print(XTrainData.shape)

print(YTrainData.shape)

X= XTrainData.values

Y= YTrainData.values

XX=XValidationData.values

YY=YValidationData.values

VX=XTestData.values

VY=YTestData.values

XAll =XAll.values

YAll= YAll.values

TEST=TestData.values

XY= TrainData.values

XYValid= ValidationData.values

1 Like

@DrBrm17 I’ve made a few adjustments to enhance its clarity and functionality. Here’s the modified version:

import pandas as pd
import sys
import keras.backend as K
from sklearn.model_selection import train_test_split
from keras.models import load_model
from sklearn.preprocessing import StandardScaler

NumberOfTraining = 0.7
NumberOfValidation = 0.15
NumberOfTesting = 0.15

AllData = Data
AllData = AllData.sample(frac=1)

Train-Test Split

TrainData, TestData = train_test_split(AllData, test_size=NumberOfTesting)
TrainData, ValidationData = train_test_split(TrainData, test_size=NumberOfValidation / (1 - NumberOfTesting))

Extract Features and Labels

XAll = AllData.iloc[:, :32]
YAll = AllData.iloc[:, 32:]

XTrainData = TrainData.iloc[:, :32]
YTrainData = TrainData.iloc[:, 32:]

XValidationData = ValidationData.iloc[:, :32]
YValidationData = ValidationData.iloc[:, 32:]

XTestData = TestData.iloc[:, :32]
YTestData = TestData.iloc[:, 32:]

Data Scaling

scaler_x = StandardScaler()
X_scaled = scaler_x.fit_transform(XTrainData)

scaler_y = StandardScaler()
Y_scaled = scaler_y.fit_transform(YTrainData)

Print Shapes for Debugging

print(XTrainData.shape)
print(YTrainData.shape)

Convert to NumPy Arrays

X = X_scaled.values
Y = Y_scaled.values

XX = scaler_x.transform(XValidationData.values)
YY = scaler_y.transform(YValidationData.values)

VX = scaler_x.transform(XTestData.values)
VY = scaler_y.transform(YTestData.values)

XAll = scaler_x.transform(XAll.values)
YAll = scaler_y.transform(YAll.values)

TEST = TestData.values
XY = TrainData.values
XYValid = ValidationData.values