title: vgg probability doesn't add up to 1, pytorch
body: <p>I've trained a vgg16 model to predict 102 classes of flowers.
  It works however now that I'm trying to understand one of it's predictions I feel it's not acting normally.</p>
  
  <h1>model layout</h1>
  
  <pre><code># Imports here
  import os
  import numpy as np
  import torch
  
  import torchvision
  from torchvision import datasets, models, transforms
  import matplotlib.pyplot as plt
  import json
  from pprint import pprint
  from scipy import misc
  
  %matplotlib inline
  
  data_dir = 'flower_data'
  train_dir = data_dir + '/train'
  test_dir = data_dir + '/valid'
  
  json_data=open('cat_to_name.json').read()
  main_classes = json.loads(json_data)
  main_classes = {int(k):v for k,v in classes.items()}
  
  train_transform_2 = transforms.Compose([transforms.RandomResizedCrop(224), 
                                      transforms.RandomRotation(30),
                                      transforms.RandomHorizontalFlip(),
                                      transforms.ToTensor()])
  
  test_transform_2= transforms.Compose([transforms.RandomResizedCrop(224), 
                                      transforms.ToTensor()])
  
  # TODO: Load the datasets with ImageFolder
  train_data = datasets.ImageFolder(train_dir, transform=train_transform_2)
  test_data = datasets.ImageFolder(test_dir, transform=test_transform_2)
  
  # define dataloader parameters
  batch_size = 20
  num_workers=0
  
  # TODO: Using the image datasets and the trainforms, define the dataloaders
  train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, 
                                          num_workers=num_workers, shuffle=True)
  test_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, 
                                          num_workers=num_workers, shuffle=True)
  
  vgg16 = models.vgg16(pretrained=True)
  
  # Freeze training for all "features" layers
  for param in vgg16.features.parameters():
      param.requires_grad = False
  
  import torch.nn as nn
  
  n_inputs = vgg16.classifier[6].in_features
  
  # add last linear layer (n_inputs -&gt; 102 flower classes)
  # new layers automatically have requires_grad = True
  last_layer = nn.Linear(n_inputs, len(classes))
  
  vgg16.classifier[6] = last_layer
  
  import torch.optim as optim
  
  # specify loss function (categorical cross-entropy)
  criterion = nn.CrossEntropyLoss()
  
  # specify optimizer (stochastic gradient descent) and learning rate = 0.001
  optimizer = optim.SGD(vgg16.classifier.parameters(), lr=0.001)
  
  pre_trained_model=torch.load("model.pt")
  new=list(pre_trained_model.items())
  
  my_model_kvpair=vgg16.state_dict()
  count=0
  
  for key,value in my_model_kvpair.items():
      layer_name, weights = new[count]      
      my_model_kvpair[key] = weights
      count+=1
  
  # number of epochs to train the model
  n_epochs = 6
  
  # initialize tracker for minimum validation loss
  valid_loss_min = np.Inf # set initial "min" to infinity
  
  for epoch in range(1, n_epochs+1):
  
      # keep track of training and validation loss
      train_loss = 0.0
      valid_loss = 0.0
  
      ###################
      # train the model #
      ###################
      # model by default is set to train
      vgg16.train()
  
      for batch_i, (data, target) in enumerate(train_loader):
          # clear the gradients of all optimized variables
          optimizer.zero_grad()
          # forward pass: compute predicted outputs by passing inputs to the model
          output = vgg16(data)
          # calculate the batch loss
          loss = criterion(output, target)
          # backward pass: compute gradient of the loss with respect to model parameters
          loss.backward()
          # perform a single optimization step (parameter update)
          optimizer.step()
          # update training loss 
          train_loss += loss.item()
  
          if batch_i % 20 == 19:    # print training loss every specified number of mini-batches
              print('Epoch %d, Batch %d loss: %.16f' %
                  (epoch, batch_i + 1, train_loss / 20))
              train_loss = 0.0
  
      ######################    
      # validate the model #
      ######################
      vgg16.eval() # prep model for evaluation
      for data, target in test_loader:
          # forward pass: compute predicted outputs by passing inputs to the model
          output = vgg16(data)
          # calculate the loss
          loss = criterion(output, target)
          # update running validation loss 
          valid_loss += loss.item()
  
      # print training/validation statistics 
      # calculate average loss over an epoch
      train_loss = train_loss/len(train_loader.dataset)
      valid_loss = valid_loss/len(test_loader.dataset)
  
      print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format(
          epoch+1, 
          train_loss,
          valid_loss
          ))
  
      # save model if validation loss has decreased
      if valid_loss &lt;= valid_loss_min:
          print('Validation loss decreased ({:.6f} --&gt; {:.6f}).  Saving model ...'.format(
          valid_loss_min,
          valid_loss))
          torch.save(vgg16.state_dict(), 'model.pt')
          valid_loss_min = valid_loss
  </code></pre>
  
  <h1>testing on a single image</h1>
  
  <pre><code>tensor = torch.from_numpy(test_image)
  reshaped = tensor.permute(2, 0, 1).unsqueeze(0)
  floatified = reshaped.to(torch.float32) / 255
  vgg16(floatified)
  &gt;&gt;&gt;
  tensor([[ 2.5686, -1.1964, -0.0872, -1.7010, -1.6669, -1.0638,  0.4515,  0.1124,
            0.0166,  0.3156,  1.1699,  1.5374,  1.8720,  2.5184,  2.9046, -0.8241,
           -1.1949, -0.5700,  0.8692, -1.0485,  0.0390, -1.3783, -3.4632, -0.0143,
            1.0986,  0.2667, -1.1127, -0.8515,  0.7759, -0.7528,  1.6366, -0.1170,
           -0.4983, -2.6970,  0.7545,  0.0188,  0.1094,  0.5002,  0.8838, -0.0006,
           -1.7993, -1.3706,  0.4964, -0.3251, -1.7313,  1.8731,  2.4963,  1.1713,
           -1.5726,  1.5476,  3.9576,  0.7388,  0.0228,  0.3947, -1.7237, -1.8350,
           -2.0297,  1.4088, -1.3469,  1.6128, -1.0851,  2.0257,  0.5881,  0.7498,
            0.0738,  2.0592,  1.8034, -0.5468,  1.9512,  0.4534,  0.7746, -1.0465,
           -0.7254,  0.3333, -1.6506, -0.4242,  1.9529, -0.4542,  0.2396, -1.6804,
           -2.7987, -0.6367, -0.3599,  1.0102,  2.6319,  0.8305, -1.4333,  3.3043,
           -0.4021, -0.4877,  0.9125,  0.0607, -1.0326,  1.3186, -2.5861,  0.1211,
           -2.3177, -1.5040,  1.0416,  1.4008,  1.4225, -2.7291]],
         grad_fn=&lt;ThAddmmBackward&gt;)
  
  sum([ 2.5686, -1.1964, -0.0872, -1.7010, -1.6669, -1.0638,  0.4515,  0.1124,
            0.0166,  0.3156,  1.1699,  1.5374,  1.8720,  2.5184,  2.9046, -0.8241,
           -1.1949, -0.5700,  0.8692, -1.0485,  0.0390, -1.3783, -3.4632, -0.0143,
            1.0986,  0.2667, -1.1127, -0.8515,  0.7759, -0.7528,  1.6366, -0.1170,
           -0.4983, -2.6970,  0.7545,  0.0188,  0.1094,  0.5002,  0.8838, -0.0006,
           -1.7993, -1.3706,  0.4964, -0.3251, -1.7313,  1.8731,  2.4963,  1.1713,
           -1.5726,  1.5476,  3.9576,  0.7388,  0.0228,  0.3947, -1.7237, -1.8350,
           -2.0297,  1.4088, -1.3469,  1.6128, -1.0851,  2.0257,  0.5881,  0.7498,
            0.0738,  2.0592,  1.8034, -0.5468,  1.9512,  0.4534,  0.7746, -1.0465,
           -0.7254,  0.3333, -1.6506, -0.4242,  1.9529, -0.4542,  0.2396, -1.6804,
           -2.7987, -0.6367, -0.3599,  1.0102,  2.6319,  0.8305, -1.4333,  3.3043,
           -0.4021, -0.4877,  0.9125,  0.0607, -1.0326,  1.3186, -2.5861,  0.1211,
           -2.3177, -1.5040,  1.0416,  1.4008,  1.4225, -2.7291])
  &gt;&gt;&gt;
  5.325799999999998
  </code></pre>
  
  <p>given this as how I test it on a single image (and the model as usual is trained and tested on batches it returns a prediction matrix that doesn't seem to be normalized or add up to 1.</p>
  
  <p>Is this normal?</p>