ValueError: Expected input batch_size (440) to match target batch_size (40)

Hello!

I have created dataset for 4 diff functions. My dataset is one-hot-encoded. Basically just 40 data elements, each being a one-hot-encoded string of 11 characters. There are total of 31 mappings.

So my dataset looks like tensor of (40,11,31)

My output is a label, with one one-hot-encoded letter. e.g. h,f
so label tensor is of the size (40,1,31)

My code looks like this

Error occurs on line
loss = criterion(outputs, labels)

 ```python
import torch
import torch.nn as nn
from torch.autograd import Variable


###################### define parameters for RNN #############

inputs = Variable(torch.Tensor(input_tensors_one_hot))
labels = Variable(torch.LongTensor(tensor_of_labels))

# print(f'im inputs size {inputs.size()}' )
print(f'im labels size {labels}' )


num_classes = 31
input_size = 31  # one-hot size
hidden_size = 31  # output from the LSTM. 31 to directly predict one-hot
batch_size = 1   # one string
sequence_length = 11  # string length == 11
num_layers = 1  # one-layer rnn
# print(inputs[0])

################ Define RNN #################

class RNN(nn.Module):

    def __init__(self, num_classes, input_size, hidden_size, num_layers):
        super(RNN, self).__init__()

        self.num_classes = num_classes
        self.num_layers = num_layers
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.sequence_length = sequence_length
        self.rnn = nn.RNN(input_size=31, hidden_size=31, batch_first=True)


    def forward(self, x):
        # Initialize hidden and cell states
        # (num_layers * num_directions, batch, hidden_size) for batch_first=True
        h_0 = Variable(torch.zeros(
            self.num_layers, x.size(0), self.hidden_size))

        # Reshape input
        x.view(x.size(0), self.sequence_length, self.input_size)    
# Propagate input through RNN
        # Input: (batch, seq_len, input_size)
        # h_0: (num_layers * num_directions, batch, hidden_size)

        out, _ = self.rnn(x, h_0)
        print(f'im hidden size shape {out.size()}')

        # dense_outputs = self.fc(out)
        # print(f'im dense outputs {dense_outputs}')
        return out.reshape(-1, num_classes)
        # return out.view(-1, num_classes)


# Instantiate RNN model
rnn = RNN(num_classes, input_size, hidden_size, num_layers)
print(rnn)

# Set loss and optimizer function
# CrossEntropyLoss = LogSoftmax + NLLLoss
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(rnn.parameters(), lr=0.1)

# Train the model
for epoch in range(100):
    outputs = rnn(inputs)
    print('Im output size ', outputs.size())
    optimizer.zero_grad()
    print('Im label size ', labels.size())
    loss = criterion(outputs, labels)  
    loss.backward()
    optimizer.step()
    _, idx = outputs.max(1)
    idx = idx.data.numpy()
    # result_str = [idx2char[c] for c in idx.squeeze()]
    # print("epoch: %d, loss: %1.3f" % (epoch + 1, loss.data[0]))
    # print("Predicted string: ", ''.join(result_str))
    print("Predicted string: ", ''.join(idx))

print("Learning finished!")

This is the problem:

out has shape of (seq_len, batch, num_directions * hidden_size). You cannot simply reshape it like you do. It completely messes up you tensor.

By the way, this is a problem as well:

x.view(x.size(0), self.sequence_length, self.input_size)

See this post.

Hi Chris! Thanks for the reply.

Basically my output tensor in
out, _ = self.rnn(x, h_0)

gives (40,11,31) dimen

which after the line reshape becomes (440,31)

However, my label tensor has the shape (40,1,31),

how do I use them to calculate the loss. My input and label have diff dimensions. I am quite new at this. So, a more detailed reply is appreciated

I know that in CrossEntropyLoss()
Input has dim (N,C)
Target has dim N

How do I change my input and target to be compatible with the loss function while calculating correct loss

As you seem you go for a basic classification task, I would do the following

Use the only the last hidden state, and not out which gives you the hidden states of each time step

out, h = self.rnn(x, h_0)

h will have a shape of (num_layers * num_directions, batch, hidden_size), but since you don’t use a bidirectional RNN, it’s just (num_layers, batch, hidden_size) So to get the hidden state if the last layer you just need

h = h[-1]  # Consider only the last layer

Now the shape of h is (batch, hidden_size). Usually you now push this through at least one linear layer, say, self.fc = nn.Linear(hidden_size, num_classes:

output = self.fc(h)

output will have the shape (batch, num_classes), what is most likely what you want.

You probably still have to fix

x.view(x.size(0), self.sequence_length, self.input_size)

using permute() or transpose()

1 Like

Well thakyou Chris. Your answer helped alot :slight_smile: