Ошибка значения Keras для сверточного автоэкондера - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь создать сверточный автоэнкодер, но у меня возникают проблемы с частью декодера. Мои входные изображения 32 на 32 на 3 (RGB).

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Activation, Dropout

def deep_autoencoder(img_shape, code_size):

    #### encoder ######
    encoder = keras.models.Sequential()
    encoder.add(keras.layers.InputLayer(img_shape))

    encoder.add(Conv2D(32, kernel_size=(3, 3), strides=1,
                 activation='elu', padding ='same' ))
    encoder.add(MaxPooling2D(pool_size=(3, 3), padding = 'same'))

    encoder.add(Conv2D(64, kernel_size=(3, 3), strides=1,
                 activation='elu', padding ='same' ))
    encoder.add(MaxPooling2D(pool_size=(3, 3), padding = 'same'))

    encoder.add(Conv2D(128, kernel_size=(3, 3), strides=1,
                 activation='elu', padding ='same' ))
    encoder.add(MaxPooling2D(pool_size=(3, 3), padding = 'same') )   

    encoder.add(Conv2D(256, kernel_size=(3, 3), strides=1,
                 activation='elu', padding ='same' ))

    encoder.add(Flatten())
    encoder.add(Dense(code_size, activation='relu'))


    ##### decoder#####
    decoder = keras.models.Sequential()
    decoder.add(keras.layers.InputLayer((code_size,)))

    decoder.add(Dense(code_size, activation='relu'))
    decoder.add(keras.layers.Reshape([16,16])) #???

    decoder.add(keras.layers.Conv2DTranspose(filters=128, kernel_size=(3, 3), strides=2, activation='elu', padding='same'))
    decoder.add(keras.layers.Conv2DTranspose(filters=64, kernel_size=(3, 3), strides=2, activation='elu', padding='same'))
    decoder.add(keras.layers.Conv2DTranspose(filters=32, kernel_size=(3, 3), strides=2, activation='elu', padding='same'))
    decoder.add(keras.layers.Conv2DTranspose(filters=3, kernel_size=(3, 3), strides=2, padding='same'))


    return encoder, decoder

Я предполагаю, что мой декодер должен начинаться с 16 * 16, поскольку моя плотная сеть в конце моего кодера имеет 256 узлов. Однако когда я бегу encoder, decoder = deep_autoencoder(IMG_SHAPE, code_size=32) Я получаю ошибку:

---> 34     decoder.add(keras.layers.Reshape([16,16]))
.
.
.
ValueError: total size of new array must be unchanged

Я могу добавить полный код ошибки, если он полезен, но я чувствую, что у меня что-то не так. Чтобы применить деконволюционные фильтры, мне нужно преобразовать сглаженный вывод кодера в матрицу.

Для простоты чтения сети я добавил сводку модели для кодировщика часть - которую я получу, если закомментирую часть декодера и запусту encoder.summary()

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 32, 32, 3)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 32, 32, 32)        896       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 11, 11, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 4, 4, 64)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 4, 4, 128)         73856     
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 2, 2, 128)         0         
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 2, 2, 256)         295168    
_________________________________________________________________
max_pooling2d_4 (MaxPooling2 (None, 1, 1, 256)         0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 256)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 32)                8224      
=================================================================

1 Ответ

0 голосов
/ 27 июня 2018

Что меня беспокоит в вашей модели, так это две вещи: во-первых, асимметрия вашего автоэнкодера. Вы используете слои conv и pool во время кодирования, но не используете слой с повышением частоты (обратный пул). Это уже реализовано в keras как UpSampling2D. Кроме того, вы также должны использовать одинаковые шаги в слоях conv и deconv.

Во-вторых, после объединения в четвертый раз вы получите сжатое представление 1x1x256. Почему вы пытаетесь преобразовать это в 16x16x1 представление для части декодирования? Это также о симметрии. Нет необходимости выравнивать кодированный слой, вы можете просто использовать представление 1x1x256 в качестве входных данных для модели декодирования. Поскольку вы создаете кодер и декодер как отдельные модели, вы можете сложить их следующим образом:

encoder = Sequential()
encoder.add ...
...

decoder = Sequential()
decoder.add(encoder)
decoder.add ...

Также есть учебник по созданию автоэнкодеров, написанный Франсуа Шоле ( LINK ). Это может помочь вам в вашей реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...