tf.keras.layers.LSTM参数的含义

时间:2019-08-08 13:59:50

标签: tensorflow keras tf.keras

我在理解LSTM API中tf.keras.layers层的某些参数时遇到了麻烦。

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

我分别列出了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层之前/之后,是否可以将这些辍学参数中的任何一个替换为辍学层(即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层中,因为它可能会使并行化变得更加困难。但是,在LSTM s中,这是否会影响结果(即具有相同种子,implementation=1会收敛到与implementation=2相同或不同的结果)?
  • unroll

我已经阅读了很多关于LSTM的文章,并且正处于决定开始训练事物的时刻,否则我不会吸收更多的假设知识。我在建模方面也尝试了很多事情,但是我正在训练的网络非常简单,因此似乎没有什么影响结果。

1 个答案:

答案 0 :(得分:3)

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_dropout

dropoutrecurrent_dropout的需求是,在时维上应用dropout可能会很麻烦,因为这会影响模型的内存。但是,在输入数据上应用dropout几乎是我们每天使用前馈模型所做的事情。所以,

  • dropout:在输入数据(x)上应用滤除掩码
  • recurrent_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

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

找到我引用的源代码here。希望这可以澄清它。