ValueError: Target size (torch.Size([1, 1])) must be the same as input size (torch.Size([1, 2]))

While trying to train my model with 2 targets, I get the error…“ValueError: Target size (torch.Size([1, 1])) must be the same as input size (torch.Size([1, 2]))”. I have a data set with 2 targets. I tried a lot even by resizing the tensors but no use. Also if I make the output_dim = 1, it always predicts the same class out of two.

** Loading Training data

class SwelltrainDataset(T.utils.data.Dataset):

  def __init__(self, Swelltrain):
    
    sc = StandardScaler()
    
    X_tr = sc.fit_transform(X_train)
    Y_tr = y_train
      
    self.X_tr = torch.tensor(X_tr, dtype = torch.float32)
    self.Y_tr = torch.tensor(Y_tr, dtype = torch.float32)

  def __len__(self):
    return len(self.Y_tr)

  def __getitem__(self, idx):
              
        return self.X_tr[idx], self.Y_tr[idx]
train_ds = SwelltrainDataset(Swelltrain)

bat_size = 1
idx = np.append(np.where(train_ds.Y_tr == 0)[0], 
                np.where(train_ds.Y_tr == 1)[0],
                )

train_ds.X_tr = train_ds.X_tr[idx]
train_ds.Y_tr = train_ds.Y_tr[idx]

train_ldr = T.utils.data.DataLoader(train_ds,
    batch_size=bat_size, shuffle=True)
batch = next(iter(train_ldr))

I am using LSTM Model with dimensions: input_dim = 16, hidden_dim = 100, layer_dim = 1, output_dim = 2

class LSTMModel(nn.Module):
    def __init__(self, input_dim, hidden_dim, layer_dim, output_dim):
        super(LSTMModel, self).__init__()
        self.hidden_dim = hidden_dim
        
        self.layer_dim = layer_dim

        self.lstm = nn.LSTM(input_dim, hidden_dim, layer_dim, dropout=1, batch_first=True, )
      
        self.fc = nn.Linear(hidden_dim, output_dim)
       
    def forward(self, x):
        h0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()

        c0 = torch.zeros(self.layer_dim, x.size(0), self.hidden_dim).requires_grad_()
        
        x, (hn, cn) = self.lstm(x, (h0.detach(), c0.detach()))
       
        x = self.fc(x[:, -1, :]) 
        return (x)    

***Model Training

optimizer = optim.Adam(model.parameters(), lr=0.001)

loss_func = nn.BCEWithLogitsLoss()

epochs = 2
loss_list = []

model.train()

for epoch in range(epochs):
    total_loss = []
    
    for X_tr, Y_tr in train_ldr:
  
      X_tr = X_tr.unsqueeze(1)
      
     
      Y_tr = Y_tr.type(torch.LongTensor)
      Y_tr = Y_tr.unsqueeze(1)
      
      optimizer.zero_grad()
  
      output = model(X_tr.float())

      pred = output.argmax(dim=1, keepdim=True)

     loss = loss_func(output, Y_tr.float())
         
      loss.backward()
       
      optimizer.step()
        
      total_loss.append(loss.item())

    loss_list.append(sum(total_loss)/len(total_loss))
    print('Training [{:.0f}%]\tLoss: {:.4f}'.format(
         100. * (epoch + 1) / epochs, loss_list[-1]))

Since your model creates an output in [batch_size, 2], your target would need to match this shape while using nn.BCEWithLogitsLoss. I don’t know if you are working on a multi-class or multi-label classification, but given that you are using nn.BCEWithLogitsLoss and the model output shape it seems to be a multi-label classification, where zero, one, or multiple classes can be active in each sample.

Thank you for the reply. Since new to pytorch, not able to make out that how to make the sizes equal as I m using 2 output labels.

Could you describe your use case, i.e. what do the model outputs and targets represent in each dimension and their values?

The output labels are 0, 1. In the above code, the model output is

tensor([[-0.0190, -0.0389]], grad_fn=<AddmmBackward>)

and the target is

tensor([[0]])

The target data in data loader is in form

tensor([0., 0., 0.,  ..., 1., 1., 1.])