
在Pytorch中,使用LSTM(使用nn.LSTM())需要了解代表输入时间序列、隐藏状态向量和细胞状态向量的张量应该如何形状。在本文中,假设您正在处理多变量时间序列。数据集中的每个多变量时间序列包含多个单变量时间序列。
以下是与pytorch的LSTMCell的差异:
Pytorch LSTMCell — 输入、隐藏状态和细胞状态的形状
在pytorch中,使用LSTMCell,我们需要了解代表输入时间序列、隐藏状态…
VoAGI.com
- 使用nn.LSTM可以创建多层的LSTM,通过堆叠它们来形成堆叠LSTM。第二个LSTM以第一个LSTM的输出作为输入,依此类推。
2. 可以在nn.LSTM类中添加dropout。
3. 可以将非批量输入提供给nn.LSTM。
还有一个重要的差异将在本文后面讨论。
在本文中,我们使用以下术语:
batch = 数据集中单个批次中的多变量时间序列数
input_features = 一个多变量时间序列中的单变量时间序列数
time steps = 每个多变量时间序列中的时间步数
作为输入传递给LSTM的多变量时间序列的批次应该是一个形状为(time_steps, batch, input_features)的张量
以下图片给出了对输入形状的理解:

但是,在LSTM中,还有另一种方式来对输入进行形状变换。下面将对此进行解释。
在初始化LSTM对象时,应提供参数input_features和hidden_size。
在这里,
input_features = 一个多变量时间序列中的单变量时间序列数(与上述input_features的值相同)
hidden_size = 隐藏状态向量的维数。
LSTM类还可以接受的其他参数:
num_layers = LSTM层的堆叠层数。当堆叠多个层时,称为堆叠LSTM。默认情况下,层数为1
dropout = 如果非零,则在每个LSTM层的输出上添加一个dropout层,dropout概率等于该值。默认情况下,该值为0,表示没有dropout。
batch_first = 如果为True,则输入和输出张量将具有维度(batch, time_steps, input_features),而不是(time_steps, batch, input_features)。默认情况下,此值为False。
proj_size = 投影大小。如果proj_size > 0,则使用具有投影的LSTM。
对于通过LSTM的前向传播,需要将时间序列、初始隐藏状态和初始细胞状态作为输入。
将输入、初始隐藏状态和初始细胞状态通过LSTM对象的前向传播的格式应为:
LSTM(input_time_series, (h_0, c_0))
让我们看看如何在进行前向传播之前对隐藏状态向量和细胞状态向量进行形状变换。
h_0 — (num_layers, batch, h_out)。这里 h_out = proj_size 如果 proj_size > 0,否则 hidden_size
c_0 — (num_layers, batch, hidden_size)
以下图片有助于理解隐藏向量的形状。

