自动编码器最后一层的Keras尺寸不匹配

时间:2018-08-03 09:22:23

标签: python python-3.x keras keras-layer keras-2

我想重用https://blog.keras.io/building-autoencoders-in-keras.html中的卷积自动编码器(具有10位数字/类别的mnist数据集),并将其放入经过修改的版本中,在其中使用ImageDataGenerator从目录中加载图像。我的数据只有两个类,也许就是问题所在,但我不知道如何解决...

from keras.preprocessing.image import ImageDataGenerator
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D
from keras.models import Model

root_dir = '/opt/data/pets'
epochs = 10 # few epochs for testing
batch_size = 32 # No. of images to be yielded from the generator per batch.
seed = 4321 # constant seed for constant conditions
img_channel = 1 # only grayscale image: 1x8bit
img_x, img_y = 128, 128 # image x- and y-dimensions
input_img = Input(shape = (img_x, img_y, img_channel)) # keras image input type

# this is the augmentation configuration we will use for training: do only flips
train_datagen = ImageDataGenerator(
        rescale=1./255,
        horizontal_flip=True)

# this is the augmentation configuration we will use for testing: only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)

# this is a generator that will read pictures found in
# subfolers of 'data/train', and indefinitely generate
# batches of augmented image data
train_generator = train_datagen.flow_from_directory(
        root_dir + '/train',  # this is the target directory
        target_size=(img_x, img_y),  # all images will be resized
        batch_size=batch_size,
        color_mode='grayscale',
        seed = seed)

# this is a similar generator, for validation data
validation_generator = test_datagen.flow_from_directory(
        root_dir + '/validate',
        target_size=(img_x, img_y),
        batch_size=batch_size,
        color_mode='grayscale',
        seed = seed)

# create Convolutional autoencoder from https://blog.keras.io/building-autoencoders-in-keras.html
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)

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',padding='same')(x)
x = UpSampling2D((2, 2))(x)
decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

autoencoder = Model(input_img, decoded)
autoencoder.summary() # show model data

autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')

autoencoder_train = autoencoder.fit_generator(
        train_generator,
        validation_data=validation_generator,
        epochs=epochs,
        shuffle=True)

错误是expected conv2d_121 to have 4 dimensions, but got array with shape (32, 2)

  1. 最后一层具有4个维度(无,128、128、1),编码和解码后的图像均具有原始分辨率。
  2. “(32,2)”似乎是我的batch_size = 32和我隐式的两个类(取自带有训练/验证图像的目录)。

但是我不明白这个问题。其他有类似错误的人在最后一层中的CNN输出很少,必须符合类的数量,但我不适合。

这是模型摘要和错误的输出:

Found 3784 images belonging to 2 classes.
Found 1074 images belonging to 2 classes.
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_24 (InputLayer)        (None, 128, 128, 1)       0         
_________________________________________________________________
conv2d_115 (Conv2D)          (None, 128, 128, 16)      160       
_________________________________________________________________
max_pooling2d_55 (MaxPooling (None, 64, 64, 16)        0         
_________________________________________________________________
conv2d_116 (Conv2D)          (None, 64, 64, 8)         1160      
_________________________________________________________________
max_pooling2d_56 (MaxPooling (None, 32, 32, 8)         0         
_________________________________________________________________
conv2d_117 (Conv2D)          (None, 32, 32, 8)         584       
_________________________________________________________________
max_pooling2d_57 (MaxPooling (None, 16, 16, 8)         0         
_________________________________________________________________
conv2d_118 (Conv2D)          (None, 16, 16, 8)         584       
_________________________________________________________________
up_sampling2d_46 (UpSampling (None, 32, 32, 8)         0         
_________________________________________________________________
conv2d_119 (Conv2D)          (None, 32, 32, 8)         584       
_________________________________________________________________
up_sampling2d_47 (UpSampling (None, 64, 64, 8)         0         
_________________________________________________________________
conv2d_120 (Conv2D)          (None, 64, 64, 16)        1168      
_________________________________________________________________
up_sampling2d_48 (UpSampling (None, 128, 128, 16)      0         
_________________________________________________________________
conv2d_121 (Conv2D)          (None, 128, 128, 1)       145       
=================================================================
Total params: 4,385
Trainable params: 4,385
Non-trainable params: 0
_________________________________________________________________
Epoch 1/10
Traceback (most recent call last):
.....

  File "/opt/anaconda/lib/python3.6/site-packages/keras/engine/training_utils.py", line 126, in standardize_input_data
    'with shape ' + str(data_shape))

ValueError: Error when checking target: expected conv2d_121 to have 4 dimensions, but got array with shape (32, 2)

1 个答案:

答案 0 :(得分:2)

错误与模型无关,而与图像生成器有关。 flow_from_directory 默认会进行分类,并将根据目录生成类输出,因此您会得到类似(32, 2)的内容,即每个图像都有一个类标签,而模型需要一个实际图像。

  

class_mode:“分类”,“二进制”,“稀疏”,“输入”或“无”之一。默认值:“类别”。确定返回的标签数组的类型:   “类别”将是二维一键编码标签。

因此,您希望flow方法中的class_mode="input"返回相同的图像作为目标。 documentation中的更多信息。