代码之家  ›  专栏  ›  技术社区  ›  Vikas NS

使用lstm的助记生成如何确保我的模型使用loss函数生成有意义的句子?[关闭]

  •  -2
  • Vikas NS  · 技术社区  · 6 年前

    我在做一个能产生记忆的项目。我的模型有问题。

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

    项目目标

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

    数据集

    im使用kaggles 55000+歌曲歌词数据,这些歌词中的句子包含5到10个单词,我想生成的助记符也包含相同数量的单词。

    输入/输出预处理。

    在去掉标点符号和数字,从一个句子中的每个单词中提取前两个字母,并从一个预定义的字典中为这两个字母指定一个唯一的数字(其中包含一对键、一个键和一个唯一的数字作为值)之后,我将遍历所有的句子。 作为输入时指定的这些唯一数字的列表,这些单词的手套向量将作为输出。在每个时间步骤中,lstm模型都将获取分配给这些单词的唯一数字,并输出相应单词的手套向量。

    enter image description here

    模型体系结构

    我在用10个时间步的LSTM。 在每一个时间步,与一对字母相关联的唯一数字将被输入,输出将是相应单词的手套向量。

    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'])
    

    结果:

    我的模型是输出与输入中每个单词的前两个字母相匹配的助记符。但是,所产生的助记符没有什么意义。 我意识到这个问题是由我的训练方式引起的。从单词中提取字母的顺序已经准备好形成句子了。但这在测试时是不一样的。我输入单词的字母摘录的顺序可能不太可能构成句子。 因此,我为我的数据构建了一个bigram,并将具有最高造句概率的排列输入到我的记忆生成器模型中。虽然有一些改进,但整个句子没有任何意义。 我被困在这一点上。

    输入

    Input

    输出

    Output

    我的问题是,

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

    1 回复  |  直到 6 年前
        1
  •  2
  •   modesitt    6 年前

    首先,我有一些不相关的建议。我不认为你应该输出每个单词的手套向量。为什么?word2vec方法旨在封装word 意义 可能不包含拼写信息。然而,这个意义也有助于产生 有意义的 句子。因此,我会让lstm在阅读每个单词的前两个字母后产生它自己的隐藏状态(就像您现在所做的那样)。然后我会把这个序列展开成序列 第一维度 (索引到单词映射的索引中)。然后,我将获取该输出,通过一个嵌入层处理它,该嵌入层将单词索引映射到它们的手套嵌入,然后我将通过另一个输出lstm运行该输出以生成更多索引。你可以根据自己的需要来堆叠它-但是2到3层可能就足够了。

    即使有了这些变化,你也不太可能在生成容易记住的句子方面看到任何成功。对于这个主要问题,我认为通常有两种方法。第一个是增加你的损失,让你感觉到结果句子是一个“有效的英语句子”。通过对输出句子进行词性标记,并添加与是否遵循标准句子结构(主谓副词直接宾语等)相关的损失,可以在程序上实现一定的准确性。尽管这个结果可能比下面的选择更容易,但它可能不会产生实际的自然结果。

    我建议,除了以当前的方式训练您的模型之外,使用gan来判断输出语句是否是自然语句。有很多资源 Keras GANs ,所以我认为您不需要在这个答案中使用特定的代码。但是,这里有一个模型应该如何进行逻辑训练的概要:

    1. 用两个额外的阶段来增加你当前的训练。
      • 首先训练鉴别器判断输出语句是否自然。你可以通过让lstm模型读取句子,并给出一个sigmoid输出(0/1)来判断它们是否“自然”。然后,您可以在一些带有1个标签的真实句子数据集和大约50/50分割的带有0个标签的句子数据集上训练此模型。
      • 然后,除了用于实际生成助记符的current loss函数外,添加loss,即生成的句子的二元交叉熵分数。 带1(真) 标签。进行此操作时,请确保明显冻结鉴别器模型。

    继续重复这两个步骤(每次训练一个历元),直到开始看到更合理的结果。为了在一个正确的记忆法和一个容易记住的句子之间取得正确的平衡,你可能需要计算生成器(你的模型)中每个损失项的权重。