keras-team / keras

Deep Learning for humans
http://keras.io/
Apache License 2.0
61.98k stars 19.48k forks source link

AssertionError: Could not compute output Tensor("sequential_6/dense_31/Sigmoid:0", shape=(None, 784), dtype=float32) #14197

Closed bryanongwx closed 3 years ago

bryanongwx commented 4 years ago

I'm trying a code out from a tutorial online but there seems to be an error in compiling the VAE. Any help would be greatly appreciated!

The tutorial is online here, which was posted in June this year: https://tiao.io/post/tutorial-on-variational-autoencoders-with-a-concise-keras-implementation/

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

from keras import backend as K

from keras.layers import Input, Dense, Lambda, Layer, Add, Multiply
from keras.models import Model, Sequential
from keras.datasets import mnist

original_dim = 784
intermediate_dim = 256
latent_dim = 2
batch_size = 100
epochs = 50
epsilon_std = 1.0

def nll(y_true, y_pred):
    """ Negative log likelihood (Bernoulli). """

    # keras.losses.binary_crossentropy gives the mean
    # over the last axis. we require the sum
    return K.sum(K.binary_crossentropy(y_true, y_pred), axis=-1)

class KLDivergenceLayer(Layer):

    """ Identity transform layer that adds KL divergence
    to the final model loss.
    """

    def __init__(self, *args, **kwargs):
        self.is_placeholder = True
        super(KLDivergenceLayer, self).__init__(*args, **kwargs)

    def call(self, inputs):

        mu, log_var = inputs

        kl_batch = - .5 * K.sum(1 + log_var -
                                K.square(mu) -
                                K.exp(log_var), axis=-1)

        self.add_loss(K.mean(kl_batch), inputs=inputs)

        return inputs

decoder = Sequential([
    Dense(intermediate_dim, input_dim=latent_dim, activation='relu'),
    Dense(original_dim, activation='sigmoid')
])

x = Input(shape=(original_dim,))
h = Dense(intermediate_dim, activation='relu')(x)

z_mu = Dense(latent_dim)(h)
z_log_var = Dense(latent_dim)(h)

z_mu, z_log_var = KLDivergenceLayer()([z_mu, z_log_var])
z_sigma = Lambda(lambda t: K.exp(.5*t))(z_log_var)

eps = Input(tensor=K.random_normal(stddev=epsilon_std,
                                   shape=(K.shape(x)[0], latent_dim)))
z_eps = Multiply()([z_sigma, eps])
z = Add()([z_mu, z_eps])

x_pred = decoder(z)

vae = Model(inputs=[x, eps], outputs=x_pred)
vae.compile(optimizer='rmsprop', loss=nll)

# train the VAE on MNIST digits
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, original_dim) / 255.
x_test = x_test.reshape(-1, original_dim) / 255.

vae.fit(x_train,
        x_train,
        shuffle=True,
        epochs=epochs,
        batch_size=batch_size,
        validation_data=(x_test, x_test))

encoder = Model(x, z_mu)

# display a 2D plot of the digit classes in the latent space
z_test = encoder.predict(x_test, batch_size=batch_size)
plt.figure(figsize=(6, 6))
plt.scatter(z_test[:, 0], z_test[:, 1], c=y_test,
            alpha=.4, s=3**2, cmap='viridis')
plt.colorbar()
plt.show()

# display a 2D manifold of the digits
n = 15  # figure with 15x15 digits
digit_size = 28

# linearly spaced coordinates on the unit square were transformed
# through the inverse CDF (ppf) of the Gaussian to produce values
# of the latent variables z, since the prior of the latent space
# is Gaussian
u_grid = np.dstack(np.meshgrid(np.linspace(0.05, 0.95, n),
                               np.linspace(0.05, 0.95, n)))
z_grid = norm.ppf(u_grid)
x_decoded = decoder.predict(z_grid.reshape(n*n, 2))
x_decoded = x_decoded.reshape(n, n, digit_size, digit_size)

plt.figure(figsize=(10, 10))
plt.imshow(np.block(list(map(list, x_decoded))), cmap='gray')
plt.show()
mbongaerts commented 3 years ago

I have the exact same error. I am using the following versions: Tensorflow 2.3.1 Keras 2.4.0

mbongaerts commented 3 years ago

I have found a solution to make this example work, but I don't dare to promise this is a 'good' workaround.

I was inspired by this issue and solution: https://stackoverflow.com/questions/61997378/assertionerror-could-not-compute-output-tensor

Which made me change some parts of the original code:

x = Input(shape= (original_dim, ), name = 'I1' )
h = Dense(intermediate_dim, activation='relu')(x)

z_mu = Dense(latent_dim)(h)
z_log_var = Dense(latent_dim)(h)

z_mu, z_log_var = KLDivergenceLayer()([z_mu, z_log_var])
z_sigma = Lambda(lambda t: K.exp(.5*t))(z_log_var)

eps = Input(shape=(latent_dim,), name = 'I2') # <--- note

z_eps = Multiply()([z_sigma, eps])
z = Add()([z_mu, z_eps])

decoder = Sequential([
    InputLayer(input_shape=(latent_dim,), name='z'),
    Dense(intermediate_dim, input_shape=(latent_dim,),
          activation='relu', name='hidden_dec'),
    Dense(original_dim, activation='sigmoid')
], name='decoder')

x_pred = decoder(z)

vae = Model(inputs=(x, eps), outputs=x_pred, name='vae')
vae.compile(optimizer='adam', loss=nll)

Training will be done as follow:


(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(-1, original_dim) / 255.
x_test = x_test.reshape(-1, original_dim) / 255.

noise = np.random.normal(0,1, size = (x_train.shape[0],2))

hist = vae.fit({'I1':x_train, 'I2':noise},
                    {'decoder':x_train, },
                    epochs=25,
                    verbose = 1)

And my results are in line with what you expect when using the "generator":

image

tbrittoborges commented 3 years ago

I have experienced a similar issue. Tested https://tiao.io VAE implementation caused exact the same problem, so my guess the issue is related to keras version 2.4.3 or tf 2.3.0, unfortunately the @mbongaerts solution didn't work for me.

tbrittoborges commented 3 years ago

I see the problem now,

You need to propagate the changes to validation as well, and now it will work fine!

Thanks!

mbongaerts commented 3 years ago

I see the problem now,

You need to propagate the changes to validation as well, and now it will work fine!

Thanks!

Good it works! Note, that you do need to frequently change the noise, else it will "learn" only this noise. I just put my training in a loop where the noise each iteration changes.

Good luck!

sushreebarsa commented 3 years ago

@bryanongwx Moving this issue to closed status as there has been no recent activity.In case you still face the error please create a new issue,we will get you the right help.Thanks!