类似的图片也适用于细胞状态向量。
从图片中可以理解,所有层的隐藏状态和细胞状态的维度相同。
考虑以下代码片段:
import torchimport torch.nn as nn lstm_0 = nn.LSTM(10, 20, 2) # (input_features, hidden_size, num_layers)inp = torch.randn(4, 3, 10) # (time_steps, batch, input_features) -> 输入时间序列h0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size) -> 初始隐藏状态值c0 = torch.randn(2, 3, 20) # (num_layers, batch, hidden_size) -> 初始细胞状态值output, (hn, cn) = lstm_0(input, (h0, c0)) # 通过 LSTM 对输入进行前向传播
调用 nn.LSTM() 会调用 __init__() 魔术方法并创建 LSTM 对象。在上面的代码中,这个对象被引用为 lstm_0。
在一般的 RNN 中(LSTM 是 RNN 的一种类型),输入时间序列的每个时间步都应按顺序逐个传递到 RNN 中进行处理。
为了使用 LSTM 批量处理多变量时间序列,在批次中的所有 MTS 的每个时间步都应顺序通过 LSTM。
LSTM 的一次前向传播调用通过顺序处理每个时间步来处理整个序列。这与 LSTMCell 不同,LSTMCell 中的一次调用只处理一个时间步而不是整个序列。
上述代码的输出为:
tensor([[[ 3.8995e-02, 1.1831e-01, 1.1922e-01, 1.3734e-01, 1.6157e-02, 3.3094e-02, 2.8738e-01, -6.9250e-02, -1.8313e-01, -1.2594e-01, 1.4951e-01, -3.2489e-01, 2.1723e-01, -1.1722e-01, -2.5523e-01, -6.5740e-02, -5.2556e-02, -2.7092e-01, 3.0432e-01, 1.4228e-01], [ 9.2476e-02, 1.1557e-02, -9.3600e-03, -5.2662e-02, 5.5299e-03, -6.2017e-02, -1.9826e-01, -2.7072e-01, -5.5575e-02, -2.3024e-03, -2.6832e-01, -5.8481e-01, -8.3415e-03, -2.8817e-01, 4.6101e-03, 3.5043e-02, -6.2501e-01, 4.2930e-02, -5.4698e-01, -5.8626e-01], [-2.8034e-01, -3.4194e-01, -2.1888e-02, -2.1787e-01, -4.0497e-01, -3.6124e-01, -1.5303e-01, -1.3310e-01, -3.7745e-01, -1.8368e-01, -2.7527e-01, -2在此输出中,有4个数组对应于4个时间步长。每个时间步长包含3个数组,对应于批次中的3个MTS。每个这些3个数组包含20个元素,即隐藏状态。因此,对于批次中的每个MTS中的每个时间步长中的每个x_t向量,都会输出一个隐藏状态。这些是堆叠LSTM的最后一层中的隐藏状态。
输出:(output_multivariate_time_series, (h_n, c_n))
如果打印上面代码中存在的hn,则输出如下:
tensor([[[-0.3046, -0.1601, -0.0024, -0.0138, -0.1810, -0.1406, -0.1181, 0.0634, 0.0936, -0.1094, -0.2822, -0.2263, -0.1090, 0.2933, 0.0760, -0.1877, -0.0877, -0.0813, 0.0848, 0.0121], [ 0.0349, -0.2068, 0.1353, 0.1121, 0.1940, -0.0663, -0.0031, -0.2047, -0.0008, -0.0439, -0.0249, 0.0679, -0.0530, 0.1078, -0.0631, 0.0430, 0.0873, -0.1087, 0.3161, -0.1618], [-0.0528, -0.2693, 0.1001, -0.1097, 0.0097, -0.0677, -0.0048, 0.0509, 0.0655, 0.0075, -0.1127, -0.0641, 0.0050, 0.1991, 0.0370, -0.0923, 0.0629, 0.0122, 0.0688, -0.2374]], [[ 0.0273, -0.1082, 0.0243, -0.0924, 0.0077, 0.0359, 0.1209, 0.0545, -0.0838, 0.0139, 0.0086, -0.2110, 0.0880, -0.1371, -0.0171, 0.0332, 0.0509, -0.1481, 0.2044, -0.1747], [ 0.0087, -0.0943, 0.0111, -0.0618, -0.0376, -0.1297, 0.0497, 0.0071, -0.0905, 0.0700, -0.1282, -0.2104, 0.1350, -0.1672, 0.0697, 0.0679, 0.0512, 0.0183, 0.1531, -0.2602], [-0.0705, -0.1263, 0.0099, -0.0797, -0.1074, -0.0752, 0.1020, 0.0254, -0.1382, -0.0007, -0.0787, -0.1934, 0.1283, -0.0721, 0.1132, 0.0252, 0.0765, 0.0238, 0.1846, -0.2379]]], grad_fn=<StackBackward0>)
这包含了堆叠LSTM中最后一个时间步长中每个3个MTS中的第一层和第二层的隐藏状态向量。如果您注意到,第二层(最后一层)的隐藏状态与先前提到的输出中的最后一个时间步长的隐藏状态相同。
所以,输出的MTS维度是(时间步长,批次,隐藏层大小)。
这个输出维度可以从下面的图片中理解:

h_n的维度:(层数,批次,输出维度)
c_n的维度:(层数,批次,隐藏层大小)