Press "Enter" to skip to content

PyTorch LSTMCell – 输入、隐藏状态、细胞状态和输出的形状

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第1张

在Pytorch中,使用LSTMCell(使用nn.LSTMCell)时,我们需要了解表示输入时间序列、隐藏状态向量和细胞状态向量的张量应如何形状。在本文中,让我们假设您正在处理多变量时间序列。数据集中的每个多变量时间序列包含多个单变量时间序列。

在本文中,我们使用以下术语:

batch = 数据集中单个批次中的多变量时间序列数量

input_features = 单个多变量时间序列中的单变量时间序列数量

time_steps = 每个多变量时间序列中的时间步数

传递给LSTMCell的多变量时间序列批次应该是一个形状为(time_steps, batch, input_features)的张量

以下图片给出了输入形状的理解:

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第2张

LSTMCell的输入是以特定方式给出的。基本上,整个多变量时间序列不作为时间序列的输入给出。在MTS中的特定时间步的向量x_t作为LSTMCell的输入。为了处理单个时间步的向量,LSTMCell需要一个单个的隐藏状态向量作为输入的一部分,以及一个单个的细胞状态向量作为输入的一部分。它们分别表示为h_0和c_0。LSTMCell的输出将是在处理下一个时间步的输入向量x_t+1时使用的隐藏状态和细胞状态。这些隐藏状态和细胞状态分别表示为h_1和c_1。LSTMCell在循环中调用,将h_1和c_1作为后续时间步的h_0和c_0传入。这个概念在以下代码片段中说明。

在初始化LSTMCell对象时,应给出参数input_features和hidden_size。

这里,input_features = 单个多变量时间序列中的单变量时间序列数量(与上述input_features相同)

hidden_size = 隐藏状态向量中的维数。这个大小也应该用于细胞状态向量中的维数。

LSTMCell中的隐藏状态和细胞状态的初始值应该创建为形状为(batch, hidden_size)的张量。这里,batch应与输入多变量时间序列中的batch相匹配。这意味着对于输入批次中的每个MTS,都有一个相应的隐藏状态和细胞状态。

初始隐藏状态和初始细胞状态的时间序列应作为前向传播通过LSTMCell的输入。

将输入MTS的特定时间步的向量、初始隐藏状态和初始细胞状态通过LSTMCell对象的前向传播应按以下格式进行:

LSTMCell(x_t, (h_0, c_0))

以下图片给出了隐藏状态和细胞状态形状的理解:

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第3张

以下是一个示例代码。代码的解释如下。

import torch
import torch.nn as nn
lstm_0 = nn.LSTMCell(10, 20) # (input_features, hidden_size)
inp = torch.randn(7, 3, 10) # (time_steps, batch, input_features) -> input time series
hx = torch.randn(3, 20) # (batch, hidden_size) -> initial value of hidden state
cx = torch.randn(3, 20) # (batch, hidden_size) -> initial value of cell state
for i in range(inp.size()[0]):
     hx, cx = lstm_0(inp[i], (hx, cx)) # input通过LSTMCell进行前向传播
     output.append(hx)
output = torch.stack(output, dim=0)

调用nn.LSTMCell()将调用__init__()魔术方法并创建一个LSTMCell对象。在上面的代码中,该对象被引用为lstm_0

通常情况下的RNN(LSTM是RNN的一种类型),输入时间序列的每个时间步都应按顺序逐个传入RNN中以由RNN进行处理。

为了使用LSTMCell批量处理多变量时间序列,批次中所有MTS的每个时间步都应顺序通过LSTMCell进行传递。

这通过for循环实现。循环遍历MTS的每个时间步(inp.size()的第一个维度是时间步数),并将每个MTS中的时间步向量并行地传递到LSTMCell中。对LSTMCell的单个调用仅处理MTS中一个时间步的向量。

for循环中调用lstm_0(inp[i], (hx, cx))的输出是为每个时间步创建下一个隐藏状态和细胞状态。输出的隐藏状态(hx)和细胞状态(cx)根据先前的hx和cx进行递归计算。

输出:(h_1, c_1)

此输出对整个批次中的每个时间序列计算。输出形状为(batch, hidden_size)

以下图片展示了输出的隐藏状态和细胞状态的形状:

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第3张

