所以我一直在研究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
的任何花费。
答案 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
我建议一种类似于语言翻译模型的方法:
预处理将令牌索引转换为embedding_dims。这可用于生成编码器输入和解码器目标。
后处理以将embedding_dims转换为logits(在vocab_index空间中)。
我需要使编码器层的output_shape为[Latent_size,Vocab_size],同时出于明显的原因,我不想将特征表示为one_hot编码。
听起来不对。通常,使用自动编码器试图实现的目标是为句子提供嵌入向量。因此,编码器的输出通常为[latent_dims]。解码器的输出需要可转换为[sequence_length,vocab_index(1)],通常是通过从嵌入空间转换为logits,然后采用argmax转换为令牌索引来完成的。