Help with writing out neural network inference test code

For this SqueezeNet Pruning python code , What do ‘batch’ and ‘label’ do ? I have printed them out, but I cannot figure it out

Hi, @promach if you need any help with inference code, you can check the example of my code @


You’ll find a code named inference.py

batch and label are two variables that has been used to extrapolate data from the test_loaders
Labels has the class_name and batch probably has the images

1 Like

How do I modify this line to use my own pruned model instead those defined in the torchvision library ?

Say suppose you have a class where your architecture is defined like:

change

model = resnet18(pretrained=True, num_classes=10)

to

model = Your_Net(num_classes=10)

In your code I guess

model = ModifiedSqueezeNetModel(num_classes = .... )
1 Like

Hmm… I am not sure what else I should put in place of

model = ModifiedSqueezeNetModel(num_classes = int(args.num_classes))

[phung@archlinux SqueezeNet-Pruning]$ python predict.py --image “3_100.jpg” --model “model_prunned” --num_class “2”
Traceback (most recent call last):
File “predict.py”, line 23, in
checkpoint = torch.load(path_to_model)
File “/usr/lib/python3.7/site-packages/torch/serialization.py”, line 358, in load
return _load(f, map_location, pickle_module)
File “/usr/lib/python3.7/site-packages/torch/serialization.py”, line 529, in _load
result = unpickler.load()
AttributeError: Can’t get attribute ‘ModifiedSqueezeNetModel’ on <module ‘main’ from ‘predict.py’>
[phung@archlinux SqueezeNet-Pruning]$

#Modified from https://github.com/amrit-das/Custom-Model-Training-PyTorch/blob/master/predict.py
import torch
import torch.nn as nn
#from torchvision.models import resnet18
from torchvision.transforms import transforms
import matplotlib.pyplot as plt
import numpy as np
from torch.autograd import Variable
import torch.functional as F
from PIL import Image
import os
import sys
import argparse
from prune import *

parser = argparse.ArgumentParser(description = 'To Predict from a trained model')
parser.add_argument('-i','--image', dest = 'image_name', required = True, help='Path to the image file')
parser.add_argument('-m','--model', dest = 'model_name', required = True, help='Path to the model')
parser.add_argument('-n','--num_class',dest = 'num_classes', required = True, help='Number of training classes')
args = parser.parse_args()

path_to_model = "./"+args.model_name
checkpoint = torch.load(path_to_model)

model = ModifiedSqueezeNetModel(num_classes = int(args.num_classes))
#model = resnet18(num_classes = int(args.num_classes))
model.load_state_dict(checkpoint)
model.eval()

def predict_image(image_path):
    print("prediciton in progress")
    image = Image.open(image_path)
    transformation = transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])
    image_tensor = transformation(image).float()
    image_tensor = image_tensor.unsqueeze_(0)

    if torch.cuda.is_available():
        image_tensor.cuda()

    input = Variable(image_tensor)
    output = model(input)

    index = output.data.numpy().argmax()
    return index

def class_mapping(index):
    mapping=open('class_mapping.txt','r')
    class_map={}
    for line in mapping:
        l=line.strip('\n').split('~')
        class_map[l[1]]=l[0]
    return class_map[str(index)]

if __name__ == "__main__":

    imagepath = "./test/Lemon/"+args.image_name
    prediction = predict_image(imagepath)
    name = class_mapping(prediction)
    print("Predicted Class: ",name)

I have solved the above class problem using

from finetune import *

because the saved model is in finetune.py

@Amrit_Das Did you encounter the following cpu/gpu backend error ? and how to go around it ?

[phung@archlinux SqueezeNet-Pruning]$ python predict.py --image “3_100.jpg” --model “model_prunned” --num_class “2”
prediction in progress
Traceback (most recent call last):
File “predict.py”, line 63, in
prediction = predict_image(imagepath)
File “predict.py”, line 47, in predict_image
output = model(input)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 477, in call
result = self.forward(*input, **kwargs)
File “/home/phung/Documents/Grive/Personal/Coursera/Machine_Learning/pruning/Pruning-CNN/SqueezeNet-Pruning/finetune.py”, line 39, in forward
x = self.features(x)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 477, in call
result = self.forward(*input, **kwargs)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/container.py”, line 92, in forward
input = module(input)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 477, in call
result = self.forward(*input, **kwargs)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/conv.py”, line 313, in forward
self.padding, self.dilation, self.groups)
RuntimeError: Expected object of backend CPU but got backend CUDA for argument #2 ‘weight’
[phung@archlinux SqueezeNet-Pruning]$

