如何在整个单词的预测中拥有LSTM自动编码器模型,同时以嵌入方式展示单词

时间:2019-07-08 15:27:03

标签: tensorflow keras lstm autoencoder seq2seq

所以我一直在研究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])
  1. 在第二种情况下,我在模型本身中实现了单词嵌入层:

这是结构:

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)
  1. 在第三种情况下,我没有使用任何嵌入技术,而是使用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 个答案:

答案 0 :(得分:1)

您的问题:

  

是否可以用我嵌入的方式来更改模型的结构,以便将单词表示给模型,同时在解码器层中具有vocab_size?

我喜欢将Tensorflow变压器模型用作参考: https://github.com/tensorflow/models/tree/master/official/transformer

在语言翻译任务中,模型输入往往是令牌索引,然后对其进行嵌入查找,导致形状为(sequence_length,embedding_dims);编码器本身可以在此形状上工作。 解码器输出也趋向于也是(sequence_length,embedding_dims)的形状。例如上述模型,然后通过在输出和嵌入矢量之间进行点积运算,将解码器输出转换为logit。这是他们使用的转换:https://github.com/tensorflow/models/blob/master/official/transformer/model/embedding_layer.py#L94

我建议一种类似于语言翻译模型的方法:

  • 前阶段:
    • input_shape =(sequence_length,1)[即[0 .. vocab_size中的token_index)
  • 编码器:
    • input_shape =(sequence_length,embedding_dims)
    • output_shape =(潜伏数)
  • 解码器:
    • 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)],通常是通过从嵌入空间转换为logits,然后采用argmax转换为令牌索引来完成的。