Prince Umbrella
Prince Umbrella

Reputation: 29

RuntimeError: dimension specified as 0 but tensor has no dimensions

I was trying to Implement simple NN using the MNIST datasets and I keep getting this error import matplotlib.pyplot as plt

import torch
from torchvision import models
from torchvision import datasets, transforms
from torch import nn, optim
import torch.nn.functional as F
import helper

transform = transforms.ToTensor()

train_data = datasets.MNIST(root='data', train=True,
                                   download=True, transform=transform)
test_data = datasets.MNIST(root='data', train=False,
                                  download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_data, batch_size = 20, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_data, batch_size = 20, shuffle=True)
class Net(nn.Module):
    def __init__(self):
        super(Net,self).__init__()
        self.fc1 = nn.Linear(784,10)

    def forward(self,x):

        x = x.view(-1,784)
        x = F.relu(self.fc1(x))
        x = F.log_softmax(x, dim = 1)
        return x


model = Net()
criterion = nn.NLLLoss()
optimizer = optim.Adam(model.parameters(), lr = 0.003)

epochs = 20
model.train()
for epoch in range(epochs):
    train_loss = 0

    for image, lables in train_data:

        optimizer.zero_grad()

        output = model(image)
        loss = criterion(output, lables)
        loss.backwards()
        optimizer.step()
        train_loss += loss.item()*image.size(0)
    train_loss = train_loss/len(train_data.dataset)

    print('Epoch: {} \tTraining Loss: {:.6f}'.format(epoch+1, train_loss))

Here is the error RuntimeError: dimension specified as 0 but tensor has no dimensions

Upvotes: 2

Views: 11617

Answers (1)

Jatentaki
Jatentaki

Reputation: 13123

The issue you're hitting directly is that NLL loss expects a labels (you're spelling it lables btw) tensor of at least 1 dimension and it's getting a 0-dimensional tensor (aka a scalar). If you see this kind of messages, it's good to just print(output.shape, labels.shape) for easier inspection. The source of this error is that you, probably by mistake, run for image, labels in train_data instead of for image, labels in train_loader. The consequence is that your data is not batched - batching the scalars coming out of dataset would create the missing dimension NLLLoss complains about.

Once we fix this, we proceed to fix backwards -> backward and finally len(train_data.dataset) -> len(train_data). Then the loop works (if it's a reasonable net etc, I did not test).

As a side remark, you can combine NLLLoss and log_softmax by using CrossEntropyLoss, which has the benefit of extra numerical stability.

Upvotes: 7

Related Questions