LSTM¶
- class LSTM(*args, **kwargs)[源代码]¶
将多层 LSTM 应用于输入序列。
对于输入序列中的每个元素,每层都计算以下函数:
\[\begin{split}\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}\end{split}\]其中 \(h_t\) 是时间 t 的 hidden state, \(c_t\) 是时间 t 的 cell state, \(x_t\) 是时间 t 的输入, :math: h_{t-1} 是时间 t-1 的层的 hidden state 或时间 0 的初始 hidden state, \(i_t\), \(f_t\), \(g_t\), \(o_t\) 分别是输入、遗忘、单元和输出门。 \(\sigma\) 是sigmoid函数, \(\odot\) 是 Hadamard 积。
在多层LSTM中, \(l\) 层(\(l >= 2\))的输入 \(x^{(l)}_t\) 是前一层的 hidden state \(h^{(l-1)}_t\) 乘以 dropout \(delta^{(l-1)}_t\),其中每个 \(delta^{(l-1)}_t\) 是一个伯努利随机变量,其概率
dropout
为 \(0\).如果指定
proj_size > 0
,将使用带投影的LSTM。这将以下列方式改变LSTM单元。首先, \(h_t\) 的维度将从hidden_size
改为 ``proj_size``( \(W_{hi}\)。请注意,这样做的结果是,LSTM网络的输出也将是不同的形状。所有变量的确切维度见下面的输入/输出部分。你可以在 https://arxiv.org/abs/1402.1128 中找到更多细节。- 参数
input_size – 输入 `x ` 中的预期特征的数量
hidden_size – Hidden state h 中特征的数量
num_layers – Recurrent 层的数量。例如,设置
num_layers=2
意味着将两个LSTM堆叠在一起,形成一个 stacked LSTM,第二个LSTM接收第一个LSTM的输出并计算最终结果。默认值:1bias – 如果
False
,那么该层不使用偏置权重 b_ih 和 b_hh。默认值:True
batch_first – 如果
True
,那么输入和输出 tesnor 被提供为 (batch, seq, feature),而不是 (seq, batch, feature)。注意,这不适用于 hidden state 或 cell state. 详见下面的输入/输出部分。 默认值:False
dropout – 如果非零,在每个LSTM层的输出上引入一个
dropout
层,除了最后一层,dropout 概率等于dropout
。默认值:0bidirectional – 如果是
True
,则成为一个双向LSTM。默认值:False
proj_size – 如果
> 0
,将为LSTM设置相应大小的投影。默认值:0
- Inputs: input, (h_0, c_0)
input:当
batch_first=False
时,形状为 \((L, N, H_{in})\) 的tensor;当batch_first=True
时,形状为:math:(N, L, H_{in}) 的tensor,该tensor包含输入序列的特征。 输入也可以是一个打包的可变长度序列。详见torch.nn.utils.rnn.pack_padded_sequence
或torch.nn.utils.rnn.pack_sequence
.h_0:包含 batch 中每个元素的初始 hidden state 的形状为 \((D *\text{num\_layers}, N, H_{out})\) 的 tensor. 如果没有提供(h_0, c_0),则默认为零。
c_0:包含 batch 中每个元素的初始 cell state 的形状为 \((D *\text{num\_layers}, N, H_{cell})\) 的 tensor. 如果没有提供(h_0, c_0),则默认为零。
其中:
\[\begin{split}\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}\end{split}\]- Outputs: output, (h_n, c_n)
output:当
batch_first=False
时,形状为 \((L, N, D * H_{out})\) 的tensor;当batch_first=True
时,形状为 \((N, L, D * H_{out})\) 的tensor,该tensor包含LSTM最后一层的关于每个 t 的输出特征 (h_t)。如果一个torch.nn.utils.rnn.PackedSequence
被作为输入,输出也将是一个打包序列。h_n:形状为 \((D *\text{num\_layers}, N, H_{out})\),包含 batch 中每个元素的最终 hidden state 的 tensor.
c_n:形状为 \((D *\text{num\_layers}, N, H_{cell})\),包含 batch 中每个元素的最终 cell state 的 tensor.
实际案例
import numpy as np import megengine as mge import megengine.module as M m = M.LSTM(10, 20, 2, batch_first=False, bidirectional=True, bias=True) inp = mge.tensor(np.random.randn(6, 30, 10), dtype=np.float32) hx = mge.tensor(np.random.randn(4, 30, 20), dtype=np.float32) cx = mge.tensor(np.random.randn(4, 30, 20), dtype=np.float32) out, (hn, cn) = m(inp,(hx,cx)) print(out.numpy().shape)
输出:
(6, 30, 40)