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.
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
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
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