i'm trying to adapt the 2d convolutional autoencoder example from the keras website: https://blog.keras.io/building-autoencoders-in-keras.html
to my own case where i use 1d inputs:
from keras.layers import Input, Dense, Conv1D, MaxPooling1D, UpSampling1D
from keras.models import Model
from keras import backend as K
import scipy as scipy
import numpy as np
mat = scipy.io.loadmat('edata.mat')
emat = mat['edata']
input_img = Input(shape=(64,1)) # adapt this if using `channels_first` image data format
x = Conv1D(32, (9), activation='relu', padding='same')(input_img)
x = MaxPooling1D((4), padding='same')(x)
x = Conv1D(16, (9), activation='relu', padding='same')(x)
x = MaxPooling1D((4), padding='same')(x)
x = Conv1D(8, (9), activation='relu', padding='same')(x)
encoded = MaxPooling1D(4, padding='same')(x)
x = Conv1D(8, (9), activation='relu', padding='same')(encoded)
x = UpSampling1D((4))(x)
x = Conv1D(16, (9), activation='relu', padding='same')(x)
x = UpSampling1D((4))(x)
x = Conv1D(32, (9), activation='relu')(x)
x = UpSampling1D((4))(x)
decoded = Conv1D(1, (9), activation='sigmoid', padding='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
x_train = emat[:,0:80000]
x_train = np.reshape(x_train, (x_train.shape[1], 64, 1))
x_test = emat[:,80000:120000]
x_test = np.reshape(x_test, (x_test.shape[1], 64, 1))
from keras.callbacks import TensorBoard
autoencoder.fit(x_train, x_train,
epochs=50,
batch_size=128,
shuffle=True,
validation_data=(x_test, x_test),
callbacks=[TensorBoard(log_dir='/tmp/autoencoder')])
however, i receive this error when i try to run the autoencoder.fit():
ValueError: Error when checking target: expected conv1d_165 to have shape (None, 32, 1) but got array with shape (80000, 64, 1)
i know i'm probably doing something wrong when i set up my layers, i just changed the maxpool and conv2d sizes to a 1d form...i have very little experience with keras or autoencoders, anyone see what i'm doing wrong?
thanks
EDIT: the error when i run it on a fresh console:
ValueError: Error when checking target: expected conv1d_7 to have shape (None, 32, 1) but got array with shape (80000, 64, 1)
here is the output of autoencoder.summary()
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 64, 1) 0
_________________________________________________________________
conv1d_1 (Conv1D) (None, 64, 32) 320
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 16, 32) 0
_________________________________________________________________
conv1d_2 (Conv1D) (None, 16, 16) 4624
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 4, 16) 0
_________________________________________________________________
conv1d_3 (Conv1D) (None, 4, 8) 1160
_________________________________________________________________
max_pooling1d_3 (MaxPooling1 (None, 1, 8) 0
_________________________________________________________________
conv1d_4 (Conv1D) (None, 1, 8) 584
_________________________________________________________________
up_sampling1d_1 (UpSampling1 (None, 4, 8) 0
_________________________________________________________________
conv1d_5 (Conv1D) (None, 4, 16) 1168
_________________________________________________________________
up_sampling1d_2 (UpSampling1 (None, 16, 16) 0
_________________________________________________________________
conv1d_6 (Conv1D) (None, 8, 32) 4640
_________________________________________________________________
up_sampling1d_3 (UpSampling1 (None, 32, 32) 0
_________________________________________________________________
conv1d_7 (Conv1D) (None, 32, 1) 289
=================================================================
Total params: 12,785
Trainable params: 12,785
Non-trainable params: 0
_________________________________________________________________
Since the autoencoder output should reconstruct the input, a minimum requirement is that their dimensions should match, right?
Looking at your
autoencoder.summary()
, it is easy to confirm that this is not the case: your input is of shape(64,1)
, while the output of your last convolutional layerconv1d_7
is(32,1)
(we ignore theNone
in the first dimension, since they refer to the batch size).Let's have a look at the example in the Keras blog you link to (it is a 2D autoencoder, but the idea is the same):
Here is the result of
autoencoder.summary()
in this case:It is easy to confirm that here the dimensions of the input and the output (last convolutional layer
conv2d_7
) are indeed both(28, 28, 1)
.So, the
summary()
method is your friend when building autoencoders; you should experiment with the parameters until you are sure that you produce an output of the same dimensionality as your input. I managed to do so with your autoencoder simply by changing thesize
argument of the lastUpSampling1D
layer from 4 to 8:In which case, the
autoencoder.summary()
becomes:with the dimensionality of your input and output matched, as it should be...