Please refer to this Issue

[phung@archlinux ~]$ python -c “import torch; print(torch.version)”
1.0.0a0+ff608a9
[phung@archlinux ~]$

I am now using pytorch version 1.0 where the error had already been solved in version 0.40 in May 2018.

This is the modification I made to your predict.py

Could you duplicate the same error using original code version and my modified code version ?

The correct way for using a model for inference is

model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()

You have modified this part which I guess is causing th error.

https://pytorch.org/tutorials/beginner/saving_loading_models.html

Following your advice and a recent commit by the pytorch-pruning original author, I managed to get past cpu/gpu backend error. Now, I am facing some squeezenet tensor size mismatch issues:

[phung@archlinux SqueezeNet-Pruning]$ python predict.py --image 3_100.jpg --model model_prunned --num_class 2
/usr/lib/python3.7/site-packages/torchvision/models/squeezenet.py:94: UserWarning: nn.init.kaiming_uniform is now deprecated in favor of nn.init.kaiming_uniform_.
init.kaiming_uniform(m.weight.data)
/usr/lib/python3.7/site-packages/torchvision/models/squeezenet.py:92: UserWarning: nn.init.normal is now deprecated in favor of nn.init.normal_.
init.normal(m.weight.data, mean=0.0, std=0.01)
Traceback (most recent call last):
File “predict.py”, line 29, in
model.load_state_dict(checkpoint)
File “/usr/lib/python3.7/site-packages/torch/nn/modules/module.py”, line 723, in load_state_dict
self.class.name, “\n\t”.join(error_msgs)))
RuntimeError: Error(s) in loading state_dict for ModifiedSqueezeNetModel:
size mismatch for features.0.weight: copying a param of torch.Size([31, 3, 3, 3]) from checkpoint, where the shape is torch.Size([64, 3, 3, 3]) in current model.
size mismatch for features.0.bias: copying a param of torch.Size([31]) from checkpoint, where the shape is torch.Size([64]) in current model.
size mismatch for features.3.squeeze.weight: copying a param of torch.Size([16, 31, 1, 1]) from checkpoint, where the shape is torch.Size([16, 64, 1, 1]) in current model.
size mismatch for features.3.expand1x1.weight: copying a param of torch.Size([46, 16, 1, 1]) from checkpoint, where the shape is torch.Size([64, 16, 1, 1]) in current model.
size mismatch for features.3.expand1x1.bias: copying a param of torch.Size([46]) from checkpoint, where the shape is torch.Size([64]) in current model.
size mismatch for features.3.expand3x3.weight: copying a param of torch.Size([45, 16, 3, 3]) from checkpoint, where the shape is torch.Size([64, 16, 3, 3]) in current model.
size mismatch for features.3.expand3x3.bias: copying a param of torch.Size([45]) from checkpoint, where the shape is torch.Size([64]) in current model.
size mismatch for features.4.squeeze.weight: copying a param of torch.Size([16, 91, 1, 1]) from checkpoint, where the shape is torch.Size([16, 128, 1, 1]) in current model.
size mismatch for features.4.expand1x1.weight: copying a param of torch.Size([33, 16, 1, 1]) from checkpoint, where the shape is torch.Size([64, 16, 1, 1]) in current model.
size mismatch for features.4.expand1x1.bias: copying a param of torch.Size([33]) from checkpoint, where the shape is torch.Size([64]) in current model.
size mismatch for features.4.expand3x3.weight: copying a param of torch.Size([28, 16, 3, 3]) from checkpoint, where the shape is torch.Size([64, 16, 3, 3]) in current model.
size mismatch for features.4.expand3x3.bias: copying a param of torch.Size([28]) from checkpoint, where the shape is torch.Size([64]) in current model.
size mismatch for features.6.squeeze.weight: copying a param of torch.Size([32, 61, 1, 1]) from checkpoint, where the shape is torch.Size([32, 128, 1, 1]) in current model.
size mismatch for features.6.expand1x1.weight: copying a param of torch.Size([83, 32, 1, 1]) from checkpoint, where the shape is torch.Size([128, 32, 1, 1]) in current model.
size mismatch for features.6.expand1x1.bias: copying a param of torch.Size([83]) from checkpoint, where the shape is torch.Size([128]) in current model.
size mismatch for features.6.expand3x3.weight: copying a param of torch.Size([60, 32, 3, 3]) from checkpoint, where the shape is torch.Size([128, 32, 3, 3]) in current model.
size mismatch for features.6.expand3x3.bias: copying a param of torch.Size([60]) from checkpoint, where the shape is torch.Size([128]) in current model.
size mismatch for features.7.squeeze.weight: copying a param of torch.Size([32, 143, 1, 1]) from checkpoint, where the shape is torch.Size([32, 256, 1, 1]) in current model.
size mismatch for features.7.expand1x1.weight: copying a param of torch.Size([69, 32, 1, 1]) from checkpoint, where the shape is torch.Size([128, 32, 1, 1]) in current model.
size mismatch for features.7.expand1x1.bias: copying a param of torch.Size([69]) from checkpoint, where the shape is torch.Size([128]) in current model.
size mismatch for features.7.expand3x3.weight: copying a param of torch.Size([46, 32, 3, 3]) from checkpoint, where the shape is torch.Size([128, 32, 3, 3]) in current model.
size mismatch for features.7.expand3x3.bias: copying a param of torch.Size([46]) from checkpoint, where the shape is torch.Size([128]) in current model.
size mismatch for features.9.squeeze.weight: copying a param of torch.Size([48, 115, 1, 1]) from checkpoint, where the shape is torch.Size([48, 256, 1, 1]) in current model.
size mismatch for features.9.expand1x1.weight: copying a param of torch.Size([84, 48, 1, 1]) from checkpoint, where the shape is torch.Size([192, 48, 1, 1]) in current model.
size mismatch for features.9.expand1x1.bias: copying a param of torch.Size([84]) from checkpoint, where the shape is torch.Size([192]) in current model.
size mismatch for features.9.expand3x3.weight: copying a param of torch.Size([80, 48, 3, 3]) from checkpoint, where the shape is torch.Size([192, 48, 3, 3]) in current model.
size mismatch for features.9.expand3x3.bias: copying a param of torch.Size([80]) from checkpoint, where the shape is torch.Size([192]) in current model.
size mismatch for features.10.squeeze.weight: copying a param of torch.Size([48, 164, 1, 1]) from checkpoint, where the shape is torch.Size([48, 384, 1, 1]) in current model.
size mismatch for features.10.expand1x1.weight: copying a param of torch.Size([75, 48, 1, 1]) from checkpoint, where the shape is torch.Size([192, 48, 1, 1]) in current model.
size mismatch for features.10.expand1x1.bias: copying a param of torch.Size([75]) from checkpoint, where the shape is torch.Size([192]) in current model.
size mismatch for features.10.expand3x3.weight: copying a param of torch.Size([81, 48, 3, 3]) from checkpoint, where the shape is torch.Size([192, 48, 3, 3]) in current model.
size mismatch for features.10.expand3x3.bias: copying a param of torch.Size([81]) from checkpoint, where the shape is torch.Size([192]) in current model.
size mismatch for features.11.squeeze.weight: copying a param of torch.Size([64, 156, 1, 1]) from checkpoint, where the shape is torch.Size([64, 384, 1, 1]) in current model.
size mismatch for features.11.expand1x1.weight: copying a param of torch.Size([80, 64, 1, 1]) from checkpoint, where the shape is torch.Size([256, 64, 1, 1]) in current model.
size mismatch for features.11.expand1x1.bias: copying a param of torch.Size([80]) from checkpoint, where the shape is torch.Size([256]) in current model.
size mismatch for features.11.expand3x3.weight: copying a param of torch.Size([64, 64, 3, 3]) from checkpoint, where the shape is torch.Size([256, 64, 3, 3]) in current model.
size mismatch for features.11.expand3x3.bias: copying a param of torch.Size([64]) from checkpoint, where the shape is torch.Size([256]) in current model.
size mismatch for features.12.squeeze.weight: copying a param of torch.Size([64, 144, 1, 1]) from checkpoint, where the shape is torch.Size([64, 512, 1, 1]) in current model.
size mismatch for features.12.expand1x1.weight: copying a param of torch.Size([35, 64, 1, 1]) from checkpoint, where the shape is torch.Size([256, 64, 1, 1]) in current model.
size mismatch for features.12.expand1x1.bias: copying a param of torch.Size([35]) from checkpoint, where the shape is torch.Size([256]) in current model.
size mismatch for features.12.expand3x3.weight: copying a param of torch.Size([20, 64, 3, 3]) from checkpoint, where the shape is torch.Size([256, 64, 3, 3]) in current model.
size mismatch for features.12.expand3x3.bias: copying a param of torch.Size([20]) from checkpoint, where the shape is torch.Size([256]) in current model.
size mismatch for classifier.1.weight: copying a param of torch.Size([2, 55, 1, 1]) from checkpoint, where the shape is torch.Size([2, 512, 1, 1]) in current model.
[phung@archlinux SqueezeNet-Pruning]$

