【问题标题】:Meaning of tf.keras.layers.LSTM parameterstf.keras.layers.LSTM 参数的含义
【发布时间】:2019-08-08 13:59:50
【问题描述】:

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

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

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

  • activation
  • recurrent_activation
    1. activationrecurrent_activation 有什么区别?我假设它与单元格的激活与完整的LSTM 层的激活有关,但我不确定。
  • use_bias
    1. 如果 use_bias 为 True,那么此偏差应用在哪里?
  • dropout
  • recurrent_dropout
    1. 同样,dropoutrecurrent_dropout 有什么区别?如果recurrent_dropout 是 LSTM 单元之间的丢失,那对我来说没有意义,因为你会忽略之前的输出,我认为这会破坏使用 RNN 的目的。
    2. 可以在 LSTM 层之前/之后将这些 dropout 参数中的任何一个替换为 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
    1. 我理解为什么这个参数不在CuDNN 层中,因为它可能会使并行化变得更加困难。但是,在LSTMs 中,这会影响结果吗(即,使用相同的种子,implementation=1 会收敛到与implementation=2 相同或不同的结果)吗?
  • unroll

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

【问题讨论】:

    标签: tensorflow keras tf.keras


    【解决方案1】:

    activationrecurrent_activation

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

    我可以直观地解释为什么需要两个。对于门,0-1 之间的范围听起来很直观,因为门可以打开或关闭或在中间,但不是负数(因此 sigmoid)。然而,单元格输出将更具表现力并导致较少的饱和度,因为它的范围在 -1 和 1 之间(因此 tanh)。它也可能有助于解决消失的梯度。但我对此并不完全确定。

    use_bias

    如果use_bias 为真,则方程中将有一个+b(例如i_t = sigma(x_t Ui + h_t-1 Wi + bi))。如果没有,就不会有偏见(例如i_t = sigma(x_t Ui + h_t-1 Wi))。就个人而言,我总是使用偏见。

    dropoutrecurrent_dropout

    dropoutrecurrent_dropout 的需要是,在时间维度上应用 dropout 可能会非常灾难性,因为您正在影响模型的内存。然而,在输入数据上应用dropout,几乎就是我们日常使用前馈模型所做的事情。所以,

    • dropout:对输入数据应用 dropout 掩码 (x)
    • recurrent_dropout:在之前的状态数据上应用 dropout 掩码 (h_t-1)

    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

    如果为真,它将在时间维度上展开 RNN,并在没有循环的情况下进行计算(这将占用大量内存)。如果为 false,这将通过 for 循环来完成,这将花费更长的时间,但占用的内存更少。

    我提到的源代码在here。希望这可以澄清它。

    【讨论】:

    • 谢谢@thushv89,这回答了很多!因此,根据您的 cmets,我假设 dropout 可以替换为 Dropout 层 tf.keras.models.Sequential([Input(...), Dropout(0.5), LSTM(...)]),因为它是该层输入的 dropout,但无法替代 recurrent_dropout。这是正确的吗?
    • 是的,这就是我的想象。
    猜你喜欢
    • 2011-08-17
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-27
    • 2014-08-11
    相关资源
    最近更新 更多