如何限制 LSTM 模型中的序列预测以匹配特定模式?
How to restrict the sequence prediction in an LSTM model to match a specific pattern?
我使用 LSTM 模型创建了一个词级文本生成器。但就我而言,并不是每个词都适合 selected。我希望它们符合附加条件:
- 每个单词都有一个映射:如果一个字符是元音,那么它会写 1 如果不是,它会写 0(例如,overflow 将是
10100010
).然后,生成的句子需要满足给定的结构,例如01001100
(hi 01
and friend 001100
).
- 最后一个单词的最后一个元音必须是提供的那个。假设是e。 (然后 friend 就可以了)。
因此,为了处理这种情况,我创建了一个具有以下结构的 pandas 数据框:
word last_vowel word_map
----- --------- ----------
hello o 01001
stack a 00100
jhon o 0010
这是我当前的工作流程:
- 给定句子结构,我从数据框中随机选择一个与模式匹配的词。比如句子结构是
0100100100100
,我们可以选择hello,因为它的元音结构是01001
.
- 我从剩余结构中减去 selected 词:
0100100100100
将变为 00100100
因为我们已经删除了初始 01001
(你好).
- 我从数据框中检索了与剩余结构的一部分匹配的所有单词,在这种情况下,stack
00100
和 jhon 0010
.
- 我把当前单词的句子内容(现在只是hello)传给LSTM模型,它会检索每个单词的权重。
- 但我不只是想要select最佳选项,我想要select包含在第3点selection中的最佳选项。所以我选择了在该列表中具有最高估计的单词,在本例中,stack.
- 从第 2 点开始重复,直到剩余的句子结构为空。
这很有效,但还有一个条件需要处理:句子的最后一个元音。
我处理这个问题的方法如下:
- 生成 1000 个句子,强制指定最后一个元音。
- 获取LSTM模型返回的权重的rmse。输出越好,权重就越高。
- 选择检索排名较高的句子。
您认为有更好的方法吗?也许是 GAN 或强化学习?
编辑:我认为另一种方法是添加 WFST。我听说过 pynini library,但我不知道如何将它应用到我的特定环境中。
如果您对自己的方法感到满意,最简单的方法可能是您能够在反向序列上训练 LSTM 以训练它给出前一个单词的权重,而不是下一个单词.在这种情况下,您可以使用您已经采用的方法,除了单词的第一个子集将满足最后一个元音约束。我不相信这一定能产生最好的结果。
现在,如果这种逆转是不可能的,或者如果在进一步阅读我的回答后,你发现这没有找到最好的解决方案,那么我建议使用寻路算法,类似于强化学习,但不是统计因为训练有素的 LSTM 计算的权重是确定性的。您目前使用的本质上是下面第一个选项中的 depth first greedy search which, depending on the LSTM output, might be even optimal. Say if LSTM is giving you a guaranteed monotonous increase in the sum which doesn't vary much between the acceptable consequent words (as the difference between N-1 and N sequence is much larger than the difference between the different options of the Nth word). In the general case, when there is no clear heuristic to help you, you will have to perform an exhaustive search. If you can come up with an admissible heuristic, you can use A* instead of Dijkstra's 算法,它执行得越快,您的启发式算法就越好。
我想这很清楚,但为了以防万一,您的图形连通性由您的约束序列定义。初始节点(没有单词的 0 长度序列)与数据框中与约束序列开头匹配的任何单词相连。因此,您没有将图形作为数据结构,只是将压缩描述作为此约束。
编辑
根据评论中的要求,这里有更多详细信息。不过,这里有几个选项:
多次应用 Dijkstra 算法。 Dijkstra 的搜索找到 2 个已知节点之间的最短路径,而在您的情况下,我们只有初始节点(没有单词的 0 长度序列)并且最终单词未知。
- 找到所有可接受的最后单词(那些同时满足模式和元音约束的单词)。
- 对其中的每一个应用 Dijkstra 搜索,为每一个找到最大的单词序列权重和。
- Dijkstra 算法专为搜索最短路径而设计,因此要直接应用它,您必须对每一步的权重取反并选择尚未访问过的最小权重。
- 找到所有解决方案(以您最初确定的最后一个单词之一结尾的句子)后,select最小的解决方案(这将是所有解决方案中权重和最大的)。
修改现有的深度优先搜索以进行穷举搜索。
- 按照你在OP中的描述执行搜索操作,如果最后一步给出一个解决方案(如果最后一个元音正确的单词完全可用),记录权重
- 回滚到前一个单词并在前一个单词中选择第二好的选项。如果根本没有解决方案,您可以丢弃上一步中所有相同长度的单词。如果有解决方案,则取决于您的 LSTM 是否根据前一个词提供不同的权重。很可能是这样,在这种情况下,您必须对上一步中的所有单词执行该操作。
- 当您 运行 超出上一步的单词时,向上移动一步并从那里重新开始。
- 你一直保留当前的获胜者以及每一步的未访问节点列表并执行穷举搜索。最终,你会找到最好的解决方案。
我会在这里拿 Beam Search。
这很像您当前随机开始 1000 个解决方案的方法。但是它不是独立地扩展这些路径中的每一个,而是以逐步的方式一起扩展所有候选解决方案。
坚持当前的候选人数 1000,它看起来像这样:
- 生成 1000 个存根解决方案,例如使用随机起点或从某些 "sentence start" 模型中选择。
- 对于每个候选者,根据您的 LSTM 语言模型计算符合约束条件的最佳扩展。这与您当前的方法一样有效,但您也可以尝试多个选项。例如,使用下一个词的最佳 5 个选择将产生 5000 个子候选者。
- 计算每个候选部分解决方案的分数,然后通过仅保留得分最高的选项减少到 1000 个候选方案。
- 重复第 2 步和第 3 步,直到所有候选字母都包含完整的元音序列,包括结尾限制。
- 取这 1000 个解决方案中得分最高的一个。
您可以使用候选评分来权衡已完成或较长的解决方案与非常好但较短的解决方案。
我使用 LSTM 模型创建了一个词级文本生成器。但就我而言,并不是每个词都适合 selected。我希望它们符合附加条件:
- 每个单词都有一个映射:如果一个字符是元音,那么它会写 1 如果不是,它会写 0(例如,overflow 将是
10100010
).然后,生成的句子需要满足给定的结构,例如01001100
(hi01
and friend001100
). - 最后一个单词的最后一个元音必须是提供的那个。假设是e。 (然后 friend 就可以了)。
因此,为了处理这种情况,我创建了一个具有以下结构的 pandas 数据框:
word last_vowel word_map
----- --------- ----------
hello o 01001
stack a 00100
jhon o 0010
这是我当前的工作流程:
- 给定句子结构,我从数据框中随机选择一个与模式匹配的词。比如句子结构是
0100100100100
,我们可以选择hello,因为它的元音结构是01001
. - 我从剩余结构中减去 selected 词:
0100100100100
将变为00100100
因为我们已经删除了初始01001
(你好). - 我从数据框中检索了与剩余结构的一部分匹配的所有单词,在这种情况下,stack
00100
和 jhon0010
. - 我把当前单词的句子内容(现在只是hello)传给LSTM模型,它会检索每个单词的权重。
- 但我不只是想要select最佳选项,我想要select包含在第3点selection中的最佳选项。所以我选择了在该列表中具有最高估计的单词,在本例中,stack.
- 从第 2 点开始重复,直到剩余的句子结构为空。
这很有效,但还有一个条件需要处理:句子的最后一个元音。
我处理这个问题的方法如下:
- 生成 1000 个句子,强制指定最后一个元音。
- 获取LSTM模型返回的权重的rmse。输出越好,权重就越高。
- 选择检索排名较高的句子。
您认为有更好的方法吗?也许是 GAN 或强化学习?
编辑:我认为另一种方法是添加 WFST。我听说过 pynini library,但我不知道如何将它应用到我的特定环境中。
如果您对自己的方法感到满意,最简单的方法可能是您能够在反向序列上训练 LSTM 以训练它给出前一个单词的权重,而不是下一个单词.在这种情况下,您可以使用您已经采用的方法,除了单词的第一个子集将满足最后一个元音约束。我不相信这一定能产生最好的结果。
现在,如果这种逆转是不可能的,或者如果在进一步阅读我的回答后,你发现这没有找到最好的解决方案,那么我建议使用寻路算法,类似于强化学习,但不是统计因为训练有素的 LSTM 计算的权重是确定性的。您目前使用的本质上是下面第一个选项中的 depth first greedy search which, depending on the LSTM output, might be even optimal. Say if LSTM is giving you a guaranteed monotonous increase in the sum which doesn't vary much between the acceptable consequent words (as the difference between N-1 and N sequence is much larger than the difference between the different options of the Nth word). In the general case, when there is no clear heuristic to help you, you will have to perform an exhaustive search. If you can come up with an admissible heuristic, you can use A* instead of Dijkstra's 算法,它执行得越快,您的启发式算法就越好。
我想这很清楚,但为了以防万一,您的图形连通性由您的约束序列定义。初始节点(没有单词的 0 长度序列)与数据框中与约束序列开头匹配的任何单词相连。因此,您没有将图形作为数据结构,只是将压缩描述作为此约束。
编辑 根据评论中的要求,这里有更多详细信息。不过,这里有几个选项:
多次应用 Dijkstra 算法。 Dijkstra 的搜索找到 2 个已知节点之间的最短路径,而在您的情况下,我们只有初始节点(没有单词的 0 长度序列)并且最终单词未知。
- 找到所有可接受的最后单词(那些同时满足模式和元音约束的单词)。
- 对其中的每一个应用 Dijkstra 搜索,为每一个找到最大的单词序列权重和。
- Dijkstra 算法专为搜索最短路径而设计,因此要直接应用它,您必须对每一步的权重取反并选择尚未访问过的最小权重。
- 找到所有解决方案(以您最初确定的最后一个单词之一结尾的句子)后,select最小的解决方案(这将是所有解决方案中权重和最大的)。
修改现有的深度优先搜索以进行穷举搜索。
- 按照你在OP中的描述执行搜索操作,如果最后一步给出一个解决方案(如果最后一个元音正确的单词完全可用),记录权重
- 回滚到前一个单词并在前一个单词中选择第二好的选项。如果根本没有解决方案,您可以丢弃上一步中所有相同长度的单词。如果有解决方案,则取决于您的 LSTM 是否根据前一个词提供不同的权重。很可能是这样,在这种情况下,您必须对上一步中的所有单词执行该操作。
- 当您 运行 超出上一步的单词时,向上移动一步并从那里重新开始。
- 你一直保留当前的获胜者以及每一步的未访问节点列表并执行穷举搜索。最终,你会找到最好的解决方案。
我会在这里拿 Beam Search。
这很像您当前随机开始 1000 个解决方案的方法。但是它不是独立地扩展这些路径中的每一个,而是以逐步的方式一起扩展所有候选解决方案。
坚持当前的候选人数 1000,它看起来像这样:
- 生成 1000 个存根解决方案,例如使用随机起点或从某些 "sentence start" 模型中选择。
- 对于每个候选者,根据您的 LSTM 语言模型计算符合约束条件的最佳扩展。这与您当前的方法一样有效,但您也可以尝试多个选项。例如,使用下一个词的最佳 5 个选择将产生 5000 个子候选者。
- 计算每个候选部分解决方案的分数,然后通过仅保留得分最高的选项减少到 1000 个候选方案。
- 重复第 2 步和第 3 步,直到所有候选字母都包含完整的元音序列,包括结尾限制。
- 取这 1000 个解决方案中得分最高的一个。
您可以使用候选评分来权衡已完成或较长的解决方案与非常好但较短的解决方案。