Resnet is not giving me any accuracy

Well, while using Desnsenet169, I am getting proper accuracies, but in the case of ResNet - 101/50, I am not getting any accuracies. It is printing like this -

Here is a little glimpse of my code -

device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

model = models.resnet101(pretrained=True)

for param in model.parameters():
    param.requires_grad = True

model.classifier = nn.Sequential(nn.Linear(2048, 1024),
                             nn.ReLU(),
                             nn.Dropout(0.4),
                             nn.Linear(1024,4),
                             nn.LogSoftmax(dim=1))

for epoch in range(epochs):

  running_loss = 0
  model.train()
  for images, labels in dataloader_train:

    #steps += 1
    images, labels = images.to(device), labels.to(device)

    optimizer.zero_grad()

    output = model.forward(images)
    loss = criterion(output, labels)
    loss.backward()
    optimizer.step()

    running_loss += loss.item()

  #if steps % print_every == 0:
  valid_loss = 0
  accuracy = 0
  model.eval()
  for images, labels in dataloader_test:
    optimizer.zero_grad()
    with torch.no_grad():
   
      images, labels = images.to(device), labels.to(device)

      output = model.forward(images)
      loss = criterion(output, labels)
      
      valid_loss += loss.item()
      
      ps = torch.exp(output)
     
      top_p, top_class = ps.topk(1, dim = 1)
      equals = top_class == labels.view(*top_class.shape)
      accuracy += torch.mean(equals.type(torch.FloatTensor))
   
  print("Accuracy: {:.4f}.. " .format(accuracy/len(dataloader_test)))
  model.train()

Can you guys please help me to do this with getting proper accuracies? Thank you.

I suppose you should define a new class that inherits nn.Module to feed your model.classifier module in your custom forward function. Otherwise, please replace model.classifier in your current code with model.fc and run the optimization again.

Hey, you are right, when I changed it to model.fc from classifier, it worked. But how? What is the difference between them? can you please explain or give me something to study about it. Also I am about to experiment it in inception-v3, should I use model.fc or classifier? Thanks though.

Try to print your pretrained model after loading, with print(model), and see what modules it contains currently. You will see that torchvision Resnet models contain a module named fc in the final layer. What you are trying to do is to fine-tune this layer. So, you don’t have to create a new classifier module, recreating your fc module would suffice. Do the same printing for inception-v3. This will give you a hint what layers you need to recreate. Try to read more on transfer learning or fine tuning in PyTorch.

1 Like

I get these 0 accuracy issues a lot by accident if I am not careful. I.e., make sure that in

op_class == labels.view(*top_class.shape)

both are flat arrays or have the same dimension if you have multiple labels. For example, if one is a [n_examples, 1] array and one a [n_examples] array, bad things can happen. Maybe just add an assert

assert op_class.size() == labels.view(*top_class.shape).size()

before that line to rule that out.

sir can you please elaborate this labels array one, I didn’t understand properly, new to this. Thanks.

Sure, maybe this can be best explained by an example:

In [1]: import torch                                                            

In [2]: a = torch.tensor([1, 2, 3])                                             

In [3]: b = a.clone().view(-1, 1)                                               

In [4]: b                                                                       
Out[4]: 
tensor([[1],
        [2],
        [3]])

In [5]: a == b                                                                  
Out[5]: 
tensor([[1, 0, 0],
        [0, 1, 0],
        [0, 0, 1]], dtype=torch.uint8)

I am not sure if this is an issue in your case, but adding a

assert op_class.size() == labels.view(*top_class.shape).size()

just to make sure doesn’t hurt :slight_smile:

1 Like

Basically it is complexly easy. So, basically it is size matching. to maintain proper size to make it work properly. Right?

Yes exactly. Not sure if it’s fortunately or unfortunately, but it works in cases like I’ve shown above, so if you don’t match the sizes, you will still get results, but different results. Basically a “silent” bug, which is maybe why adding asserts during debugging may be helpful for finding the root of that problem

1 Like

Thank you guys for helping. This is really informative.