LSTM(Long Short-Term Memory)是循环神经网络(RNN)的一种变体。在RNN(Recurrent Neural Network)中,网络的每个时间步都会接受一个输入和一个隐藏状态,并输出一个新的隐藏状态和一个输出。隐藏状态可以看作是网络对过去输入的记忆,它会在每个时间步被更新,并传递到下一个时间步,从而捕捉到序列中的长期依赖关系。
LSTM在RNN的基础上新增了记忆单元(memory cell)和门控机制,在记忆单元中,LSTM层的每一个时间步对于上一时刻隐藏状态的输入()会和当前输入(
)相结合先通过遗忘门来控制上一时刻状态需要被遗忘的程度,再通过输入门来控制新信息需要被更新的程度,接下来会根据上面遗忘门和输入门的输出来更新当前时刻的状态(
)。接着,通过输出门,将当前状态的某些信息舍去,得到最终当前时刻的隐藏状态(
),再将其传递给下一个时间步(并输出)。
一个简单但完整的LSTM网络包含一个LSTM层和一个全连接层,LSTM层用于处理序列数据,全连接层用于将LSTM的输出映射到所需的输出空间,例如分类或回归。以下是一个使用Pytorch实现LSTM的简单代码:
import torch
import torch.nn as nn
# 定义一个LSTM网络类
class LSTM(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size):
super(LSTM, self).__init__()
# 定义LSTM的输入大小、隐藏状态大小、层数和输出大小
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.output_size = output_size
# 定义LSTM层
self.lstm = nn.LSTM(input_size, hidden_size, num_layers)
# 定义全连接层
self.fc = nn.Linear(hidden_size, output_size)
# 前向传播函数
def forward(self, inputs):
# 初始化LSTM的隐藏状态和记忆单元
h0 = torch.zeros(self.num_layers, inputs.size(1), self.hidden_size).to(inputs.device)
c0 = torch.zeros(self.num_layers, inputs.size(1), self.hidden_size).to(inputs.device)
# 通过LSTM层进行前向传播
output, (hn, cn) = self.lstm(inputs, (h0, c0)))
# 取LSTM最后一个时间步的输出作为全连接层的输入
output = output[-1, :, :]
# 将LSTM的输出传入全连接层进行前向传播
output = self.fc(output)
return output
这个LSTM网络类接受四个参数:输入大小(input_size)、隐藏状态大小(hidden_size)、层数(num_layers)和输出大小(output_size)。
在前向传播函数中,首先通过LSTM层进行前向传播,然后取LSTM最后一个时间步的输出作为全连接层的输入,并将其传入全连接层进行前向传播。在LSTM层的前向传播中,需要初始化LSTM的隐藏状态和记忆单元,这里我使用了torch.zeros
函数创建全零张量,并将其移到与输入张量相同的设备上(如CPU或GPU)。以下是具体关于上面代码的前向传播函数的说明:
初始化隐藏状态和记忆单元是LSTM模型的重要步骤之一。在LSTM模型中,每个时间步都有一个隐藏状态和一个记忆单元。隐藏状态包含了当前时间步的信息,而记忆单元则包含了过去时间步的信息。
h0 = torch.zeros(self.num_layers, inputs.size(1), self.hidden_size).to(inputs.device)
c0 = torch.zeros(self.num_layers, inputs.size(1), self.hidden_size).to(inputs.device)
首先创建了两个全零的张量h0和c0,它们的形状分别为(num_layers, batch_size, hidden_size)。这些张量都被转移到与输入张量相同的设备上,以便在GPU上进行计算。这里将隐藏状态和记忆单元初始化为全零是因为在LSTM模型的初始状态下,它们应该是没有任何先验信息的。
output, (hn, cn) = self.lstm(inputs, (h0, c0)))
通过LSTM层进行前向传播,其中inputs是输入数据,(h0, c0)
是LSTM的初始隐藏状态和记忆单元。这里的LSTM层会返回两个值,分别是最后一个时间步的输出output和最后一个时间步的隐藏状态hn
和记忆单元cn
。
output = output[-1, :, :]
取LSTM最后一个时间步的输出作为全连接层的输入。这是因为在LSTM中,每个时间步都会有一个输出,但我们只需要最后一个时间步的输出来进行分类或回归等任务。output[-1]
表示取output
张量的最后一个时间步,然后[:, :]
表示取该时间步中所有样本的输出和隐藏状态。因为在LSTM中,每个时间步的输出都是一个二维张量,所以这里使用了两个冒号来表示取所有行和所有列。
output = self.fc(output)
将LSTM的输出传入全连接层进行前向传播。这里的self.fc
是定义好的全连接层,它将LSTM的输出映射到所需的输出空间,例如分类或回归。最终的output
即为全连接层的输出,也是LSTM网络的预测结果。