为什么UpSampling2d Keras图层不起作用?

时间:2018-07-13 20:57:14

标签: image tensorflow keras convolution autoencoder

我尝试在keras中构建卷积自动编码器,但似乎无法正常工作。 首先,这是代码:

from keras.models import Sequential
from keras.layers import Reshape
from keras.layers import Flatten
from keras.layers import Dense
from keras.layers import Conv2D
from keras.layers import MaxPooling2D
from keras.layers import UpSampling2D
from keras.optimizers import RMSprop
from keras.losses import categorical_crossentropy
import numpy as np
import matplotlib.pyplot as plt
import scipy
import h5py
import random
from glob import glob
from tqdm import tqdm
from os import getcwd

learning_rate = 0.001
epochs = 10000
batch_size = 200
data_len = 400
training_data = []

for filename in tqdm(glob('D:/AI/Celeba/*.jpg')[0:data_len],desc='loading images'):
    im = scipy.misc.imread(filename)
    im = scipy.misc.imresize(im,(128,128))
    training_data.append(im)
training_data = np.array(training_data)
example = random.choice(training_data)

autoencoder = Sequential()
autoencoder.add(Conv2D(32,5,activation='relu',input_shape=(128,128,3)))
autoencoder.add(MaxPooling2D())
autoencoder.add(Conv2D(16,5,activation='relu'))
autoencoder.add(MaxPooling2D())
autoencoder.add(Conv2D(8,5,activation='relu'))
autoencoder.add(MaxPooling2D())
autoencoder.add(Conv2D(4,5,activation='relu'))
autoencoder.add(MaxPooling2D())
autoencoder.add(Conv2D(2,3,activation='relu'))
autoencoder.add(MaxPooling2D())
autoencoder.add(Flatten())
autoencoder.add(Dense(32,activation='sigmoid'))
autoencoder.add(Dense(32,activation='sigmoid'))
autoencoder.add(Reshape((4,4,2)))
autoencoder.add(Conv2D(2,3,activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(4,5,activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(8,5,activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(16,5,activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(32,5,activation='relu'))
autoencoder.add(UpSampling2D())
autoencoder.add(Conv2D(3,5,activation='relu'))
autoencoder.compile(optimizer=RMSprop(lr=learning_rate),loss=categorical_crossentropy)

for epoch in range(epochs):
    autoencoder.fit(x=training_data,y=training_data,batch_size=batch_size,epochs=1)
    output = autoencoder.predict(np.array([example]))[0]
    fig = plt.figure()
    fig.suptitle('training step: {}'.format(epoch+1))
    a=fig.add_subplot(1,2,1)
    imgplot = plt.imshow(example)
    a.set_title('Original')
    a=fig.add_subplot(1,2,2)
    imgplot = plt.imshow(output)
    imgplot.set_clim(0.0,0.7)
    a.set_title('Reconstruction')
    plt.savefig(getcwd()+'/training/{}.png'.format(epoch))

    if (epoch+1)%10 == 0:
        autoencoder.save(getcwd()+'/saved/model.h5')

所以我的问题是模型输出的形状错误。输出形状应为[batch_size, 2, 2, 3]时为[batch_size, 128, 128, 3]。 我已经进行了一些调试,并找出了为什么模型输出错误尺寸的一些可能原因:

  1. UpSampling2D层什么也没做
  2. 由于某些原因,最后一个Conv2D层将图片的尺寸减小了2个

有人知道我该如何解决吗?

PS。 在撰写本文时,我意识到我的调试结果可以用另一种方式解释:

  1. UpSampling2D层工作正常
  2. 所有Conv2D层的图像尺寸都减小了2,因此图像始终保持2 * 2的高度

1 个答案:

答案 0 :(得分:1)

在Conv2D层中,您正在减小输入的大小。

在卷积中,如果您拍摄了32 x 32的图像,并且应用了5x5的内核。输出图像的大小将为28 x 28。

3 x 3的内核将产生30 x 30的图像,而4 x 4则将产生29 x 29的图像。

如果要防止卷积减小,可以在其上添加填充。

This提供了一个很好的资源来了解是否要填充。

也很高兴知道大小为奇数时下采样是向下取整还是向上取整,这可能对以后有所帮助。我相信它会四舍五入。

我还强烈建议您执行autoencoder.summary(),这将为您提供有关每一层尺寸的信息。有了这个,您可以弄清楚每一层正在发生什么。