Керас: Укажите правильную форму вывода (для сверточного автоэнкодера) - PullRequest
0 голосов
/ 12 сентября 2018

В Керасе у меня модель

input_img = Input(shape=(150, 360, 3))

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)

# at this point the representation is autoencoder.layers[6].output_shape = (None, 19, 45, 8)

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

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

Окончательная форма

autoencoder.layers[13].output_shape
(None, 152, 360, 3)

Это неудивительно из-за настройки слоев и того факта, что я могу использовать только целые числа для размера слоев MaxPooling2D и UpSampling2D. Но как я могу справиться с этим?

Как мне вернуться к форме (150, 360, 3)?

1 Ответ

0 голосов
/ 12 сентября 2018

Проблема в том, что измерение высоты (150) не делится на 8.

РЕШЕНИЕ 1 : Возможно, это не лучшее решение, но вы можете добавить Срез Cropping2D после последнего слоя UpSampling2D:

x = UpSampling2D((2, 2))(x)
x = Cropping2D(cropping=(1, 0))(x)
decoded = Conv2D(3, (3, 3), activation='sigmoid', padding='same')(x)

Используя эту операцию, вы в основном указываете модели игнорировать первые и последние строки последнего вывода UpSampling2D.

РЕШЕНИЕ 2 : Вы также можете использовать ZeroPadding2D для ввода изображения, чтобы оно имело высоту 152:

input_img = Input(shape=(150, 360, 3))
x = ZeroPadding2D(padding=(1, 0))(input_img)
x = Conv2D(16, (3, 3), activation='relu', padding='same')(x)

Таким образом, измерение высоты делится на 8.

...