Difference between target and input size

I’m new to pytorch. I tried to run this code:

import torchvision.transforms
from torch.utils.data import DataLoader
import torch.utils.data.dataloader
from torch import nn
from torchsummary import summary

def train(
        mdl,
        train_dataloader,
        valid_dataloader,
        n_epoch,
        opt,
        loss,
        valid_step,
        save_path):
    min_valid_loss = float('inf')
    mdl = mdl.cpu()

    for e in range(0, n_epoch):
        mdl.train()
        train_loss = 0.0
        for i, (inp, out) in enumerate(train_dataloader):
            opt.zero_grad()
            pred = mdl(inp)
            ls = loss(pred, out) **# error raises here**
            ls.backward()
            opt.step()
            train_loss += ls.item()

        if e % valid_step != 0:
            continue

        mdl.eval()
        valid_loss = 0.0
        with torch.no_grad():
            for i, (inp, out) in enumerate(valid_dataloader):
                pred = mdl(inp)
                ls = loss(pred, out)
                valid_loss += ls.item()

        if valid_loss < min_valid_loss:
            p = save_path.format(
                en=n_epoch,
                vl=valid_loss,
                tl=train_loss)
            torch.save(mdl, p)

            best_state = mdl.state_dict()

        print('epoch: ' + str(e + 1))
        print('train loss: ' + str(train_loss / len(train_dataloader)))
        print('valid loss: ' + str(valid_loss / len(valid_dataloader)))
        print('\n')

    return best_state


tns = torchvision.transforms.Compose([
    torchvision.transforms.ToTensor()
])
ds = torchvision.datasets.MNIST(root='data/dataset', train=True, download=True, transform=tns)
dt = DataLoader(dataset=ds, batch_size=32, shuffle=True)

model = nn.Sequential(
    nn.Conv2d(in_channels=1, out_channels=16, kernel_size=(3, 3)),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=(2, 2), stride=2),
    nn.Conv2d(in_channels=16, out_channels=32, kernel_size=(3, 3)),
    nn.ReLU(),
    nn.MaxPool2d(kernel_size=(2, 2), stride=2),
    nn.Flatten(start_dim=1, end_dim=-1),
    nn.Linear(800, 10),
    nn.LogSoftmax())

summary(model)

train(
    mdl=model,
    train_dataloader=dt,
    valid_dataloader=dt,
    n_epoch=10,
    opt=torch.optim.Adam(params=model.parameters(), lr=0.1),
    loss=nn.BCELoss(),
    valid_step=10,
    save_path='')

but I got this error:

ValueError: Using a target size (torch.Size([32])) that is different to the input size (torch.Size([32, 10])) is deprecated. Please ensure they have the same size.

I know this is because of mismatch size between input size for loss function and out of predicted values. How can I fix this problem?

MNIST is a multi-class classification dataset where each sample belongs to 1 of 10 targets.
Your model looks alright and you should use nn.NLLLoss as the criterion instead of nn.BCELoss (which is used for a binary classification or a multi-label classification where each target belongs to 0, 1, or multiple classes).

1 Like