LSTM模型
文章目录
- LSTM模型
- 模型搭建
- 模型的搭建
- 参数列表
- 输入的数据格式
- data
- h_0和c_0
- 输出的数据格式信息
- 代码的理解
- 测试代码
模型搭建
模型的搭建
参数列表
input_size:x的特征维度
hidden_size:隐藏层的特征维度
num_layers:lstm隐层的层数,默认为1
bias:False则bih=0和bhh=0. 默认为True
batch_first:True则输入输出的数据格式为 (batch, seq, feature)
dropout:除最后一层,每一层的输出都进行dropout,默认为: 0
bidirectional:True则为双向lstm默认为False
bilstm = nn.LSTM(input_size=10, hidden_size=20, num_layers=2, bidirectional=True)
输入的数据格式
Pytorch里的LSTM单元接受的输入都必须是3维的张量(Tensors).每一维代表的意思不能弄错。
- 第一维体现的是序列(sequence)结构,也就是序列的个数,用文章来说,就是每个句子的长度,因为是喂给网络模型,一般都设定为确定的长度,也就是我们喂给LSTM神经元的每个句子的长度,当然,如果是其他的带有带有序列形式的数据,则表示一个明确分割单位长度,
例如是如果是股票数据内,这表示特定时间单位内,有多少条数据。这个参数也就是明确这个层中有多少个确定的单元来处理输入的数据。 - 第二维度体现的是batch_size,也就是一次性喂给网络多少条句子,或者股票数据中的,一次性喂给模型多少是个时间单位的数据,具体到每个时刻,也就是一次性喂给特定时刻处理的单元的单词数或者该时刻应该喂给的股票数据的条数
- 第三位体现的是输入的元素(elements of input),也就是,每个具体的单词用多少维向量来表示,或者股票数据中 每一个具体的时刻的采集多少具体的值,比如最低价,最高价,均价,5日均价,10均价,等等
输入:input, (h0, c0) 输出:output, (hn,cn)
输入数据格式: input(seq_len, batch, input_size)
h0(num_layers * num_directions, batch, hidden_size)
c0(num_layers * num_directions, batch, hidden_size)
data
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zyAtIPGN-1681962687573)(C:%5CUsers%5CAdministrator%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1681959007485.png)]
h_0和c_0
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMhxQg1N-1681962687573)(C:%5CUsers%5CAdministrator%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1681959090586.png)]
输出的数据格式信息
输出数据格式:
output(seq_len, batch, hidden_size * num_directions)
hn(num_layers * num_directions, batch, hidden_size)
cn(num_layers * num_directions, batch, hidden_size)
代码的理解
理解对于不同的数据中LSTM怎么把状态进行向下传递的操作
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
torch.manual_seed(1)
lstm = nn.LSTM(3, 3) # 输入单词用一个维度为3的向量表示, 隐藏层的一个维度3,仅有一层的神经元,
#记住就是神经元,这个时候神经层的详细结构还没确定,仅仅是说这个网络可以接受[seq_len,batch_size,3]的数据输入
# print(lstm.all_weights)
inputs = [torch.randn(1, 3) for _ in range(5)]
print(inputs)
hidden = (torch.randn(1, 1, 3),
torch.randn(1, 1, 3))
print('Hidden:',hidden)
for i in inputs:
# 将序列的元素逐个输入到LSTM,这里的View是把输入放到第三维,看起来有点古怪
#回头看看上面的关于LSTM输入的描述,这是固定的格式,以后无论你什么形式的数据,
#都必须放到这个维度。就是在原Tensor的基础之上增加一个序列维和MiniBatch维,
#这里可能还会有迷惑,前面的1是什么意思啊,就是一次把这个输入处理完,
#在输入的过程中不会输出中间结果,这里注意输入的数据的形状一定要和LSTM定义的输入形状一致。
# 经过每步操作,hidden 的值包含了隐藏状态的信息
out, hidden = lstm(i.view(1, 1, -1), hidden)
print('out1:',out)
print('hidden2:',hidden)
inputs = torch.cat(inputs).view(len(inputs), 1, -1)
print(inputs.shape)
hidden = (torch.randn(1, 1, 3), torch.randn(1, 1, 3)) # clean out hidden state
out, hidden = lstm(inputs, hidden)
print('out2',out)
print('hidden3',hidden)
测试代码
import torch
import torch.nn as nn
import torch.optim as optim
class LSTM(nn.Module):
def __init__(self, input_size, hidden_size, num_layers, output_size):
super(LSTM, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device=x.device)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device=x.device)
out, _ = self.lstm(x, (h0, c0))
out = self.fc(out[:, -1, :])
return out
class Model(nn.Module):
def __init__(self):
super(Model, self).__init__()
self.LSTM = LSTM(input_size=input_size, hidden_size=hidden_size, num_layers=num_layers, output_size=output_size)
def forward(self, x):
return self.LSTM(x)
train_loss, test_loss = optim.train(model=Model, optimizer='adam', epochs=100, input_data=(x_train, y_train), target_data=(x_test, y_test))
import torch
import torchvision.datasets as dsets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader, Dataset
# 定义测试数据集类
class TestDataset(Dataset):
def __init__(self, x, y, transform=None):
self.x = x
self.y = y
self.transform = transform
def __getitem__(self, index):
x = torch.tensor(self.x[index]).float()
y = torch.tensor(self.y[index]).float()
return x, y
def __len__(self):
return len(self.x)
# 定义测试数据集加载函数
def load_test_data(data_dir):
x, y = dsets.ImageFolder(root=data_dir, transform=transforms.ToTensor())
return x, y
# 加载测试数据并进行预测
x_test, y_test = load_test_data('test_data')
model.eval()
dataloader = DataLoader(TestDataset(x_test, y_test), batch_size=2, shuffle=False)
for x, y in dataloader:
x = x.view(-1, x.size(0))
y = y.view(-1)
output = model(x)
pred = output.argmax(dim=1)
print(f'Model evaluated on test set: {pred.numpy()}')