Error: RNN Expected input Batch_size

Hello everyone!
first of all this forum helped me so much in the past few days… Thank you very much for all the good posts and answers!

Now I have a problem I couldn’t find in a post…

I’m currently working on a RNN network for classification of images. I tried CNN but the images are signals not “normal” Images. I need to track them over time. (but that problem comes later)

the Images/Signals are 128x64

# init
num_classes = 2  
num_epochs = 10
batch_size = 4
learning_rate = 0.001

# input size and sequence length are the Image dimension
input_size = 128 # tried both ways same error
sequence_length = 64
hidden_size = 128
num_layers = 2

the data is loaded over

trainset = torchvision.datasets.ImageFolder(root="/PATH",
                                            transform=transforms.ToTensor())
validation = torchvision.datasets.ImageFolder(root="/PATH",
                                              transform=transforms.ToTensor())

trainloader = torch.utils.data.DataLoader(dataset = trainset,
                                          batch_size = batch_size,
                                          shuffle=False)

validationloader = torch.utils.data.DataLoader(dataset = validation,
                                               batch_size = batch_size,
                                               shuffle=False)

My class

class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, num_classes):
        super(RNN, self).__init__()
        self.num_layers = num_layers
        self.hidden_size = hidden_size
        self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)
        # -> x : (batch_size, seq, input_size)

        self.fc = nn.Linear(hidden_size, num_classes)


    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(device)
        print(x.size(0)) # outputs: 12

        # Forward propagate RNN
        out, _ = self.rnn(x, h0)
       

        # out: tensor of shape (batch_size, seq_length, hidden_size)
        print(x.shape) # outputs: torch.Size([12, 64, 128])

        out = out[:, -1, :]

        out = self.fc(out)
        return out

the Error i’m getting is:

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

I know the problem is that the size from x is 12 and the batch_size is 4… but if i change batch_size to 12 the Error still remains just with 36… Somehow my batch_size is 3 times to big for the input (if I see this right?)

training loop

net = RNN(input_size, hidden_size, num_layers, num_classes).to(device)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=learning_rate)

# train the model
for epoch in range(10):  # loop over the dataset multiple times
    print("epoche: ", epoch)
    running_loss = 0.0
    for i, (images, labels) in enumerate(trainloader):
        # origin shape: [N, 1, 64, 128]
        # resized: [N, 64, 128]
        images = images.reshape(-1, sequence_length, input_size).to(device)
        labels = labels.to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 100 == 99:    # print every 200 mini-batches
            print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

EDIT: If I try the whole RNN with a MNIST (input_size: 28 / sequence_length: 28)dataset it works just fine (28x28)

Thanks all!

I cannot reproduce the issue using your code snippet and get a valid output with a batch size of 4, which should be expected.
I’m using this code snippet based on the posted code:

# init
num_classes = 2  
num_epochs = 10
batch_size = 4
learning_rate = 0.001

# input size and sequence length are the Image dimension
input_size = 128 # tried both ways same error
sequence_length = 64
hidden_size = 128
num_layers = 2

class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, num_classes):
        super(RNN, self).__init__()
        self.num_layers = num_layers
        self.hidden_size = hidden_size
        self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True)
        # -> x : (batch_size, seq, input_size)

        self.fc = nn.Linear(hidden_size, num_classes)


    def forward(self, x):
        h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
        print(x.size(0)) # outputs: 12

        # Forward propagate RNN
        out, _ = self.rnn(x, h0)
       

        # out: tensor of shape (batch_size, seq_length, hidden_size)
        print(x.shape) # outputs: torch.Size([12, 64, 128])

        out = out[:, -1, :]

        out = self.fc(out)
        return out

net = RNN(input_size, hidden_size, num_layers, num_classes)
# origin shape: [N, 1, 64, 128]
# resized: [N, 64, 128]
images = torch.randn(batch_size, 1, 64, 128)
images = images.reshape(-1, sequence_length, input_size)
print(images.shape)
> torch.Size([4, 64, 128])

outputs = net(images)
print(outputs.shape)
> torch.Size([4, 2])

Thank you for your answer and for running the code!
I think the images are somehow the problem… I’ll test more, if I find the error I’ll post it!
Just to be sure does the amount of images i have in the folder matter?

Since it’s a shape mismatch I guess that some reshaping operation is wrong in the code.
Could you post the shape of the data you are getting and compare it to my code?

Thanks for your answer.
My original error didn’t pop up any more after I upgraded my system. Not a single change in the code.
If I print the shape of the data with batch_size = 1 its [3,64, 128]
with batch_size = 4 the [3, 68, 522] so not exactly 4 times more. And the fact that its a 3 channel not just 1 channel. But that I will try to change directly from the source of the data.

What I’m getting now is the error:

RuntimeError: The size of tensor a (2) must match the size of tensor b (4) at non-singleton dimension 1

when I change the batch_size to 2 i will train (extremely poorly loss starts at 0.011) but at the end of the program I get the same error again with tensor a (6) and tensor b (2)

RuntimeError: The size of tensor a (6) must match the size of tensor b (2) at non-singleton dimension 0