使用LSTM的助记符生成|如何确保我的模型使用损失函数生成有意义的句子?

时间:2018-07-16 13:58:09

标签: machine-learning keras nlp deep-learning

我正在研究生成助记符的项目。我的模型有问题。

我的问题是,如何确保我的模型使用损失函数生成有意义的句子?

项目目标

为单词列表生成助记符。给定用户想要记住的单词列表,该模型将输出一个有意义,简单且易于记住的句子,该句子将用户想要记住的单词的前两个字母封装在要生成的助记符单词中。我的模型将只接收用户想要记住的单词的前两个字母,因为它包含了要生成助记符的所有信息。 enter image description here

数据集

我正在使用Kaggle的55000+首歌曲歌词数据,这些歌词中的句子包含5至10个单词,而我想生成的助记符也包含相同数量的单词。

输入/输出预处理。

我在删除标点符号和数字并从句子中每个单词中提取前2个字母并为预定义词典中的这对字母分配一个唯一的数字(包括一对键和一个唯一键)后,遍历所有句子数字作为值。 这些唯一数字的列表在用作输入时分配,而这些单词的手套向量将作为输出。在每个时间步,LSTM模型都会将这些唯一的数字分配给这些单词,并输出相应单词的GloVe向量。

enter image description here

模型架构

我正在使用具有10个时间步长的LSTM。 在每个时间步,将输入与字母对相关的唯一数字,输出将是相应单词的GloVe向量。

enter image description here

optimizer=rmsprop(lr=0.0008)
model=Sequential()
model.add(Embedding(input_dim=733,output_dim=40,input_length=12))
model.add(Bidirectional(LSTM(250,return_sequences=True,activation='relu'),merge_mode='concat'))
Dropout(0.4)

model.add(Bidirectional(LSTM(350,return_sequences=True,activation='relu'),merge_mode='concat'))
Dropout(0.4)
model.add(TimeDistributed(Dense(332, activation='tanh')))
model.compile(loss='cosine_proximity',optimizer=optimizer,metrics=['acc'])

结果:

我的模型输出的助记符与输入中每个单词的前两个字母匹配。但是生成的助记符几乎没有意义。 我已经意识到这个问题是由于我的训练方式引起的。从单词中提取字母的顺序已经准备好形成句子。但这在进行测试时是不同的。我输入单词的字母摘录的顺序可能不会很容易形成句子。 因此,我为我的数据构建了一个二元组,并将具有最高句子形成概率的排列输入到了助记符生成器模型中。尽管有一些改进,但整个句子没有任何意义。 我现在被困住了。

输入

Input

输出

Output

我的问题是,

如何确保我的模型产生有意义的句子?使用损失函数

1 个答案:

答案 0 :(得分:2)

首先,我有几个不相关的建议。我认为您不应该输出每个单词的GLoVe向量。为什么? Word2Vec方法旨在封装单词含义,并且可能不包含有关其拼写的信息。但是,含义也有助于产生有意义的句子。因此,我将让LSTM在读取每个单词的前两个字母后产生它自己的隐藏状态(就像您当前所做的那样)。然后,我将把这个序列(如您目前所做的那样)展开为一维的序列(索引到单词映射的索引)。然后,我将获取该输出,并通过将单词索引映射到其GLoVe嵌入的嵌入层进行处理,然后通过另一个输出LSTM运行该输出以生成更多索引。您可以根据需要随意堆叠-但是2或3个级别可能就足够了。

即使进行了这些更改,您也不太可能在生成易于记忆的句子方面取得任何成功。对于该主要问题,我认为通常可以采用两种方法。第一种是在某种程度上增加您的损失,即所得到的句子是“有效的英语句子”。您可以通过POS标记输出语句并相对于其是否遵循标准语句结构(主题谓词副词直接宾语)相对增加损失,以编程方式以某种精度实现此目的。尽管此结果可能比以下替代方法容易,但它可能不会产生实际的自然结果。

除了以当前的方式训练模型外,我建议使用GAN来判断输出句子是否为自然句子。 Keras GANs的资源很多,因此我认为您在此答案中不需要特定的代码。但是,以下是模型应如何进行逻辑训练的概述:

  1. 通过另外两个阶段来扩展当前的培训。
    • 首先训练判别器,以判断输出句子是否自然。您可以通过使LSTM模型读取句子并为它们是否“自然”提供S形输出(0/1)来实现此目的。然后,您可以在带有1个标签的真实句子和带有0个标签的句子的某些数据集上以大约50/50的比例训练该模型。
    • 然后,除了用于实际生成助记符的当前损失函数外,还要为所产生的句子具有1个(true)标签的二进制交叉熵分数添加损失。在执行此操作时,请确保明显冻结区分器模型。

继续重复执行这两个步骤(每次训练一次1个时期),直到您开始看到更合理的结果为止。您可能需要计算生成器(您的模型)中每个损失项的权重,以便在正确的助记符和易于记忆的句子之间进行正确的权衡。