ValueError: Expected input batch_size (1) to match target batch_size (4)

I am not understanding what this exception means or how to fix it?

I am building the following convolutional neural network with 3 convolutional layers and 2 fully connected layers:

import torch

import torchvision

import torchvision.transforms as transforms

import torch.nn as nn

import torch.nn.functional as F

import torch.optim as optim

transform = transforms.Compose(

    [transforms.ToTensor(),

     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,

                                        download=True, transform=transform)

trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,

                                          shuffle=True, num_workers=0)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,

                                       download=True, transform=transform)

testloader = torch.utils.data.DataLoader(testset, batch_size=4,

                                         shuffle=False, num_workers=0)

classes = ('plane', 'car', 'bird', 'cat',

           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')


# -------------- Define a convolutional neural network (CNN) -------------

class Net(nn.Module):

    def __init__(self):

        super(Net, self).__init__()

        self.conv1 = nn.Conv2d(3, 6, 5)

        self.pool = nn.MaxPool2d(2, 2)

        self.conv2 = nn.Conv2d(6, 16, 5)

        self.conv3 = nn.Conv2d(16, 32, 5)

        self.fc1 = nn.Linear(32 * 2 * 2, 120)

        self.fc2 = nn.Linear(120, 84)        

    def forward(self, x):

        x = self.pool(F.elu(self.conv1(x)))       

        x = self.pool(F.elu(self.conv2(x)))          

        x = F.elu(self.conv3(x))     

        x = x.view(-1, 32 * 2 * 2)    

        x = F.elu(self.fc1(x))      

        x = self.fc2(x)      

        return x

net = Net()

# ------------------------ Define a loss (distance) function and optimizer----------------------

criterion = nn.CrossEntropyLoss()

optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

# ------------------------ Train the network -------------------------

for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0

    for i, data in enumerate(trainloader, 0):

        # get the inputs; data is a list of [inputs, labels]

        inputs, labels = data

        # zero the parameter gradients

        optimizer.zero_grad()

        # forward + backward + optimize

        outputs = net(inputs)

        loss = criterion(outputs, labels)

        loss.backward()

        optimizer.step()

        # print statistics

        running_loss += loss.item()

        if i % 2000 == 1999:    # print every 2000 mini-batches

            print('[%d, %5d] loss: %.3f' %

                  (epoch + 1, i + 1, running_loss / 2000))

            running_loss = 0.0

print('Finished Training')

# ----------- Save model -------------

PATH = './cifar_net.pth'

torch.save(net.state_dict(), PATH)

But am getting the following error

ValueError: Expected input batch_size (1) to match target batch_size (4).

Any advice is greatly appreciated!

EDIT: I printed the shape of x before my view and discovered it was:
torch.Size([4, 32, 1, 1])
So I changed my linear layer to
self.fc1 = nn.Linear(32 * 1 * 1, 120)
and my view to
x = x.view(-1, 32 * 1 * 1)
and it seemed to train successfully… if someone could please verify this is accurate, I would appreciate it! Thanks for your time reading this :slight_smile:

Yes, your explanation makes sense and I also wanted to point to the view operation, which was most likely wrong.
I would generally recommend to use x = x.view(x.size(0), -1) to keep the batch dimension equal and to flatten the “additional” dimensions. This would then raise a shape mismatch in the linear layer, which is sometimes easier to debug than a batch size mismatch.