@promach the size mismatch error is due to incorrect sizes between layers. So you might have messed up with the Net sizes somewhere in the code. The easiest way to get the right size is to add a print statement in your forward pass and just look at the size. I would suggest looking at you net again.

1 Like

The problem is that when I run “python finetune.py --train && python finetune.py --prune” which is the forward pass, these two commands do not give me tensor size mismatch issues.

I will definitely look at predict.py again, but this file does not mess around with the model internally itself.

So, I guess the problems lie at prune.py which messes the original SqueezeNet model.

@promach yes I guess so, could you try to print the result of your model please

print(model)

Also, I would request you to please mark this topic as solved and start a new topic. T:his might be helpful for other users who will view your problems. Maybe other people in a new thread would be able to help you better. Also tag me in the new thread so that I could be notified.
Thank you :slight_smile:

1 Like

I hope I could help you with your problem.

give me a moment, print(model) does not work after model.load_state_dict(checkpoint) because the error is due to checkpoint variable itself.

Traceback (most recent call last):
File “predict.py”, line 29, in
model.load_state_dict(checkpoint[‘model_state_dict’])
KeyError: ‘model_state_dict’

@Amrit_Das Seems like the following line is the culprit ? How should I change this ?

@Amrit_Das @albanD

I have solved all problems and it looks like I can do the predict.py without any more problems

