Предоставление ввода временного ряда в Pytorch-LSTM с использованием размера пакета 128 - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть набор данных из n обучающих выборок (где X matrix = 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, но большинство из них имеют дело с использованием встраивания позже, которое я не хочу использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...