在输入批次中为每个时间步创建的这些计算hx被附加到输出张量中,然后沿着0轴堆叠。因此,输出的维度为(time_steps, batch, hidden_size)

对于上面的代码示例,以下是输出:

tensor([[[ 0.0087,  0.0365, -0.1233, -0.2641,  0.2908, -0.5075,  0.2587,           0.1057, -0.2079, -0.2327,  0.1390,  0.1023, -0.1186,  0.3302,           0.1139,  0.1591, -0.0264, -0.0499,  0.0153,  0.3881],         [ 0.3585, -0.4133, -0.0259,  0.2490, -0.0936, -0.2756, -0.1941,          -0.0967,  0.1501, -0.0334, -0.1904, -0.3945, -0.1036, -0.2091,           0.0545,  0.1937, -0.2338,  0.0382,  0.2344,  0.1169],         [-0.2532,  0.0745, -0.0329,  0.0971, -0.1057, -0.0383,  0.1328,           0.1263, -0.1422,  0.0351,  0.3957, -0.4115, -0.2951, -0.5560,           0.1941,  0.0100,  0.3028, -0.1803,  0.0028,  0.3210]],        [[ 0.1105, -0.1295, -0.0636, -0.2510,  0.1923, -0.2457,  0.2401,           0.1379, -0.1373, -0.2451,  0.0387,  0.1004, -0.0580,  0.3430,          -0.0149,  0.1827, -0.0229, -0.2061,  0.1718,  0.3146],         [ 0.2741, -0.2413, -0.1310,  0.1206,  0.0379, -0.1738, -0.0568,           0.0417,  0.0756,  0.1020,  0.0262, -0.3280, -0.0352, -0.1713,           0.1065,  0.0458, -0.3404, -0.0795,  0.0586,  0.0026],         [-0.0112,  0.0883, -0.1755, -0.0438,  0.0193,  0.0151,  0.1010,           0.1614, -0.0524,  0.0970,  0.2092, -0.3518, -0.0715, -0.3941,           0.1422,  0.1164,  0.2946, -0.1919,  0.1493,  0.1203]]],       grad_fn=<StackBackward0>)

对于输入中的每个时间步(输入中的 time_steps = 2),都会创建一个数组(创建了 2 个数组)。每个数组都包含批次中每个 MTS 的数组(batch_size = 3)。对于 MTS 中的每个时间步,我们会得到一个 hidden_size 维度的隐藏状态向量输出(这里 hidden_size = 20)。因此,对于每个时间步,MTS 的值是一个向量。该向量在一个时间步中被映射为一个 20 维的 hidden_state 向量。

下图展示了输出多变量时间序列批次的形状:

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第5张

如果在上面的代码中打印 hx,对于一个时间步(循环中的一个迭代),输出如下:

tensor([[ 0.1034, -0.0192, -0.0581, -0.0772, -0.1578, -0.1450,  0.0377, -0.0013,         -0.2641, -0.1821,  0.0431, -0.2262,  0.3025,  0.0952,  0.4113, -0.2968,         -0.4377,  0.0794,  0.3683, -0.0021],        [ 0.0309,  0.3957,  0.2143,  0.1020,  0.0640, -0.0628,  0.4390,  0.1818,          0.0373,  0.2497, -0.1768, -0.2038, -0.1249, -0.2995,  0.0786, -0.0522,         -0.0080, -0.3095, -0.0815,  0.2874],        [-0.2458,  0.1622,  0.2564, -0.3136,  0.0631,  0.0643,  0.4036,  0.3293,         -0.1806, -0.0251, -0.4505, -0.1437, -0.1718, -0.0479, -0.1116, -0.1065,         -0.3289,  0.1137,  0.1160,  0.1227]], grad_fn=<MulBackward0>)

它有一个对应于一个时间步的数组。在这个时间步内,有 3 个数组,对应于批次中的 3 个 MTS。每个对应于一个 MTS 的数组都有一个 20 维的隐藏向量。因此,一个时间步的输出是(batch, hidden_size)

可以通过下图理解这个输出大小:

PyTorch LSTMCell - 输入、隐藏状态、细胞状态和输出的形状 四海 第6张

nn.LSTMCell 的初始化参数是:

input_size

hidden_size

bias

device

dtype

它没有 num_layers。因为这是一个单层的 cell,所以不能有多个 LSTM 层。

Leave a Reply

Your email address will not be published. Required fields are marked *