Keras CNN自动编码器输入形状错误

时间:2019-06-04 06:22:54

标签: python opencv keras deep-learning conv-neural-network

我已经使用keras构建了CNN自动编码器,并且对于MNIST测试数据集效果很好。我现在尝试使用从另一个来源收集的不同数据集进行尝试。有纯图像,我必须使用cv2才能正常阅读。然后,我将这些图像转换为一个numpy数组,我再次认为它可以正常工作。但是当我尝试执行.fit方法时,它给了我这个错误。

Error when checking target: expected conv2d_39 to have shape (100, 100, 1) but got array with shape (100, 100, 3)

我尝试将图像转换为灰度,但是它们得到的形状是(100,100),而不是模型想要的(100,100,1)。我在这里做什么错了?

这是我正在使用的代码:

def read_in_images(path):
    images = []
    for files in os.listdir(path):
        img = cv2.imread(os.path.join(path, files))
        if img is not None:
            images.append(img)
    return images

train_images = read_in_images(train_path)
test_images = read_in_images(test_path)
x_train = np.array(train_images)
x_test = np.array(test_images) # (36, 100, 100, 3)

input_img = Input(shape=(100,100,3))
x = Conv2D(32, (3, 3), activation='relu', padding='same')(input_img)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)
x = MaxPooling2D((2, 2), padding='same')(x)
x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)
encoded = MaxPooling2D((2, 2), padding='same')(x)


x = Conv2D(16, (3, 3), activation='relu', padding='same')(encoded)
x = UpSampling2D((2, 2))(x)
x = Conv2D(168, (3, 3), activation='relu', padding='same')(x)
x = UpSampling2D((2, 2))(x)
x = Conv2D(32, (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.fit(x_train, x_train,
            epochs=25,
            batch_size=128,
            shuffle=True,
            validation_data=(x_test, x_test),
            callbacks=[TensorBoard(log_dir='/tmp/autoencoder')])

该模型适用于MNIST数据集,但不适用于我自己的数据集。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您的输入和输出形状不同。这触发了错误(我认为)。

decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)

应该是

decoded = Conv2D(num_channels, (3, 3), activation='sigmoid', padding='same')(x)

答案 1 :(得分:1)

我进行了一些测试,并以这样的灰度加载数据:

img = cv2.imread(os.path.join(path, files), 0)

然后将最终加载的数组的暗度扩展为:

x_train = np.expand_dims(x_train, -1)

最后通过一个简单的方法对数据进行归一化:

x_train = x_train / 255.

(模型的输入必须为:input_img = Input(shape=(100, 100, 1)

损失再次恢复正常,模型运行良好!

评论后更新

为了保持所有rgb通道通过网络,您需要一个与输入形状相对应的输出。
在这里,如果要获得形状为(100,100,3)的图像,则需要解码器的输出为(100,100,3)。

decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)会将输出缩小到具有形状(100,100,1)

所以您只需要更改滤镜的数量,这里我们需要3个颜色通道,因此转换必须像这样:

decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)