首页 文章

自动编码器最后一层中的Keras维度不匹配

提问于
浏览
3

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

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) .

  • 最后一层有4个维度(无,128,128,1),其编码和解码图像的原始分辨率 .

  • "(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 回答

  • 1

    错误不是关于模型而是关于图像生成器 . flow_from_directory 默认情况下会进行分类,并会根据目录生成一个类输出,因此您可以获得类似于 (32, 2) 的内容,即模型需要实际图像时,每个图像都是类标签 .

    class_mode:“分类”,“二进制”,“稀疏”,“输入”或“无”之一 . 默认值:“分类” . 确定返回的标签数组的类型:“分类”将是2D单热编码标签 .

    所以你希望你的flow方法中的 class_mode="input" 作为目标返回相同的图像 . 更多信息在documentation .

相关问题