代码之家  ›  专栏  ›  技术社区  ›  jfp

keras tensorflow CAE尺寸不匹配

  •  0
  • jfp  · 技术社区  · 7 年前

    this 使用tensorflow后端构建卷积自动编码器指南。与指南的主要区别在于,我的数据是257x257灰度图像。以下代码:

    TRAIN_FOLDER = 'data/OIRDS_gray/'
    EPOCHS = 10
    SHAPE = (257,257,1)
    
    FILELIST = os.listdir(TRAIN_FOLDER)
    
    def loadTrainData():
        train_data = []
        for fn in FILELIST:
            img = misc.imread(TRAIN_FOLDER + fn)
            img = np.reshape(img,(len(img[0,:]), len(img[:,0]), SHAPE[2]))
            if img.shape != SHAPE:
                print "image shape mismatch!"
                print "Expected: " 
                print SHAPE 
                print "but got:"
                print img.shape
                sys.exit()
            train_data.append (img)
        train_data = np.array(train_data)
        train_data = train_data.astype('float32')/ 255
    
        return np.array(train_data)
    
    def createModel():
        input_img = Input(shape=SHAPE)
        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)
        return Model(input_img, decoded)
    
    
    x_train = loadTrainData()
    autoencoder = createModel()
    autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
    
    print x_train.shape
    autoencoder.summary()
    
    # Run the network
    autoencoder.fit(x_train, x_train,
                    epochs=EPOCHS,
                    batch_size=128,
                    shuffle=True)
    

    ValueError: Error when checking target: expected conv2d_7 to have shape (None, 260, 260, 1) but got array with shape (859, 257, 257, 1)

    正如您所看到的,这不是no/tensorflow后端dim排序的标准问题,而是其他问题。我检查了我的数据是否符合要求 print x_train.shape

    (859, 257, 257, 1)
    

    我也跑步 autoencoder.summary() :

    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    input_1 (InputLayer)         (None, 257, 257, 1)       0
    _________________________________________________________________
    conv2d_1 (Conv2D)            (None, 257, 257, 16)      160
    _________________________________________________________________
    max_pooling2d_1 (MaxPooling2 (None, 129, 129, 16)      0
    _________________________________________________________________
    conv2d_2 (Conv2D)            (None, 129, 129, 8)       1160
    _________________________________________________________________
    max_pooling2d_2 (MaxPooling2 (None, 65, 65, 8)         0
    _________________________________________________________________
    conv2d_3 (Conv2D)            (None, 65, 65, 8)         584
    _________________________________________________________________
    max_pooling2d_3 (MaxPooling2 (None, 33, 33, 8)         0
    _________________________________________________________________
    conv2d_4 (Conv2D)            (None, 33, 33, 8)         584
    _________________________________________________________________
    up_sampling2d_1 (UpSampling2 (None, 66, 66, 8)         0
    _________________________________________________________________
    conv2d_5 (Conv2D)            (None, 66, 66, 8)         584
    _________________________________________________________________
    up_sampling2d_2 (UpSampling2 (None, 132, 132, 8)       0
    _________________________________________________________________
    conv2d_6 (Conv2D)            (None, 132, 132, 16)      1168
    _________________________________________________________________
    up_sampling2d_3 (UpSampling2 (None, 264, 264, 16)      0
    _________________________________________________________________
    conv2d_7 (Conv2D)            (None, 264, 264, 1)       145
    =================================================================
    Total params: 4,385
    Trainable params: 4,385
    Non-trainable params: 0
    _________________________________________________________________
    

    (None, 258, 258, 1) . 我是通过在反褶积侧盲目尝试不同的填充组合来实现这一点的,这并不是解决问题的明智方法。。。

    在这一点上,我不知所措,任何帮助都将不胜感激

    1 回复  |  直到 7 年前
        1
  •  1
  •   Daniel Möller    7 年前

    由于输入和输出数据相同,因此最终输出形状应与输入形状相同。

    (None, 257,257,1) .

    出现这个问题是因为图像的大小是奇数(257)。

    MaxPooling ,它应该将这个数字除以2,所以它选择向上或向下取整(向上,见129,来自257/2=128.5)

    以后,当你这样做的时候 UpSampling ,模型不知道当前维度已舍入,它只是将值加倍。按顺序进行的操作将为最终结果添加7个像素。

    您可以尝试裁剪结果或填充输入。

    层,您的大小应该是2的倍数。答案是264。


    直接填充输入数据:

    x_train = numpy.lib.pad(x_train,((0,0),(3,4),(3,4),(0,0)),mode='constant')
    

    SHAPE=(264,264,1)

    模型内部填充:

    import keras.backend as K
    
    input_img = Input(shape=SHAPE)
    x = Lambda(lambda x: K.spatial_2d_padding(x, padding=((3, 4), (3, 4))), output_shape=(264,264,1))(input_img)
    

    裁剪结果:

    decoded = Lambda(lambda x: x[:,3:-4,3:-4,:], output_shape=SHAPE)(x)