5

我使用 LSTM 模型创建了一个词级文本生成器。但就我而言,并不是每个词都适合选择。我希望他们匹配附加条件:

  1. 每个单词都有一个映射:如果一个字符是元音,那么它会写 1,如果不是,它将写 0(例如,溢出将是10100010)。然后,生成的句子需要满足给定的结构,例如01001100hi 01 andfriend 001100
  2. 最后一个单词的最后一个元音必须是提供的那个。假设是e。(那么,朋友会这项工作)。

因此,为了处理这种情况,我创建了一个具有以下结构的 pandas 数据框:

word    last_vowel  word_map
-----   ---------   ----------
hello   o           01001
stack   a           00100
jhon    o           0010

这是我目前的工作流程:

  1. 给定句子结构,我从与模式匹配的数据框中选择一个随机词。例如,如果句子结构是0100100100100,我们可以选择单词hello,因为它的元音结构是01001
  2. 我从剩余的结构中减去选定的单词:0100100100100将成为00100100我们删除了初始的01001你好)。
  3. 我从数据框中检索与剩余结构的一部分匹配的所有单词,在本例中为stack 00100jhon 0010
  4. 我将当前单词的句子内容(现在只是你好)传递给 LSTM 模型,它会检索每个单词的权重。
  5. 但我不只是想选择最佳选项,我想选择第 3 点选择中包含的最佳选项。所以我选择了该列表中估计值最高的单词,在本例中为stack
  6. 从第 2 点开始重复,直到剩下的句子结构为空。

这就像一个魅力,但还有一个条件需要处理:句子的最后一个元音。

我处理这个问题的方法如下:

  1. 生成 1000 个句子,强制最后一个元音是指定的。
  2. 获取 LSTM 模型返回的权重的 rmse。输出越好,权重就越高。
  3. 选择检索到较高排名的句子。

你认为有更好的方法吗?也许是 GAN 或强化学习?

编辑:我认为另一种方法是添加 WFST。我听说过pynini library,但我不知道如何将它应用到我的特定上下文中。

4

2 回答 2

2

如果您对自己的方法感到满意,最简单的方法可能是您能够在反向序列上训练 LSTM,以便训练它来赋予前一个单词的权重,而不是下一个单词的权重。在这种情况下,您可以使用您已经采用的方法,除了单词的第一个子集将满足最后一个元音约束。我不相信这可以保证产生最好的结果。

现在,如果这种逆转是不可能的,或者如果在进一步阅读我的答案后,您发现这没有找到最佳解决方案,那么我建议使用类似于强化学习的寻路算法,但不是统计的,因为权重由训练的 LSTM 是确定性的。您目前使用的本质上是深度优先 贪婪搜索根据 LSTM 的输出,这可能是最优的。假设 LSTM 是否保证总和的单调增加,在可接受的后续词之间变化不大(因为 N-1 和 N 序列之间的差异远大于第 N 个单词的不同选项之间的差异) . 在一般情况下,当没有明确的启发式方法可以帮助您时,您将不得不执行详尽的搜索。如果你能想出一个可接受的启发式算法,你可以在下面的第一个选项中使用A*代替Dijkstra算法,它会做得越快,你的启发式算法就越好。

我想这很清楚,但以防万一,您的图形连接性由您的约束序列定义。初始节点(没有单词的 0 长度序列)与数据框中与约束序列开头匹配的任何单词相连。因此,您没有将图形作为数据结构,只是将压缩描述作为此约束。

编辑 根据评论中的要求,这里有更多详细信息。不过,这里有几个选项:

  1. 多次应用 Dijkstra 算法。Dijkstra 的搜索找到了 2 个已知节点之间的最短路径,而在您的情况下,我们只有初始节点(没有单词的 0 长度序列)并且最终单词是未知的。

    • 找到所有可接受的最后单词(那些同时满足模式和元音约束的单词)。
    • 对其中的每一个应用 Dijkstra 的搜索,找到每个的最大单词序列权重和。
    • Dijkstra 的算法是为搜索最短路径量身定制的,因此要直接应用它,您必须对每一步的权重求反,并选择尚未访问过的最小路径。
    • 在找到所有解决方案(以您最初确定的最后一个单词结尾的句子)后,选择最小的解决方案(这将是所有解决方案中最大的权重总和)。
  2. 修改现有的深度优先搜索以进行详尽的搜索。

    • 执行你在OP中描述的搜索操作,如果最后一步给出了一个解决方案(如果最后一个带有正确元音的单词完全可用),记录权重
    • 回滚到上一个单词,并在之前的单词中选择第二好的选项。如果根本没有解决方案,您也许可以在上一步中丢弃所有相同长度的单词。如果有解决方案,则取决于您的 LSTM 是否根据前一个单词提供不同的权重。很可能确实如此,在这种情况下,您必须对上一步中的所有单词执行该操作。
    • 当你上一步的单词用完时,向上移动一步,然后从那里重新开始。
    • 您始终保留当前的获胜者以及每一步的未访问节点列表,并执行详尽的搜索。最终,您将找到最佳解决方案。
于 2020-04-10T05:00:09.713 回答
0

我会在这里进行Beam Search

这很像您当前随机启动 1000 个解决方案的方法。但是,它不是独立扩展这些路径中的每一个,而是逐步扩展所有候选解决方案。

坚持当前的候选人数 1000,它看起来像这样:

  1. 生成 1000 个存根解决方案,例如使用随机起点或从某些“句子开头”模型中选择。
  2. 对于每个候选者,根据您的 LSTM 语言模型计算适合约束的最佳扩展。这与您当前的方法一样有效,但您也可以尝试多个选项。例如,对下一个词使用最佳 5 个选项将产生 5000 个子候选者。
  3. 计算每个候选部分解决方案的分数,然后通过仅保留最佳评分选项将候选解决方案减少到 1000 个。
  4. 重复第 2 步和第 3 步,直到所有候选项都覆盖完整的元音序列,包括结束约束。
  5. 从这 1000 个解决方案中取最好的分数。

您可以使用候选人评分来权衡已完成或较长的解决方案与非常好的但短期的解决方案。

于 2020-04-11T23:16:26.307 回答