title: Giving a time series input to Pytorch-LSTM using a Batch size of 128
body: <p>I have a dataset of n training samples (Where X matrix = n * 30 * 20) where 30 is the number of sequences, 20 is the number of features. I am using categorical cross-entropy loss since this is a classification task. My input matrix is of shape 10000 *30 * 20 and target matrix is 1000 * 1. I was wondering what is the correct way to give the input to the LSTM. My entire code is attached below. </p>
  
  <pre><code>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
  </code></pre>
  
  <p>Moreover, I am initializing the hidden and cell states as 1 * Batch_size * hidden size. However since I have 30 as sequence length, should it be 30 * batch_size * hidden size?</p>
  
  <pre><code>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-&gt;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-&gt;Epoch: ",epoch," Accuracy: ",100.*correct/total," Loss ",test_loss/len(testloader))
  </code></pre>
  
  <p>I am loading my inputs as below:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>I get the below shape mismatch error. I definitely think it has something to do with my input tensors or the way I am initializing my hidden states. Also, I am not sure if my input to the first fully connected layer is correct. Should I give only the last hidden state output from the LSTM 2 <code>(self.hx2[-1]?)</code></p>
  
  <p>On reading other posts, I see that for 2D inputs, you are sometimes asked to reshape to <code>(sequence * batch size * feature)</code> for direct input to LSTM. How does this work ?</p>
  
  <p>And most important I get the below error :</p>
  
  <pre><code>RuntimeError: Expected hidden[0] size (1, 30, 64), got (30, 128, 64)
  </code></pre>
  
  <p>I understand this is all a lot but my goal here is to provide as much information as possible. I have read other posts, sample GitHub codes but most of them deal with using an embedding later which I don't want to use.</p>