I am trying to build a simple Autoencoder using the KMNIST dataset from Tensorflow and some sample code from a textbook I'm using, but I keep getting an error when I try to fit the model.
The error says ValueError: Layer sequential_20 expects 1 inputs, but it received 2 input tensors.
I'm really new to TensorFlow, and all my research on this error has baffled me since it seems to involve things not in my code. This thread wasn't helpful since I'm only using sequential layers.
Code in full:
import numpy as np
import tensorflow as tf
from tensorflow import keras
import tensorflow_datasets as tfds
import pandas as pd
import matplotlib.pyplot as plt
#data = tfds.load(name = 'kmnist')
(img_train, label_train), (img_test, label_test) = tfds.as_numpy(tfds.load(
name = 'kmnist',
split=['train', 'test'],
batch_size=-1,
as_supervised=True,
))
img_train = img_train.squeeze()
img_test = img_test.squeeze()
## From Hands on Machine Learning Textbook, chapter 17
stacked_encoder = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(100, activation="selu"),
keras.layers.Dense(30, activation="selu"),
])
stacked_decoder = keras.models.Sequential([
keras.layers.Dense(100, activation="selu", input_shape=[30]),
keras.layers.Dense(28 * 28, activation="sigmoid"),
keras.layers.Reshape([28, 28])
])
stacked_ae = keras.models.Sequential([stacked_encoder, stacked_decoder])
stacked_ae.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.SGD(lr=1.5))
history = stacked_ae.fit(img_train, img_train, epochs=10,
validation_data=[img_test, img_test])
In solutions, some says you need to change from bracelet to parentheses, but it was not working in Colab. And yes, turningvalidation_data=[X_val, y_val] into validation_data=(X_val, y_val) should work since it's required format, but in tf==2.5.0(in Google Colab) it doesn't solve the problem. I changed from functional API to sequential API, that solves the problem. Strange.
You have given data instead of labels two times:
history = stacked_ae.fit(img_train, img_train, epochs=10,
validation_data=[img_test, img_test])
instead of
history = stacked_ae.fit(img_train, label_train, epochs=10,
validation_data=[img_test, label_test])
Use validation_data=(img_test, img_test) instead of validation_data=[img_test, img_test]
Here the example with encoder and decoder combined together:
stacked_ae = keras.models.Sequential([
keras.layers.Flatten(input_shape=[28, 28]),
keras.layers.Dense(100, activation="selu"),
keras.layers.Dense(30, activation="selu"),
keras.layers.Dense(100, activation="selu"),
keras.layers.Dense(28 * 28, activation="sigmoid"),
keras.layers.Reshape([28, 28])
])
stacked_ae.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.SGD(lr=1.5))
history = stacked_ae.fit(img_train, img_train, epochs=10,
validation_data=(img_test, img_test))
it helped me when I changed:
validation_data=[X_val, y_val] into validation_data=(X_val, y_val)
Actually still wonder why?
As stated in the Keras API reference (link),
validation_data: ... validation_data could be: -
tuple(x_val, y_val) of Numpy arrays or tensors -tuple(x_val, y_val, val_sample_weights) of Numpy arrays - dataset ...
So, validation_data has to be a tuple rather than a list (of Numpy arrays or tensors). We should use parentheses (round brackets) (...), not square brackets [...].
According to my limited experience, however, TensorFlow 2.0.0 would be indifferent to the use of square brackets, but TensorFlow 2.3.0 would complain about it. Your script would be fine if it is run under TF 2.0 intead of TF 2.3.