Глубокий автоэнкодер в Keras, преобразующий одно измерение в другое i

#python #vector #neural-network #keras #autoencoder

#python #вектор #нейронная сеть #keras #автоэнкодер

Вопрос:

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

Векторы заголовков имеют длину / размерность размера 128. Векторы изображений имеют длину / размерность размера 2048.

Что я хочу сделать, так это обучить автоэнкодер, чтобы получить кодировщик, который способен преобразовывать текстовый вектор в вектор изображения. И декодер, который способен преобразовывать вектор изображения в текстовый вектор.

Кодировщик: 128 -> 2048.

Декодер: 2048 -> 128.

Я следовал этому руководству, чтобы реализовать мелкую сеть, делающую то, что я хотел.

Но я не могу понять, как создать глубокую сеть, следуя тому же руководству.

 x_dim = 128
y_dim = 2048
x_dim_shape = Input(shape=(x_dim,))
encoded = Dense(512, activation='relu')(x_dim_shape)
encoded = Dense(1024, activation='relu')(encoded)
encoded = Dense(y_dim, activation='relu')(encoded)

decoded = Dense(1024, activation='relu')(encoded)
decoded = Dense(512, activation='relu')(decoded)
decoded = Dense(x_dim, activation='sigmoid')(decoded)

# this model maps an input to its reconstruction
autoencoder = Model(input=x_dim_shape, output=decoded)

# this model maps an input to its encoded representation
encoder = Model(input=x_dim_shape, output=encoded)

encoded_input = Input(shape=(y_dim,))
decoder_layer1 = autoencoder.layers[-3]
decoder_layer2 = autoencoder.layers[-2]
decoder_layer3 = autoencoder.layers[-1]

# create the decoder model
decoder = Model(input=encoded_input, output=decoder_layer3(decoder_layer2(decoder_layer1(encoded_input))))

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


autoencoder.fit(training_data_x, training_data_y,
                nb_epoch=50,
                batch_size=256,
                shuffle=True,
                validation_data=(test_data_x, test_data_y))
  

training_data_x и test_data_x имеют 128 измерений.
training_data_y и test_data_y имеют 2048 измерений.

Ошибка, которую я получаю при попытке запустить это, заключается в следующем:

Исключение: ошибка при проверке цели модели: ожидаемый dense_6 должен иметь форму (None, 128), но получен массив с формой (32360, 2048)

dense_6 — последняя декодированная переменная.

Комментарии:

1. Причины, по которым я думаю, что это работает в учебнике, заключаются в том, что они обучают свой автоэнкодер одинаковым измерениям на входе и выходе, в то время как я хочу обучить свой автоэнкодер переходить из одного измерения в другое.

Ответ №1:

Автоэнкодеры

Если вы хотите иметь возможность вызывать encoder и decoder отдельно, то вам нужно обучить весь автоэнкодер точно так, как указано в руководстве, с input_shape == output_shape помощью ( == 128 в вашем случае), и только тогда вы можете вызвать подмножество слоев:

 x_dim = 128
y_dim = 2048
x_dim_shape = Input(shape=(x_dim,))
encoded = Dense(512, activation='relu')(x_dim_shape)
encoded = Dense(1024, activation='relu')(encoded)
encoded = Dense(y_dim, activation='relu')(encoded)

decoded = Dense(1024, activation='relu')(encoded)
decoded = Dense(512, activation='relu')(decoded)
decoded = Dense(x_dim, activation='sigmoid')(decoded)

# this model maps an input to its reconstruction
autoencoder = Model(input=x_dim_shape, output=decoded)
autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
autoencoder.fit(training_data_x, training_data_x, nb_epoch=50, batch_size=256, shuffle=True, validation_data=(test_data_x, test_data_y))

# test the decoder model
encoded_input = Input(shape=(y_dim,))
decoder_layer1 = autoencoder.layers[-3]
decoder_layer2 = autoencoder.layers[-2]
decoder_layer3 = autoencoder.layers[-1]

decoder = Model(input=encoded_input, output=decoder_layer3(decoder_layer2(decoder_layer1(encoded_input))))
decoder.compile(optimizer='adadelta', loss='binary_crossentropy')
eval = decoder.evaluate(test_data_y, test_data_x)
print('Decoder evaluation: {:.2f}'.format(eval))
  

Обратите внимание, что при вызове autoencoder.fit() x == y в аргументах. Вот как автокодер (обычно) должен оптимизировать представление узкого места (которое вы вызываете y в своем собственном коде), чтобы наилучшим образом соответствовать исходному изображению с меньшими размерами.

Но, в качестве перехода ко второй части этого ответа, обратите внимание, что в вашем случае, x_dim < y_dim . На самом деле вы обучаете модель для увеличения размерности данных, что не имеет особого смысла, AFAICT.

Ваша проблема

Теперь, снова читая ваш вопрос, я не думаю, что автоэнкодеры хороши для того, чего вы хотите достичь. Они предназначены для уменьшения размерности данных с минимальными потерями.

То, что вы пытаетесь сделать, это:

  1. Преобразование текста в изображение (то, что вы называете encode )
  2. Считывание текста с изображения (то, что вы называете decode )

В моем понимании, хотя 2. это действительно может потребовать некоторого машинного обучения, 1. определенно нет: существует множество библиотек для написания текста на изображениях.