简体   繁体   中英

Training Variational Auto Encoder in Keras raises “InvalidArgumentError: Incompatible shapes” error

I have been attempting to get this VAE working all evening, but keep running into the same issue over and over. I am not sure what the problem is. I have tried removing callbacks, validation, changing the loss function, changing the sampling method. The error (while showing below to be early stopping) has consistently been the last argument added to the fit function. I am out of ideas as to how to get this to work.

Below is the reproducible code and then followed is the error I keep having. Note that changing the batch size does change the error, but the mismatched number will also reduce along with the batch size.

import pandas as pd
from sklearn.datasets import make_blobs 
from sklearn.preprocessing import MinMaxScaler

import keras.backend as K
import tensorflow as tf

from keras.layers import Input, Dense, Lambda, Layer, Add, Multiply
from keras.models import Model, Sequential
from keras.callbacks import EarlyStopping, LearningRateScheduler
from keras.objectives import binary_crossentropy


x, labels = make_blobs(n_samples=150000, n_features=110,  centers=16, cluster_std=4.0)
scaler = MinMaxScaler()
x = scaler.fit_transform(x)
x = pd.DataFrame(x)

train = x.sample(n = 100000)
train_indexs = train.index.values
test = x[~x.index.isin(train_indexs)]
print(train.shape, test.shape)

min_dim = 2
batch_size = 1024

def sampling(args):
    mu, log_sigma = args
    eps = K.random_normal(shape=(batch_size, min_dim), mean = 0.0, stddev = 1.0)
    return mu + K.exp(0.5 * log_sigma) * eps

#Encoder
inputs = Input(shape=(x.shape[1],))
down1 = Dense(64, activation='relu')(inputs)
mu = Dense(min_dim, activation='linear')(down1)
log_sigma = Dense(min_dim, activation='linear')(down1)

#Sampling
sample_set = Lambda(sampling, output_shape=(min_dim,))([mu, log_sigma])

#decoder
up1 = Dense(64, activation='relu')(sample_set)
output = Dense(x.shape[1], activation='sigmoid')(up1)

vae = Model(inputs, output)
encoder = Model(inputs, mu)

def vae_loss(y_true, y_pred):
    recon  = binary_crossentropy(y_true, y_pred)
    kl = - 0.5 * K.mean(1 + log_sigma - K.square(mu) - K.exp(log_sigma), axis=-1)
    return recon + kl

vae.compile(optimizer='adam', loss=vae_loss)
vae.fit(train, train, shuffle = True, epochs = 1000, 
        batch_size = batch_size, validation_data = (test, test), 
        callbacks = [EarlyStopping(patience=50)])

Error:


  File "<ipython-input-2-7aa4be21434d>", line 62, in <module>
    callbacks = [EarlyStopping(patience=50)])

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\keras\engine\training.py", line 1239, in fit
    validation_freq=validation_freq)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\keras\engine\training_arrays.py", line 196, in fit_loop
    outs = fit_function(ins_batch)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\keras\backend.py", line 3792, in __call__
    outputs = self._graph_fn(*converted_inputs)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 1605, in __call__
    return self._call_impl(args, kwargs)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 1645, in _call_impl
    return self._call_flat(args, self.captured_inputs, cancellation_manager)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 1746, in _call_flat
    ctx, args, cancellation_manager=cancellation_manager))

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\eager\function.py", line 598, in call
    ctx=ctx)

  File "C:\Users\se01040434\Anaconda3\lib\site-packages\tensorflow\python\eager\execute.py", line 60, in quick_execute
    inputs, attrs, num_outputs)

InvalidArgumentError:  Incompatible shapes: [672] vs. [1024]
     [[node gradients/loss/dense_5_loss/vae_loss/weighted_loss/mul_grad/Mul_1 (defined at C:\Users\se01040434\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:3009) ]] [Op:__inference_keras_scratch_graph_1515]

Function call stack:
keras_scratch_graph

You are creating a random tensor having batch_size samples, where batch_size is a fixed preset value in your code. However, note that the model may not necessarily take as much as batch_size input samples (eg the last batch of training/test data might have smaller number of samples). Instead, in these situations where your model implementation depends on the dynamic value of batch size, you should fetch it dynamically using keras.backend.shape function:

def sampling(args):
    # ...
    eps = K.random_normal(shape=(K.shape(mu)[0], min_dim)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM