LSTM
- classtorch.nn.LSTM(input_size, hidden_size, num_layers=1, bias=True, batch_first=False, dropout=0.0, bidirectional=False, proj_size=0, device=None, dtype=None)[源代码]
-
使用多层长短期记忆(LSTM)RNN来处理输入序列。对于序列中的每一个元素,每一层都会执行以下计算:
$\begin{array}{ll} \\ i_t = \sigma(W_{ii} x_t + b_{ii} + W_{hi} h_{t-1} + b_{hi}) \\ f_t = \sigma(W_{if} x_t + b_{if} + W_{hf} h_{t-1} + b_{hf}) \\ g_t = \tanh(W_{ig} x_t + b_{ig} + W_{hg} h_{t-1} + b_{hg}) \\ o_t = \sigma(W_{io} x_t + b_{io} + W_{ho} h_{t-1} + b_{ho}) \\ c_t = f_t \odot c_{t-1} + i_t \odot g_t \\ h_t = o_t \odot \tanh(c_t) \\ \end{array}$其中,$h_t$ 表示时间t的隐藏状态,$c_t$ 表示时间t的单元状态,$x_t$ 是时间t的输入数据。此外,$h_{t-1}$ 代表时间t-1的隐藏状态或初始时刻(即时间0)的隐藏状态。$i_t$、$f_t$、$g_t$ 和 $o_t$ 分别对应输入门、遗忘门、单元门和输出门。符号$\sigma$ 表示 sigmoid 函数,而$\odot$ 则表示 Hadamard 乘积。
在多层LSTM中,第$l$ 层($l \ge 2$)的输入 $x^{(l)}_t$ 是前一层隐藏状态 $h^{(l-1)}_t$ 与 dropout $\delta^{(l-1)}_t$ 的乘积。每个 $\delta^{(l-1)}_t$ 是一个伯努利随机变量,取值为$0$的概率是
dropout
。如果指定了
proj_size > 0
,将使用带投影的 LSTM。这会以以下方式改变 LSTM 单元:首先,$h_t$ 的维度将从hidden_size
更改为proj_size
($W_{hi}$ 的维度也会相应改变)。其次,每一层的输出隐藏状态将乘以一个可学习的投影矩阵:$h_t = W_{hr}h_t$。请注意,这会导致 LSTM 网络的输出形状发生变化。有关所有变量的确切维度,请参见下面的输入/输出部分。更多细节请参阅 https://arxiv.org/abs/1402.1128。- 参数
-
-
input_size - 输入x中预期的特征数量
-
hidden_size – 隐藏状态 h 中的特征数
-
num_layers – 循环层的数量。例如,设置
num_layers=2
意味着堆叠两个LSTM层来形成一个堆叠的LSTM,其中第二个LSTM接收第一个LSTM的输出并计算最终结果。默认值:1 -
bias – 如果为
False
,则该层不使用偏置权重b_ih和b_hh。默认值:True
-
batch_first – 如果为
True
,则输入和输出张量的形状为(batch, seq, feature),而不是默认的(seq, batch, feature)。需要注意的是,这不适用于隐藏状态或单元状态。有关详细信息,请参阅下面的Inputs/Outputs部分。默认值:False
-
dropout – 如果非零,则在每个 LSTM 层(除了最后一层)的输出后引入一个Dropout层,丢弃概率为
dropout
。默认值:0 -
bidirectional - 如果设置为
True
,则表示使用双向LSTM。默认值:False
-
proj_size – 如果值大于 0,则使用相应大小的投影 LSTM。默认值:0
-
- 输入:input,(h_0, c_0)
-
-
input: 形状为$(L, H_{in})$的张量,用于未批量处理的输入;当
batch_first=False
时形状为$(L, N, H_{in})$,当batch_first=True
时形状为$(N, L, H_{in})$。这些张量包含输入序列的特征。输入也可以是一个打包的可变长度序列。详情请参阅torch.nn.utils.rnn.pack_padded_sequence()
或者torch.nn.utils.rnn.pack_sequence()
。 -
h_0: 形状为 $(D * \text{num\_layers}, H_{out})$ 的张量,用于未批量处理的输入;或形状为 $(D * \text{num\_layers}, N, H_{out})$ 的张量,包含输入序列中每个元素的初始隐藏状态。如果未提供 (h_0, c_0),则默认值为零。
-
c_0: 形状为 $(D * \text{num\_layers}, H_{cell})$ 的张量,用于未批量处理的输入;或形状为 $(D * \text{num\_layers}, N, H_{cell})$ 的张量,包含输入序列中每个元素的初始单元状态。如果未提供 (h_0, c_0),则默认值为零。
其中:
$\begin{aligned} N ={} & \text{batch size} \\ L ={} & \text{sequence length} \\ D ={} & 2 \text{ if bidirectional=True otherwise } 1 \\ H_{in} ={} & \text{input\_size} \\ H_{cell} ={} & \text{hidden\_size} \\ H_{out} ={} & \text{proj\_size if } \text{proj\_size}>0 \text{ otherwise hidden\_size} \\ \end{aligned}$ -
- 输出:output,(h_n, c_n)
-
-
输出: 对于未批量处理的输入,形状为$(L, D * H_{out})$ 的张量;当
batch_first=False
时,形状为 $(L, N, D * H_{out})$;当batch_first=True
时,形状为$(N, L, D * H_{out})$。输出包含每个时间步长 LSTM 最后一层的输出特征(h_t)。如果输入是torch.nn.utils.rnn.PackedSequence
类型,那么输出也将是一个打包序列。当bidirectional=True
时,output 将包含每个时间步长的前向和后向隐藏状态的连接。 -
h_n: 形状为$(D * \text{num\_layers}, H_{out})$的张量,用于未批量处理的输入;或形状为$(D * \text{num\_layers}, N, H_{out})$的张量,包含序列中每个元素的最终隐藏状态。当
bidirectional=True
时,h_n将包含正向和反向隐藏状态的连接。 -
c_n: 形状为$(D * \text{num\_layers}, H_{cell})$的张量(对于未批量处理的输入),或形状为$(D * \text{num\_layers}, N, H_{cell})$的张量,包含序列中每个元素的最终单元状态。当
bidirectional=True
时,c_n将分别包含正向和反向单元状态的连接。
-
- 变量
-
-
weight_ih_l[k] – 第 $\text{k}^{th}$ 层的可学习输入-隐藏权重 (W_ii|W_if|W_ig|W_io)。当 k = 0 时,其形状为 (4*hidden_size, input_size);否则,形状为 (4*hidden_size, num_directions * hidden_size)。如果指定了
proj_size > 0
,则当 k > 0 时形状为 (4*hidden_size, num_directions * proj_size) -
weight_hh_l[k] – 第 $\text{k}^{th}$ 层的可学习隐藏层到隐藏层权重 (W_hi|W_hf|W_hg|W_ho),其形状为 (4*hidden_size, hidden_size)。如果指定了
proj_size > 0
,则形状将变为 (4*hidden_size, proj_size)。 -
bias_ih_l[k] – 第 $\text{k}^{th}$ 层的可学习输入-隐藏偏差 (b_ii|b_if|b_ig|b_io),其形状为 (4*hidden_size)
-
bias_hh_l[k] – 第 $\text{k}^{th}$ 层的可学习隐藏层到隐藏层偏置 (b_hi|b_hf|b_hg|b_ho),其形状为 (4*hidden_size)
-
weight_hr_l[k] – 第$\text{k}^{th}$层的可学习投影权重,形状为(proj_size, hidden_size)。仅在
proj_size > 0
时存在。 -
weight_ih_l[k]_reverse — 与正向方向的 weight_ih_l[k] 类似,但用于反向方向。仅在
bidirectional=True
时出现。 -
weight_hh_l[k]_reverse — 类似于正向方向中的 weight_hh_l[k],但用于反向方向。仅在
bidirectional=True
时出现。 -
bias_ih_l[k]_reverse — 类似于正向方向中的 bias_ih_l[k],但用于反向方向。仅在
bidirectional=True
时出现。 -
bias_hh_l[k]_reverse — 类似于正向的 bias_hh_l[k],但用于反向方向。仅在
bidirectional=True
时存在。 -
weight_hr_l[k]_reverse – 与正向方向下的weight_hr_l[k]类似,但适用于反向方向。仅在指定
bidirectional=True
和proj_size > 0
时存在。
-
注意
所有的权重和偏置都从$\mathcal{U}(-\sqrt{k}, \sqrt{k})$ 初始化,其中 $k = \frac{1}{\text{hidden\_size}}$。
注意
对于双向LSTM,正向和反向分别是方向0和1。当
batch_first=False
时,输出层的分割示例如下:output.view(seq_len, batch, num_directions, hidden_size)
。注意
对于双向LSTM,h_n 不等同于output的最后一个元素;前者包含了最终的正向和反向隐藏状态,而后者则包含最终的正向隐藏状态以及初始的反向隐藏状态。
注意
batch_first
参数会被忽略,除非输入是批量化的。注意
proj_size
应该小于hidden_size
。警告
在某些版本的cuDNN和CUDA中,RNN函数存在已知的非确定性问题。你可以通过设置以下环境变量来确保其行为的一致性和确定性:
在 CUDA 10.1 中,设置环境变量
CUDA_LAUNCH_BLOCKING=1
。这可能会对性能产生影响。在 CUDA 10.2 或更高版本中,设置环境变量(注意前面的冒号符号)
CUBLAS_WORKSPACE_CONFIG=:16:8
或CUBLAS_WORKSPACE_CONFIG=:4096:2
。参阅cuDNN 8 发行说明以获取更多信息。
注意
如果满足以下条件:1)启用cudnn,2)输入数据位于GPU上,3)输入数据的数据类型为
torch.float16
,4)使用V100 GPU,5)输入数据不是PackedSequence
格式,则可以选择持久算法以提高性能。示例:
>>> rnn = nn.LSTM(10, 20, 2) >>> input = torch.randn(5, 3, 10) >>> h0 = torch.randn(2, 3, 20) >>> c0 = torch.randn(2, 3, 20) >>> output, (hn, cn) = rnn(input, (h0, c0))