Please see the updated code below:

#Modified from https://github.com/amrit-das/Custom-Model-Training-PyTorch/blob/master/predict.py
import torch
import torch.nn as nn
#from torchvision.models import resnet18
from torchvision.transforms import transforms
import matplotlib.pyplot as plt
import numpy as np
from torch.autograd import Variable
import torch.functional as F
from PIL import Image
import os
import sys
import argparse
from prune import *
from finetune import *

parser = argparse.ArgumentParser(description = 'To Predict from a trained model')
parser.add_argument('-i','--image', dest = 'image_name', required = True, help='Path to the image file')
parser.add_argument('-m','--model', dest = 'model_name', required = True, help='Path to the model')
parser.add_argument('-n','--num_class',dest = 'num_classes', required = True, help='Number of training classes')
args = parser.parse_args()

#model=ModifiedSqueezeNetModel().cuda()
#model = torch.load(args.model_name).cuda()
#model = resnet18(num_classes = int(args.num_classes))

path_to_model = "./"+args.model_name
#checkpoint = torch.load(path_to_model)
model = torch.load(path_to_model)

#model.load_state_dict(checkpoint)
#model.eval()

def predict_image(image_path):
    print("prediction in progress")
    image = Image.open(image_path)
    transformation = transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
        ])
    image_tensor = transformation(image).float()
    image_tensor = image_tensor.unsqueeze_(0)

    if torch.cuda.is_available():
        image_tensor.cuda()

    input = Variable(image_tensor).cuda()
    output = model(input)

    #index = output.argmax()
    #print("output = ", output)
    max_value, max_index = torch.max(output,1)

    return max_index.item()

def class_mapping(index):
    mapping=open('class_mapping.txt','r')
    class_map={}
    for line in mapping:
        l=line.strip('\n').split('=')
        class_map[l[1]]=l[0]
        #print("l[0] = ", l[0])
        #print("l[1] = ", l[1])
    #print("class_map[0] = ", class_map[str(0)])
    #print("class_map[1] = ", class_map[str(1)])
    return class_map[str(index)]

if __name__ == "__main__":

    imagepath = "./test/Lemon/"+args.image_name
    prediction = predict_image(imagepath)
    #print("prediction = ", str(prediction))
    name = class_mapping(prediction)
    print("Predicted Class: ",name)