python - 使用 128 的 Batch 大小为 Pytorch-LSTM 提供时间序列输入
问题描述
我有一个包含 n 个训练样本的数据集(其中 X 矩阵 = n * 30 * 20),其中 30 是序列数,20 是特征数。我正在使用分类交叉熵损失,因为这是一项分类任务。我的输入矩阵的形状是 10000 *30 * 20,目标矩阵是 1000 * 1。我想知道将输入提供给 LSTM 的正确方法是什么。我的整个代码附在下面。
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as data
import torch.backends.cudnn as cudnn
import torch.optim as optim
import torchvision.transforms as transforms
import torch.utils.data as utils
from torch.utils.data import DataLoader
import torch
from torch.autograd import Variable
class MyData(data.Dataset):
def __init__(self,X,y,transform=None, target_transform=None):
self.data = X
self.targets = y
self.transform = transform
self.target_transform= target_transform
def __getitem__(self, index):
item, target = self.data[index], self.targets[index]
item = torch.FloatTensor(item)
target = torch.LongTensor([target])
return item, target
def __len__(self):
return len(self.data)
class MyPredictor(nn.Module):
def __init__(self, num_blocks=1, input_dim=22, batch_size=128, hidden_dim1=64, hidden_dim2=128, GPU=True):
super(MyPredictor, self).__init__()
self.batch_size= batch_size
self.hidden_dim1=hidden_dim1
self.hidden_dim2=hidden_dim2
self.GPU=GPU
self.lstm1 = nn.LSTM(input_dim,self.hidden_dim1,num_layers=2)
self.lstm2 = nn.LSTM(self.hidden_dim1, self.hidden_dim2)
self.fc1 = nn.Linear(self.hidden_dim2, 256)
self.fc2=nn.Linear(256,1)
if self.GPU:
self.hx1 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim1).cuda())
self.cx1 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim1).cuda())
self.hx2 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim2).cuda())
self.cx2 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim2).cuda())
else:
self.hx1 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim1))
self.cx1 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim1))
self.hx2 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim2))
self.cx2 = Variable(torch.zeros(30, self.batch_size, self.hidden_dim2))
self.hidden1=(self.hx1,self.cx1)
self.hidden2=(self.hx2,self.cx2)
def forward(self, x):
out1, self.hidden1 = self.lstm1(x, self.hidden1)
out2, self.hidden2 = self.lstm1(x, self.hidden2)
out3=self.fc1(out2)
out3= F.relu(out3)
out4=self.fc2(out3)
out=F.relu(out4)
return out
此外,我将隐藏状态和单元状态初始化为 1 * Batch_size * 隐藏大小。但是,由于我有 30 作为序列长度,它应该是 30 * batch_size * 隐藏大小吗?
def train(epoch):
print('\nEpoch: %d' % epoch)
net.train()
train_loss = 0
correct = 0
total = 0
store=[]
for batch_idx, (inputs, targets) in enumerate(trainloader):
inputs, targets = inputs.to(device), targets.to(device)
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
train_loss += loss.item()
_, predicted = outputs.max(1)
total += targets.size(0)
correct += predicted.eq(targets).sum().item()
# progress_bar(batch_idx, len(trainloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
# % (train_loss/(batch_idx+1), 100.*correct/total, correct, total))
print("Train->Epoch: ",epoch," Accuracy: ",100.*correct/total," Loss ",train_loss/len(trainloader))
return[100.*correct/total,train_loss/len(trainloader)]
def test(epoch):
global best_acc
criterion = nn.CrossEntropyLoss()
net.eval()
test_loss = 0
correct = 0
total = 0
with torch.no_grad():
for batch_idx, (inputs, targets) in enumerate(testloader):
inputs, targets = inputs.to(device), targets.to(device)
outputs = net(inputs)
loss = criterion(outputs, targets)
test_loss += loss.item()
_, predicted = outputs.max(1)
total += targets.size(0)
correct += predicted.eq(targets).sum().item()
# progress_bar(batch_idx, len(testloader), 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
# % (test_loss/(batch_idx+1), 100.*correct/total, correct, total))
print("Test->Epoch: ",epoch," Accuracy: ",100.*correct/total," Loss ",test_loss/len(testloader))
我正在加载我的输入,如下所示:
from sklearn.externals import joblib
import numpy as np
#See if Gpu is available
device = 'cuda' if torch.cuda.is_available() else 'cpu'
net=MyPredictor()
net = net.to(device)
GPU=False
if device == 'cuda':
net = torch.nn.DataParallel(net)
cudnn.benchmark = True
GPU= True
#optimizer = optim.SGD(model.parameters(), lr=0.1)
optimizer = optim.Adam(net.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
#Load the datset
X, y = joblib.load("/app/dhanush/lstm_training_data.pkl")
X_train=np.array(X[0:30000])
X_test=np.array(X[30000:])
y_train= np.array(y[0:30000])
y_test= np.array(y[30000:])
print (X_train.shape)
print (y_train.shape)
trainset = MyData(X_train,y_train)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=False, num_workers=2)
testset = MyData(X_test, y_test)
testloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=False, num_workers=2)
for epoch in range(0, 21):
train(epoch)
test(epoch)
我收到以下形状不匹配错误。我绝对认为这与我的输入张量或我初始化隐藏状态的方式有关。另外,我不确定我对第一个全连接层的输入是否正确。我应该只给出 LSTM 2 的最后一个隐藏状态输出吗(self.hx2[-1]?)
在阅读其他帖子时,我看到对于 2D 输入,有时会要求您重新整形以(sequence * batch size * feature)
直接输入到 LSTM。这是如何运作的 ?
最重要的是我收到以下错误:
RuntimeError: Expected hidden[0] size (1, 30, 64), got (30, 128, 64)
我知道这很多,但我的目标是提供尽可能多的信息。我已经阅读了其他帖子,示例 GitHub 代码,但其中大多数处理使用稍后我不想使用的嵌入。
解决方案
推荐阅读
- javascript - 如何将 onclick 方法传递给使用 Javascript 创建的单选按钮?
- python - 为列表中的每个项目分配一个变量 [Python]
- oracle-apex - 将数据从表加载到 apex_util.select_list 多个
- iis - 无法从 127.0.0.1、localhost 连接到本地主机,甚至无法使用我的公共 ip
- azure-devops - 在 SonarQube 中实现/集成 ESLint?
- spring-boot - 使用 Cloud SQL:MySQL 从 Google Cloud Run 部署时出现通信链路故障错误
- javascript - 从我的网站获取表单联系方式到 whatsapp 消息空间
- angular - ngIf 如何验证 Angular Reactive Forms 中的多个条件
- image-processing - 如何使用openCV将对比度应用于图像的一半
- java - “QuantumRenderer-” 0 用于 JavaFX 字体