How to make predictions with vision learner? (solved)

I have trained a model, and want to put some new arbitrary images (that were not apart of the training/testing/validation) through it.

I can’t figure out how. The ‘predict’ method does not accept a path to an image.


learn.predict(f"{BASE}/test/0aa98293e.jpg ")

The entire notebook with the training can be found here:

Ultimately what I am trying to do take that test folder and get the top 5 predictions for each image.

As shown here, learn.predict takes an Image, not a filename.

1 Like

I appreciate the link and have looked there. That is showing how to do a prediction on data that is already “in” the learner.

I am trying to figure out how to load the image from disk into an “image” as you say.

Is there a tutorial anywhere on how to use learn.predict on data that is not a part of the training?


@sgugger the link you provided has reference to load_learner which doesn’t seem to exist anymore?

At the very worst, I think you could call learn.model() on your input, but I think you’d have to make sure to transform the input properly if necessary.

As @sgugger has said, the function takes an Image, while you are passing a string.

Open the image and pass that instead.

You can find it here

Thanks @miko

Now it looks like predict eturns the top category and a list of probabilities for all categories.

I am not sure how to map the human readable categories to the list of probabilities returned.


cat, tensor, probs = learn.predict(open_image(f"{BASE}/test/d042ac24f.jpg"))

where probs is a tensor of length num_cats that, I presume, maps to a list of categories.

I am trying to get the top 5 (rather than top 1) most likely labels.


i have too many questions about the return of predict. i will open a new thread.

I have trained a classifier for images with 7 classes. The model works perfectly fine on colab. I want to deploy the same on laptop. I went about as follows:

  1. Export the model using learn.export(). to dataPath
  2. learn=load_learner(dataPath) on my laptop.
  3. I read the image from disk stored at imgPath
    arr = plt.imread(“imgPath/1.Col_ST_48/IMG_20190801_134227.jpg”)
  4. Convert the image(ndarray) to fastai Image: img = pil2tensor(arr,dtype= np.float32)
  5. Do prediction: learn.predict(Image(img))
    I get the first class always as predicted class irrespective of image. Am I missing something?
1 Like

How about you try something like learn.predict(open_image(‘imgPath/1.Col_ST_48/IMG_20190801_134227.jpg’))

I wonder if this helps.

Thank you. It helped while running the inference on colab. But if run the same on windows pc on learn = load_learner(dataPath) I get the following warning:
C:\Users\tapas_XXXX\Miniconda3\envs\fastai_v1\lib\site-packages\torch\ SourceChangeWarning: source code of class ‘torch.nn.modules.loss.CrossEntropyLoss’ has changed. you can retrieve the original source code by accessing the object’s source attribute or set torch.nn.Module.dump_patches = True and use the patch tool to revert the changes.

  • warnings.warn(msg, SourceChangeWarning)*
    C:\Users\XXXX\Miniconda3\envs\fastai_v1\lib\site-packages\torch\ SourceChangeWarning: source code of class ‘torch.nn.modules.conv.Conv2d’ has changed. you can retrieve the original source code by accessing the object’s source attribute or set torch.nn.Module.dump_patches = True and use the patch tool to revert the changes.
  • warnings.warn(msg, SourceChangeWarning)*

If I ignore this warning during prediction I get error: AttributeError: ‘ReLU’ object has no attribute 'threshold’
Is it an issue of version. I found fastai version 1.0.55 is running in my PC as well as colab.
Any insights??

IIRC you need to make sure you have the right version of PyTorch installed, I expect that the latest version should be good enough.

1 Like

I also wanted to get the top 5 predictions instead of top 1 prediction. Here’s some code I wrote for the same. I hope it helps.

  1. Run this (Iterating over 100 images in validation data bunch, stored the index and class in a list)

list1 = []
cnt = 1
for i in data.valid_ds.x :
if cnt>100:
cnt +=1
a = learn.predict(i)
list1.append( [a[0] , a[1] ])

  1. Pass this ‘list1’ into below function to get a dictionary mapping indices to classes

from collections import OrderedDict
def makedict(list1):
od = OrderedDict()
for i in list1:
if od.get(i[1].item()) is None:
od[i[1].item()] = str(i[0]).split()[-1]
d_ascending = OrderedDict(sorted(od.items()))

  1. This returned a dictionary mapping. Now you may run this function and call topNclasses

def top_N_classes( img , N ):
tpNlist = []
x = learn.predict(img)
list_of_prob = x[2].tolist()
res = sorted(range(len(list_of_prob)), key = lambda sub: list_of_prob[sub])[-N:]
dict_map = makedict(list1)
for i in range(N-1,-1,-1):
idx= res[i]
tpNlist.append([dict_map[idx] , list_of_prob[idx]] )
return tpNlist

Explanation: You may notice that learn.predict( image ) returns a class, an index and a tensor of probabilities. like so,
class, index, probs = learn.predict( image )
we can see the index and the class corresponding to it. What I have done is iterated for 100 images storing the class and index( hopefully the 100 images contain all classes, increase the number or remove the line if all classes are not stored in dictionary )and created a dictionary mapping index to class.
Once we have that mapping, we can predict top5classes or topNclasses.

For Top 5 Classes predictions, I wrote a small function. Hope it helps:

 preds,tensor,probs=learn.predict( open_image("image.png")
def top_5_preds(preds):    
    preds_s = preds.argsort(descending=True)
    return preds_s
def top_5_pred_labels(preds, classes):
    top_5 = top_5_preds(preds)
    labels = []
    for i in top_5:

For more you can check this link :

1 Like