Trying to print class names for dog breed but it keeps saying list index out of range
I am using a resnet model to classify dog breeds but when I try to print out an image with the label of dog breed it says list index out of range. 
Here is my code:

import torchvision.models as models
import torch.nn as nn


model_transfer = models.resnet18(pretrained=True)

if use_cuda:
    model_transfer = model_transfer.cuda()

model_transfer.fc.out_features = 133


Then I train the model and get over 70% accuracy on the dog breeds. 

Then here is my code to classify dog and print the dog breed:

data_transfer = {'train': 
 datasets.ImageFolder('/data/dog_images/train',transform=transforms.Compose([transforms.RandomResizedCrop(224),transforms.ToTensor()]))}
class_names[0]
class_names = [item[4:].replace("_", " ") for item in data_transfer['train'].classes]

def predict_breed_transfer(img_path):

    image = Image.open(img_path)

    # large images will slow down processing


    in_transform = transforms.Compose([
                        transforms.CenterCrop(224),
                        transforms.ToTensor(),
                        transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                             std=[0.229, 0.224, 0.225])])

    # discard the transparent, alpha channel (that's the :3) and add the batch dimension
    image = in_transform(image)[:3,:,:].unsqueeze(0)

    image = image

    output = model_transfer(image)
    pred = torch.argmax(output)

    return class_names[pred]
    predict_breed_transfer('images/Labrador_retriever_06455.jpg')


The code always predicts the dog wrong for some reason 
Then when I try to print out the image and the label:

import matplotlib.pyplot as plt
def run_app(img_path):
    img = Image.open(img_path)
    dog = dog_detector(img_path)
    if not dog: 
        print('hello, human!')
        plt.imshow(img)
        print('You look like a ... ')
        print(predict_breed_transfer(img_path))
    if dog: 
        print('hello, dog!')
        print('Your predicted breed is ....')
        print(predict_breed_transfer(img_path))
        plt.imshow(img)
    else: 
        print('Niether human nor dog')


And run a for loop that calls it on some dog images it will print some of the breeds out then it will say list index out of range and doesn't show any of the images. 

The length of class_names is 133
And when I print out the resnet model the output is only 133 nodes does anyone know why it is saying list index out of range or why it is so inaccurate. 

`IndexError                                Traceback (most recent 
call last)
&lt;ipython-input-26-473a9ba884b5&gt; in &lt;module&gt;()
      5 ## suggested code, below
      6 for file in np.hstack((human_files[:3], dog_files[:3])):
----&gt; 7     run_app(file)
      8 
 &lt;ipython-input-25-1d44200e44cc&gt; in run_app(img_path)
      10         plt.show(img)
      11         print('You look like a ... ')
 ---&gt; 12         print(predict_breed_transfer(img_path))
      13     if dog:
      14         print('hello, dog!')

 &lt;ipython-input-20-a51fb205659e&gt; in predict_breed_transfer(img_path)
      26     pred = torch.argmax(output)
      27 
 ---&gt; 28     return class_names[pred]
      29 
predict_breed_transfer('images/Labrador_retriever_06455.jpg')
      30 

IndexError: list index out of range`


Here is the full error

I suppose you have several issues that can be fixed using 13 chars.

First, I suggest what @Alekhya Vemavarapu suggested - run your code with a debugger to isolate each line and inspect the output. This is one of the greatest benefits of dynamic graphs with pytorch.

Secondly, the most probable cause for your issue is the argmax statement that you use incorrectly. You do not specify the dimension you perform the argmax on, and therefore PyTorch automatically flattens the image and perform the operation on the full length vector. Thus, you get a number between 0 and MB_Size x num_classes -1. See Official doc on this method.

So, due to your fully connected layer I assume your output is of shape (MB_Size, num_classes). If so, you need to change your code to the following line:

pred = torch.argmax(output,dim=1)


and thats it. Otherwise, just choose the dimension of the logits.

Third thing you want to consider is the dropout and other influences that a training configuration may cause to the inference. For instance, the dropout in some frameworks may require multiplying the ouptut by 1/(1-p) in the inference (or not since it can be done while training), batch normalization may be cancelled since the batch size is different, and so on. Additionally, to reduce memory consumption, no gradients should be computed. Luckily, PyTorch developers are very thoughtful and provided us with torch.no_grad() and model.eval() for that. 

I strongly suggest to have a practice for that, possibly changing your code with a few letters:

output = model_transfer.eval()(image)


and your done!

Edit:
This is a simple use case of wrong usage of the PyTorch framework, not reading the docs and not debugging your code. The following code is purely incorrect:

model_transfer.fc.out_features = 133


This line does not actually creates a new fully connected layer. It just changes the property of that tensor. Try in your console: 

import torch
a = torch.nn.Linear(1,2)
a.out_features = 3
print(a.bias.data.shape, a.weight.data.shape)


Output:

torch.Size([2]) torch.Size([2, 1])


which indicates that the actual matrix of the weights and the biases vector remain in their original dimension.
A correct way to perform transfer learning is to keep the backbone (usually the convolutional layers until the fully connected ones in these type of models) and overwriting the head (FC layer in this case) with yours. If it is just one fully connected layer that exists in the original model, you do not have to change the forward pass of your model and you're good to go. 
Since this answer is already long enough, just visit the Transfer learning tutorial in PyTorch docs to see how it can be done.

Good luck to ya'll.
