【问题标题】:how to have a LSTM Autoencoder model over the whole vocab prediction while presenting words as embedding如何在整个词汇预测中使用 LSTM Autoencoder 模型,同时将单词表示为嵌入
【发布时间】:2019-07-08 15:27:03
【问题描述】:

所以我一直在研究LSTM Autoencoder model。我还创建了这个模型的各种版本。

1. 使用已经训练好的词嵌入创建模型: 在这种情况下,我使用已经训练好的 Glove 向量的权重,作为特征(文本数据)的权重。 这是结构:

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

【问题讨论】:

    标签: tensorflow keras lstm autoencoder seq2seq


    【解决方案1】:

    您的问题:

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

    我喜欢使用 Tensorflow 转换器模型作为参考: https://github.com/tensorflow/models/tree/master/official/transformer

    在语言翻译任务中,模型输入往往是一个标记索引,然后对其进行嵌入查找,得到 (sequence_length, embedding_dims) 的形状;编码器本身适用于这种形状。 解码器的输出也趋向于 (sequence_length, embedding_dims) 的形状。例如上面的模型,然后通过在输出和嵌入向量之间进行点积,将解码器输出转换为 logits。这是他们使用的转换: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=(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) ],这通常通过从嵌入空间转换为 logits,然后将 argmax 转换为令牌索引来完成。

    【讨论】:

    • 非常感谢您分享这些有用的信息。在您提供的建议中,矩阵的形状仍然是(latent size, embed_size)。如果我遗漏了什么,请告诉我。或者如果你可以的话,请用代码分享你的想法的一个非常简单的版本,我真的很感激。
    • 通常术语“latent_size”应用于编码器生成并由解码器读取的向量的大小。术语“潜在”是指在概率论中这些变量被认为是输出的生成器这一事实。如果我没记错的话,在我的回答中,“latent_dims”显示为向量大小而不是矩阵。
    • 所以,我根本无法拥有这样的网络!我的意思是embed_size在第一层编码器和vocab size在解码器层。
    猜你喜欢
    • 2018-09-04
    • 2016-07-17
    • 2021-04-18
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多