我正在尝试改编来自keras网站的2d卷积自动编码器示例:https://blog.keras.io/building-autoencoders-in-keras.html
在我自己的情况下,我使用一维输入:
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')])
但是,当我尝试运行autoencoder.fit()时收到此错误:
ValueError:检查目标时出错:预期conv1d_165具有
形状(无,32、1),但数组的形状为(80000、64、1)
我知道我在设置图层时可能做错了什么,我只是将maxpool和conv2d大小更改为1d形式...我对keras或自动编码器的经验很少,有人看到我在做错什么吗?
谢谢
编辑:
当我在新的控制台上运行该错误时:
ValueError:检查目标时出错:预期conv1d_7具有
形状(无,32、1),但数组的形状为(80000、64、1)
这是
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
_________________________________________________________________
最佳答案
由于自动编码器的输出应重建输入,因此最低要求是其尺寸应匹配,对吗?
查看您的autoencoder.summary()
,很容易确认并非如此:您输入的形状为(64,1)
,而最后一个卷积层conv1d_7
的输出为(32,1)
(我们忽略了None
在第一维中,因为它们指的是批次大小)。
让我们看一下链接到的example in the Keras blog(它是一个2D自动编码器,但是思想是相同的):
from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model
from keras import backend as K
input_img = Input(shape=(28, 28, 1)) # adapt this if using `channels_first` image data format
x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)
# at this point the representation is (4, 4, 8) i.e. 128-dimensional
x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(16, (3, 3), activation='relu')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
在这种情况下,这是
autoencoder.summary()
的结果:_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 28, 28, 1) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 28, 28, 16) 160
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 14, 14, 16) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 14, 14, 8) 1160
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 7, 7, 8) 0
_________________________________________________________________
conv2d_3 (Conv2D) (None, 7, 7, 8) 584
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 4, 4, 8) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 4, 4, 8) 584
_________________________________________________________________
up_sampling2d_1 (UpSampling2 (None, 8, 8, 8) 0
_________________________________________________________________
conv2d_5 (Conv2D) (None, 8, 8, 8) 584
_________________________________________________________________
up_sampling2d_2 (UpSampling2 (None, 16, 16, 8) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, 14, 14, 16) 1168
_________________________________________________________________
up_sampling2d_3 (UpSampling2 (None, 28, 28, 16) 0
_________________________________________________________________
conv2d_7 (Conv2D) (None, 28, 28, 1) 145
=================================================================
Total params: 4,385
Trainable params: 4,385
Non-trainable params: 0
很容易确认,这里输入和输出(最后卷积层
conv2d_7
)的尺寸确实都是(28, 28, 1)
。因此,在构建自动编码器时,
summary()
方法是您的朋友。您应该尝试使用这些参数,直到您确定产生的输出与输入的尺寸相同。我设法通过将最后一个size
层的UpSampling1D
参数从4更改为8来使用您的自动编码器:input_img = Input(shape=(64,1))
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((8))(x) ## <-- change here (was 4)
decoded = Conv1D(1, (9), activation='sigmoid', padding='same')(x)
autoencoder = Model(input_img, decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
在这种情况下,
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, 64, 32) 0
_________________________________________________________________
conv1d_7 (Conv1D) (None, 64, 1) 289
=================================================================
Total params: 12,785
Trainable params: 12,785
Non-trainable params: 0
输入和输出的尺寸匹配,应该这样...