【问题标题】:Keras LSTM for Text Generation keeps repeating a line or a sequence用于文本生成的 Keras LSTM 不断重复一行或一个序列
【发布时间】:2018-04-17 22:53:15
【问题描述】:

我大致遵循了这个教程:

https://machinelearningmastery.com/text-generation-lstm-recurrent-neural-networks-python-keras/

一个显着的区别是我使用了 2 个带 dropout 的 LSTM 层。我的数据集不同(abc 表示法的音乐数据集)。我确实生成了一些歌曲,但是在生成过程中经过一定数量的步骤(可能从 30 步到几百步不等)之后,LSTM 会一遍又一遍地生成完全相同的序列。例如,它曾经陷入为歌曲生成 URL 的难题:

F:http://www.youtube.com/watch?v=JPtqU6pipQI

等等……

它也曾经被困在生成相同的两首歌曲(这两首歌曲是大约 300 个字符的序列)。一开始它产生了 3-4 首好歌曲,但之后,它几乎无限期地不断地再生这两首歌。

我想知道,有人对可能发生的事情有所了解吗?

我想澄清一下,无论是重复还是非重复,生成的任何序列似乎都是新的(模型不记忆)。验证损失和训练损失按预期减少。 Andrej Karpathy 能够生成包含数千个字符的文档,但我找不到这种无限期卡住的模式。

http://karpathy.github.io/2015/05/21/rnn-effectiveness/

【问题讨论】:

  • 尝试使用stateful 模式以连接连续的代。
  • 嗯我试图避免这种情况,但我会尝试的。谢谢你的建议:)
  • 我发现增加构成我的长序列的样本长度(子批次)会产生很大的不同,而不必使用 stateful。一个可能值得尝试的简单修复。
  • @Phil 你能多谈谈你的工作和这个观察吗?应用程序域是什么,您的输入序列前后多长时间?在您增加输入的“回溯”大小之前,您的模型是否生成了相同的输出?我很好奇,因为我现在面临同样的问题。 @MarcinMożejko 您能否详细说明为什么将 stateful 设置为 True 有助于防止模型记住输入并循环返回看到的值?
  • @duhaime 我有一段时间没有接触这个项目了,但我可以凭记忆告诉你。该域是在时间序列的每个步骤中生成多达 16 个参数(为语音生成提供声码器)。也就是说,我认为我最终确实设法调试了有状态使用,但它并没有真正帮助我。有兴趣的项目说明在这里:babble-rnn.consected.com

标签: python deep-learning keras lstm recurrent-neural-network


【解决方案1】:

不要在预测输出中使用 argmax,而是尝试通过以下方式引入一些随机性:

np.argmax(prediction_output)[0])

np.random.choice(len(prediction_output), p=prediction_output)

我在这个重复序列问题上苦苦挣扎了一段时间,直到我发现了这个 Colab 笔记本,在那里我弄清楚了为什么他们的模型能够生成一些非常好的样本:https://colab.research.google.com/github/tensorflow/tpu/blob/master/tools/colab/shakespeare_with_tpu_and_keras.ipynb#scrollTo=tU7M-EGGxR3E

在我更改了这一行之后,我的模型从一遍又一遍地生成几个单词变成了真正有趣的东西!

【讨论】:

    【解决方案2】:

    要使用和训练文本生成模型,请按以下步骤操作:

    1. 在给定目前可用文本的情况下,从模型中得出下一个字符的概率分布(这将是我们的预测分数)
    2. 将分布重新加权到某个“温度”(参见下面的代码)
    3. 根据重新加权的分布随机采样下一个字符(参见下面的代码)
    4. 在可用文本末尾添加新字符

    查看示例函数:

    def sample(preds, temperature=1.0):
        preds = np.asarray(preds).astype('float64')
        preds = np.log(preds) / temperature
        exp_preds = np.exp(preds)
        preds = exp_preds / np.sum(exp_preds)
        probas = np.random.multinomial(1, preds, 1)
        return np.argmax(probas)
    

    您应该在训练过程中按如下方式使用示例函数:

    for epoch in range(1, 60):
        print('epoch', epoch)
        # Fit the model for 1 epoch on the available training data
        model.fit(x, y,
                  batch_size=128,
                  epochs=1)
    
        # Select a text seed at random
        start_index = random.randint(0, len(text) - maxlen - 1)
        generated_text = text[start_index: start_index + maxlen]
        print('--- Generating with seed: "' + generated_text + '"')
    
        for temperature in [0.2, 0.5, 1.0, 1.2]:
            print('------ temperature:', temperature)
            sys.stdout.write(generated_text)
    
            # We generate 400 characters
            for i in range(400):
                sampled = np.zeros((1, maxlen, len(chars)))
                for t, char in enumerate(generated_text):
                    sampled[0, t, char_indices[char]] = 1.
    
                preds = model.predict(sampled, verbose=0)[0]
                next_index = sample(preds, temperature)
                next_char = chars[next_index]
    
                generated_text += next_char
                generated_text = generated_text[1:]
    
                sys.stdout.write(next_char)
                sys.stdout.flush()
            print()
    

    低温导致文本极其重复和可预测,但局部结构非常逼真:特别是,所有单词(一个单词是字符的局部模式)都是真实的英语单词。随着温度的升高,生成的文本会变得更有趣、更令人惊讶,甚至更有创意。

    看到这个notebook

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 2018-11-22
      • 1970-01-01
      相关资源
      最近更新 更多