【问题标题】:Generative RNN: how to deal with frequent characters?Generative RNN:如何处理频繁字符?
【发布时间】:2020-10-20 16:15:31
【问题描述】:

我想创建一个生成字符 LSTM 网络。这个想法是:模型采用最后 32 个现有字符并基于它们生成另一个字符。一次又一次。

这是模型,很简单:

model = Sequential([
    Input(shape=[32, 1]),
    LSTM(64, return_sequences=True),
    LSTM(64),
    Dense(len(corpus.keys()), activation='softmax', use_bias=False),
])

问题是:文本中字符的频率差异很大。频率最低的字母出现了 326 次,而最频繁的字母出现了 56190 次。看看条形图就知道了。

即使经过 200 个 epoch 的训练,模型所能预测的只是空间,因为它只是最频繁出现的字符。因此,损失在训练期间正在减少。


我已经尝试过更复杂和更简单的模型,结果总是一样。模型只记住频率。

编辑:这里是notebook

【问题讨论】:

  • 你应该根据频率来衡量损失。角色的损失权重可以简单地是频率的倒数,也可以是基于该概念的其他函数。

标签: python tensorflow keras lstm recurrent-neural-network


【解决方案1】:

除了解决过拟合问题,您应该从输出概率中采样,而不是取最高概率(argmax)。有一个 Tensorflow tutorial 涵盖了这一点。

要从模型中获得实际预测,您需要从输出分布中采样,以获得实际的字符索引。此分布由字符词汇表上的 logits 定义。

注意:从该分布中采样很重要,因为获取分布的 argmax 很容易使模型陷入循环。

大致是你如何做到的:

example_batch_predictions = model(X_test)

sampled_indices = tf.random.categorical(example_batch_predictions[0], 
                                        num_samples=1)
sampled_indices = tf.squeeze(sampled_indices,axis=-1).numpy()
array([41, 60,  3, 31, 47, 21, 61,  6, 56, 42, 39, 40, 52, 60, 37, 37, 27,
       11,  6, 56, 64, 62, 43, 42,  6, 34,  1, 30, 16, 45, 46, 11, 17,  8,
       26,  8,  1, 46, 37, 21, 37, 53, 34, 49,  5, 58, 11,  9, 42, 62, 14,
       56, 56, 30, 31, 32, 63, 53, 10, 23, 35,  5, 19, 19, 46,  3, 23, 63,
       61, 11, 57,  0, 35, 48, 32,  4, 37,  7, 48, 23, 39, 30, 20, 26,  1,
       52, 57, 23, 46, 56, 11, 22,  7, 47, 16, 27, 38, 51, 55, 28])

这将用于文本生成。为了更好的训练,我建议你在 LSTM 之前使用嵌入层:

model = Sequential([
    Input(shape=[32, 1]),
    Embedding(input_dim=len(corpus.keys()), output_dim=16),
    LSTM(64, return_sequences=True),
    LSTM(64),
    Dense(len(corpus.keys()), activation='softmax', use_bias=False),
])

如果您有字符序列,并且不是一个热编码词,这将起作用。

这是一个tutorial 我做基于字符的文本生成。也许它可以帮助你。

【讨论】:

  • 据我了解,您所说的是预测。但我的模型甚至无法训练。然后损失从3.2653减少到3.2489
  • 谢谢。但是添加Embedding 层并没有帮助
  • 我认为您必须提供更多详细信息,因为字符级 RNN 是最简单的任务之一。由于嵌入层,损失是如何减少的?它几乎不可能没有帮助。我怀疑某处出了点问题,从您包含的代码中我看不到
  • 随着嵌入层的损失减少到 3.1123(这仍然是一个很大的数字)。我应该提供什么样的详细信息?
  • 我在问题中添加了笔记本的链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多