Reputation: 123
I am a beginner and I am learning to code an image classifier. My goal is to create a predict
function.
Any suggestion to fix it?
In this project, I want to use the predict function to recognize different flower species. So I could check their labels later.
Attempt to fix: I have already used the unsqueeze_(0)
method and changing from numpy to torch method . I usually get the same error message shown below:
TypeError: img should be PIL
Code:
# Imports here
import pandas as pd
import numpy as np
import torch
from torch import nn
from torchvision import datasets, transforms, models
import torchvision.models as models
import torch.nn.functional as F
import torchvision.transforms.functional as F
from torch import optim
import json
from collections import OrderedDict
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from PIL import Image
def process_image(image):
#Scales, crops, and normalizes a PIL image for a PyTorch model,
#returns an Numpy array
# Process a PIL image for use in a PyTorch model
process = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
image = process(image)
return image
# Predict
#Predict the class (or classes) of an image using a trained deep learning model.
def predict(image, model, topk=5):
img = process_image(image)
img = img.unsqueeze(0)
output = model.forward(img)
probs, labels = torch.topk(output, topk)
probs = probs.exp()
# Reverse the dict
idx_to_class = {val: key for key, val in model.class_to_idx.items()}
# Get the correct indices
top_classes = [idx_to_class[each] for each in classes]
return labels, probs
#Passing
probs, classes = predict(image, model)
print(probs)
print(classes)
TypeError Traceback (most recent call last)
<ipython-input-92-b49fdcab5791> in <module>()
----> 1 probs, classes = predict(image, model)
2 print(probs)
3 print(classes)
<ipython-input-91-05809355bfe0> in predict(image, model, topk)
2 ‘’' Predict the class (or classes) of an image using a trained deep learning model.
3 ‘’'
----> 4 img = process_image(image)
5 img = img.unsqueeze(0)
6
<ipython-input-20-02663a696e34> in process_image(image)
11 std=[0.229, 0.224, 0.225])
12 ])
---> 13 image = process(image)
14 return image
/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py in __call__(self, img)
47 def __call__(self, img):
48 for t in self.transforms:
---> 49 img = t(img)
50 return img
51
/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/transforms.py in __call__(self, img)
173 PIL Image: Rescaled image.
174 “”"
--> 175 return F.resize(img, self.size, self.interpolation)
176
177 def __repr__(self):
/opt/conda/lib/python3.6/site-packages/torchvision-0.2.1-py3.6.egg/torchvision/transforms/functional.py in resize(img, size, interpolation)
187 “”"
188 if not _is_pil_image(img):
--> 189 raise TypeError(‘img should be PIL Image. Got {}’.format(type(img)))
190 if not (isinstance(size, int) or (isinstance(size, collections.Iterable) and len(size) == 2)):
191 raise TypeError(‘Got inappropriate size arg: {}’.format(size))
TypeError: img should be PIL Image. Got <class ‘str’>
All I want is to get these similar result. Thank you!
predict(image,model)
print(probs)
print(classes)
tensor([[ 0.5607, 0.3446, 0.0552, 0.0227, 0.0054]], device='cuda:0')
tensor([[ 8, 1, 31, 24, 7]], device='cuda:0')
Upvotes: 0
Views: 6777
Reputation: 8719
You are getting the above error because of the below line in predict
function:
img = process_image(image)
The input to the process_image
function should be Image.open(image)
, not image
which is basically the path to an image(string) and hence the error message TypeError: img should be PIL Image. Got <class ‘str’>
.
So, change img = process_image(image)
to img = process_image(Image.open(image))
Modified predict
function:
def predict(image, model, topk=5):
'''
Predict the class (or classes) of an image using a trained deep learning model.
Here, image is the path to an image file, but input to process_image should be
Image.open(image)
'''
img = process_image(Image.open(image))
img = img.unsqueeze(0)
output = model.forward(img)
probs, labels = torch.topk(output, topk)
probs = probs.exp()
# Reverse the dict
idx_to_class = {val: key for key, val in model.class_to_idx.items()}
# Get the correct indices
top_classes = [idx_to_class[each] for each in classes]
return labels, probs
Upvotes: 2