как использовать модель автоэккодера LSTM для прогнозирования всего вокаба, представляя слова как встраиваемые - PullRequest
0 голосов
/ 08 июля 2019

Итак, я работал над LSTM Autoencoder model.Я также создал различные версии этой модели.

1. создайте модель, используя уже обученное вложение слов: в этом сценарии я использовал веса уже обученного вектора Перчаток в качествемасса функций (текстовые данные).Это структура:

inputs = Input(shape=(SEQUENCE_LEN, EMBED_SIZE), name="input")
    encoded = Bidirectional(LSTM(LATENT_SIZE), merge_mode="sum", name="encoder_lstm")(inputs)
    encoded =Lambda(rev_entropy)(encoded)
    decoded = RepeatVector(SEQUENCE_LEN, name="repeater")(encoded)
    decoded = Bidirectional(LSTM(EMBED_SIZE, return_sequences=True), merge_mode="sum", name="decoder_lstm")(decoded)
    autoencoder = Model(inputs, decoded)
    autoencoder.compile(optimizer="sgd", loss='mse')
    autoencoder.summary()
    checkpoint = ModelCheckpoint(filepath='checkpoint/{epoch}.hdf5')
    history = autoencoder.fit_generator(train_gen, steps_per_epoch=num_train_steps, epochs=NUM_EPOCHS, validation_data=test_gen, validation_steps=num_test_steps, callbacks=[checkpoint])
во втором сценарии я внедрил слой встраивания слов в саму модель:

Это структура:

inputs = Input(shape=(SEQUENCE_LEN, ), name="input")
embedding = Embedding(input_dim=VOCAB_SIZE, output_dim=EMBED_SIZE, input_length=SEQUENCE_LEN,trainable=False)(inputs)
encoded = Bidirectional(LSTM(LATENT_SIZE), merge_mode="sum", name="encoder_lstm")(embedding)
decoded = RepeatVector(SEQUENCE_LEN, name="repeater")(encoded)
decoded = LSTM(EMBED_SIZE, return_sequences=True)(decoded)
autoencoder = Model(inputs, decoded)
autoencoder.compile(optimizer="sgd", loss='categorical_crossentropy')
autoencoder.summary()   
checkpoint = ModelCheckpoint(filepath=os.path.join('Data/', "simple_ae_to_compare"))
history = autoencoder.fit_generator(train_gen, steps_per_epoch=num_train_steps, epochs=NUM_EPOCHS,  validation_steps=num_test_steps)

в третьем сценарии я не использовал никаких методов встраивания, но использовал one hot encoding для функций.и это структура модели:

`inputs = Input(shape=(SEQUENCE_LEN, VOCAB_SIZE), name="input")
encoded = Bidirectional(LSTM(LATENT_SIZE, kernel_initializer="glorot_normal",), merge_mode="sum", name="encoder_lstm")(inputs)
encoded = Lambda(score_cooccurance,  name='Modified_layer')(encoded)
decoded = RepeatVector(SEQUENCE_LEN, name="repeater")(encoded)
decoded = LSTM(VOCAB_SIZE, return_sequences=True)(decoded)
autoencoder = Model(inputs, decoded)
sgd = optimizers.SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
autoencoder.compile(optimizer=sgd, loss='categorical_crossentropy')
autoencoder.summary()   
checkpoint = ModelCheckpoint(filepath='checkpoint/50/{epoch}.hdf5')
history = autoencoder.fit_generator(train_gen, steps_per_epoch=num_train_steps, epochs=NUM_EPOCHS, callbacks=[checkpoint])`

Как видите, в первой и второй модели Embed_size в decoding - это число нейронов в этом слое.это приводит к тому, что выходная форма слоя кодера становится [Latent_size, Embed_size].

в третьей модели выходная форма кодера равна [Latent_size, Vocab_size].

Теперь мой вопрос

ЕстьМожно ли изменить структуру модели так, как я встраиваю для представления своих слов в модели, и в то же время иметь vocab_size в слое декодера?

Мне нужно иметь output_shapeуровня кодировщика будет [Latent_size, Vocab_size], и в то же время я не хочу представлять свои функции как one_hot encoding по очевидной причине.

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

1 Ответ

1 голос
/ 11 июля 2019

Ваши вопросы:

Можно ли изменить структуру модели так, как я встроил, для представления своих слов в модели, и в то же время, имея vocab_size в слое декодера??

Я хотел бы использовать в качестве эталона модель преобразователя Tensorflow: https://github.com/tensorflow/models/tree/master/official/transformer

В задачах языкового перевода ввод модели, как правило, является индексом токена, который затем подчиняетсяпоиск встраивания, приводящий к форме (sequence_length, embedding_dims);Сам кодировщик работает над этой формой.Выход декодера также имеет тенденцию иметь форму (sequence_length, embedding_dims).Например, модель, приведенная выше, затем преобразует выходные данные декодера в логиты, выполняя точечное произведение между выходными данными и векторами внедрения.Это преобразование, которое они используют: https://github.com/tensorflow/models/blob/master/official/transformer/model/embedding_layer.py#L94

Я бы рекомендовал подход, аналогичный моделям языкового перевода:

  • pre-stage:
    • input_shape = (sequence_length, 1) [то есть token_index в [0 .. vocab_size)
  • кодировщик:
    • input_shape = (sequence_length, embedding_dims)
    • output_shape = (latent_dims)
  • декодер:
    • input_shape = (latent_dims)
    • output_shape = (sequence_length, embedding_dims)

Предварительная обработка преобразует индексы токенов в embedding_dims.Это может использоваться для генерации как входного сигнала кодера, так и целей декодера.

Постобработка для преобразования embedding_dims в logits (в пространстве vocab_index).

Мне нужно иметьoutput_shape слоя кодера будет [Latent_size, Vocab_size], и ​​в то же время я не хочу представлять свои функции как кодировку one_hot по очевидной причине.

Это не звучит правильно.Обычно с помощью автокодера пытаются добиться наличия вектора вложения для предложения.Таким образом, вывод кодера обычно [latent_dims].Выходные данные декодера должны быть переведены в [sequence_length, vocab_index (1)], что обычно делается путем преобразования пространства встраивания в логиты и последующего использования argmax для преобразования в индекс токена.

...