我无法理解 LSTM API 中 tf.keras.layers 层的一些参数。

我正在研究使用 CuDNNLSTM 层而不是 LSTM 层(以加快训练速度),但是在我使用 CuDNN 层之前,我想充分了解使用 CuDNNLSTM 而不是 LSTM 层会丢失的参数。我已经阅读了文档,但他们似乎假设了一些我没有的 LSTM 的先验知识。

我列出了 CuDNNLSTM 没有(LSTM 有)的参数,并分别穿插了我对它们的问题。

  • activation
  • recurrent_activation
  • activationrecurrent_activation 有什么区别?我假设它与单元格的激活与完整 LSTM 层的激活有关,但我不确定。
  • use_bias
  • 如果 use_bias 为 True,则此偏差应用于何处?
  • dropout
  • recurrent_dropout
  • 再次,dropoutrecurrent_dropout 之间有什么区别?如果 recurrent_dropout 是 LSTM 单元之间的 dropout,那对我来说没有意义,因为你会忽略之前的输出,我认为这会破坏拥有 RNN 的目的。
  • 这些 dropout 参数中的任何一个都可以在 LSTM 层之前/之后用 dropout 层替换(即 tf.keras.models.sequential([Input(...), LSTM(...), Dropout(0.5)])tf.keras.models.sequential([Input(...), Dropout(0.5), LSTM(...)]) 而不是 tf.keras.models.sequential([Input(...), LSTM(..., dropout=0.5)]) )
  • implementation
  • 我理解为什么这个参数不在 CuDNN 层中,因为它可能会使并行化变得更加困难。但是,在 LSTM 中,这是否会影响结果(即,使用相同的种子, implementation=1 会收敛到与 implementation=2 相同还是不同的结果)?
  • unroll

  • 我已经阅读了很多关于 LSTM 的文章,现在我决定开始训练,否则我不会吸收更多的假设知识。我在建模方面也尝试了很多东西,但是我正在训练的网络非常简单,因此似乎没有任何影响结果。

    最佳答案

    activationrecurrent_activation
    如果您查看 LSTM equationsactivation(默认为 sigmoid )指的是用于门的激活(即输入/忘记/输出),而 recurrent_activation(默认为 tanh )指的是用于其他事物的激活(例如单元输出 h)。

    我可以直观地解释为什么需要两个。对于门,0-1 之间的范围听起来很直观,因为门可以打开或关闭或在中间,但不能为负(因此 sigmoid )。但是,单元格输出将更具表现力并导致饱和度降低,因为它的范围在 -1 和 1 之间(因此 tanh )。它还可能有助于解决消失的梯度。但我对此并不完全确定。
    use_bias
    如果 use_bias 为 True,则方程中将有 +b(例如 i_t = sigma(x_t Ui + h_t-1 Wi + bi) )。如果不是,就不会有偏差(例如 i_t = sigma(x_t Ui + h_t-1 Wi) )。就个人而言,我总是使用偏见。
    dropoutrecurrent_dropoutdropoutrecurrent_dropout 的需要在于,在时间维度上应用 dropout 可能会非常灾难性,因为您正在影响模型的内存。然而,在输入数据上应用 dropout 几乎是我们每天使用前馈模型所做的。所以,

  • dropout : 对输入数据应用 dropout 掩码 (x)
  • recurrent_dropout : 在先前的状态数据 (h_t-1) 上应用 dropout 掩码
  • implementation
    该实现提供了不同的方法来计算相同的东西。差异的需要可能是不同的内存要求。
  • implementation=1
  • 此处的计算就像您编写以下等式一样。换句话说,分四步做。
  • i_t = sigma(x_t Ui + h_t-1 Wi + bi)
  • f_t = sigma(x_t Uf + h_t-1 Wf + bf)
  • o_t = sigma(x_t Uo + h_t-1 Wo + bo)
  • tilde{c}_t = tanh(x_c Uc + h_t-1 Wc + bc)
  • implementation=anything else
  • 你一次做上述计算,
  • z = x_t concat(Ui, Uf, Uo, Uc)
  • z += h_t-1 concat(Wi, Wf, Wo, Wc)
  • z += concat(bi, bf, bo, bc)
  • 应用激活

  • 所以第二个实现非常有效,因为只有两个矩阵乘法发生。
    unroll
    如果为 true,它将在时间维度上展开 RNN 并在没有循环的情况下进行计算(这将是内存密集型的)。如果为 false,这将通过 for 循环完成,这将花费更长的时间但占用的内存更少。

    我引用的源代码是 here 。希望这能澄清它。

    关于tensorflow - tf.keras.layers.LSTM 参数的含义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57414387/

    10-12 18:57