tf.keras.layers.LSTM 参数的含义
Meaning of tf.keras.layers.LSTM parameters
我无法理解 tf.keras.layers
API 中 LSTM
层的一些参数。
我正在调查使用 CuDNNLSTM
层而不是 LSTM
层(以加快训练速度),但在我承诺使用 CuDNN
层之前,我想有一个完整的了解我使用 CuDNNLSTM
而不是 LSTM
层丢失的参数。我已经阅读了文档,但它们似乎假设了一些我没有的 LSTM
的先验知识。
我列出了 CuDNNLSTM
没有(LSTM
有)的参数,并分别穿插了我对它们的疑问。
activation
recurrent_activation
activation
和 recurrent_activation
有什么区别?我假设它与细胞的激活与完整 LSTM
层的激活有关,但我不确定。
use_bias
- 如果
use_bias
为 True,此偏差应用于何处?
dropout
recurrent_dropout
- 同样,
dropout
和recurrent_dropout
有什么区别?如果 recurrent_dropout
在 LSTM 单元之间丢失,这对我来说没有意义,因为你会忽略之前的输出,我认为这会破坏 RNN 的目的。
- 是否可以将这些丢失参数中的任何一个替换为丢失层 before/after 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
- 我理解为什么这个参数不在
CuDNN
层中,因为它可能会使并行化变得更加困难。但是,在 LSTM
s 中,这是否会影响结果(即使用相同的种子,implementation=1
会收敛到与 implementation=2
相同或不同的结果)?
unroll
我已经阅读了很多关于 LSTM
的内容,现在我决定开始训练一些东西,否则我不会吸收更多的假设性知识。我在建模方面也尝试了很多东西,但我训练的网络非常简单,所以似乎没有什么影响结果。
activation
对比 recurrent_activation
如果你看LSTM equations。 activation
(默认为sigmoid
)指的是用于门的激活(即input/forget/output),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)
)。就个人而言,我总是使用偏见。
dropout
对比 recurrent_dropout
dropout
和 recurrent_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
如果为真,它将在时间维度上展开 RNN 并在没有循环的情况下进行计算(这将是内存密集型的)。如果为 false,这将通过 for
循环完成,这将花费更长的时间但占用更少的内存。
找到我引用的源代码here。希望这能澄清它。
我无法理解 tf.keras.layers
API 中 LSTM
层的一些参数。
我正在调查使用 CuDNNLSTM
层而不是 LSTM
层(以加快训练速度),但在我承诺使用 CuDNN
层之前,我想有一个完整的了解我使用 CuDNNLSTM
而不是 LSTM
层丢失的参数。我已经阅读了文档,但它们似乎假设了一些我没有的 LSTM
的先验知识。
我列出了 CuDNNLSTM
没有(LSTM
有)的参数,并分别穿插了我对它们的疑问。
activation
recurrent_activation
activation
和recurrent_activation
有什么区别?我假设它与细胞的激活与完整LSTM
层的激活有关,但我不确定。
use_bias
- 如果
use_bias
为 True,此偏差应用于何处?
- 如果
dropout
recurrent_dropout
- 同样,
dropout
和recurrent_dropout
有什么区别?如果recurrent_dropout
在 LSTM 单元之间丢失,这对我来说没有意义,因为你会忽略之前的输出,我认为这会破坏 RNN 的目的。 - 是否可以将这些丢失参数中的任何一个替换为丢失层 before/after 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
- 我理解为什么这个参数不在
CuDNN
层中,因为它可能会使并行化变得更加困难。但是,在LSTM
s 中,这是否会影响结果(即使用相同的种子,implementation=1
会收敛到与implementation=2
相同或不同的结果)?
- 我理解为什么这个参数不在
unroll
我已经阅读了很多关于 LSTM
的内容,现在我决定开始训练一些东西,否则我不会吸收更多的假设性知识。我在建模方面也尝试了很多东西,但我训练的网络非常简单,所以似乎没有什么影响结果。
activation
对比 recurrent_activation
如果你看LSTM equations。 activation
(默认为sigmoid
)指的是用于门的激活(即input/forget/output),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)
)。就个人而言,我总是使用偏见。
dropout
对比 recurrent_dropout
dropout
和 recurrent_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
如果为真,它将在时间维度上展开 RNN 并在没有循环的情况下进行计算(这将是内存密集型的)。如果为 false,这将通过 for
循环完成,这将花费更长的时间但占用更少的内存。
找到我引用的源代码here。希望这能澄清它。