How do we use our model against a specific image?

As far as I understand(from end of lessons 2 I believe) this is the code:
Am I right? @jeremy

But as you see, it didn’t work for me, try run it tell me if it worked for you

im = val_tfrms(Image.open(f’{PATH}valid/dogs/arnaud.jpg’))

Use open_image instead of Image.open. This is the recommended approach and will avoid most problems related to AttributeError: ‘PngImageFile’ object has no attribute ‘shape’.

fn = f’{PATH}valid/dogs/arnaud.jpg’
im = val_tfrms(open_image(fn))
1 Like

Setting learn.precompute = False before you run that prediction will resolved the issue.

trn_tfms, val_tfms = tfms_from_model(arch, sz) # get image transformations
im = val_tfrms(open_image(PATH + fn))
learn.precompute = False # we need to set this since we are passing in an image, not a precomputed activation
preds = learn.predict_array(im[None]) # do prediction
... truncated ...
... truncated ...
2 Likes

Does this classify a totally new image the model hasn’t seen before or do you have to show it something from the validation folder?

I see that this …

learn.precompute = False
i = '/path/to/photo/'
im = val_tfms(open_image(i))
preds = learn.predict_array(im[None])
print (np.argmax(preds))

…returns 1 or 0.
But what can I do to get it to return a value BETWEEN 1 and 0?

Yes, it can do both. I have tested both cases:

  1. Image from the validation set.

  1. Totally new image the model hasn’t seen before.
    Example: https://www.k9rl.com/dog-breeds/toy-dogs/affenpinscher/

3 Likes

It shouldn’t returns 1 or 0 or a value between 1 and 0. Your codes are incorrect. Check my previous reply for the correct codes and how the expected results should look like.

With notebook 1 it classifies dog or cat with 0 or 1. It shows probabilities between 0 and 1.
Not really relevant to my question but I’m trying with my own images with categories of want vs pass. (Stylish images I want to use for a website vs images I don’t want to use).
When I show it a new image it hasn’t seen before it returns a 1 or a 0. I want probilities like it gave on the validation images.
Here it’s giving probabilities (between 1 and 0) that it validated on. It “shouldn’t” you say, maybe because it’s not what the model is supposed to do? But it’s what I want.

(Below) These are new images after the model has been trained. They only return 1 or 0. I want probabilities instead because I know the model isn’t very good yet overall but I know anything below a 0.01 or above a 0.8 is correctly classified. The training it does on my few thousand images has an accuracy of 0.81. Pretty good but I need more images.

So I’m trying to use the model to help me build a bigger, better dataset for it to train on.

I know this is probably too much irrelevant information but, again, I want probilities if that’s possible.

np.argmax() returns the index of an array. Since the array has two elements, the two possibilities for the index are 0 or 1. See: https://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.argmax.html

Here is the post with the code that worked best for me (after sifting through this entire thread). probs_single is the array with the probabilities for each of the two classes: http://forums.fast.ai/t/how-do-we-use-our-model-against-a-specific-image/7661/99

I’ve been trying old working examples that no longer work for about an hour now. Where is the most recent code that works to do this?

I have been trying to get single image classification to work on the dogs/cats example from lesson 1, but passing in the images from the validation set is yielding some unexpected results. I have the following code:

PATH = "data/dogscats"
arch = resnet34
sz = 224
data = ImageClassifierData.from_paths(PATH, tfms=tfms_from_model(arch, sz, aug_tfms=transforms_side_on, max_zoom=1.1))
learn = ConvLearner.pretrained(arch, data, precompute=True)
learn.fit(0.01, 3)

learn.precompute = False
trn_tfms, val_tfms = tfms_from_model(arch, sz)
imgs = np.array([val_tfms(open_image(PATH+'/valid/cats/' + fn)) for fn in os.listdir(PATH+"/valid/cats/")])
log_preds = learn.predict_array(imgs)
preds = np.argmax(log_preds, axis=1)

I can see from the data.classes variable that a 0 indicates a cat and a 1 indicates a dog, but the values in the preds array are almost half and half 1’s and 0’s.

Shouldn’t the values in the preds array be almost entirely 0’s (cats) since these images are from the cats portion of the validation set (aka, the set that the training process used to determine that the model has ~99% accuracy). OR perhaps I have a bug in my code or a fundamental misunderstanding of how the training process works / how the validation set is used. Can anyone set me straight?

Hi, I’m trying to use the saved model against an image, with the following code

#using existing model
# Make transformation model & data
tfmModel = tfms_from_model(resnet34, imSize, aug_tfms = transforms_side_on, max_zoom = 1.1)
data = ImageClassifierData.from_paths(PATH, tfms = tfmModel, bs = batchSize)

myModel = ConvLearner.pretrained(resnet34, data)
myModel.load('180123_resnet34_AllLayer01')

#try to predict the image
trn_tfms, val_tfms = tfms_from_model(resnet34, imSize, aug_tfms = transforms_side_on, max_zoom = 1.1)

url_response = urllib.request.urlopen(url)
im = val_tfms(np.array(Image.open(url_response))/255)
url_log_pred = myModel.predict_array(im[None])

However i encountered the following error:

ValueError: Expected more than 1 value per channel when training, got input size [1, 1024]

However, if I run:
logPred,y = myModel.TTA()

then perform:
url_log_pred = myModel.predict_array(im[None])

then it will be able to run as expected.
Does anyone know why?

If possible I don’t want to run myModel.TTA()

I’m trying to predict a single image and have gotten the code to run without any errors; however, I’m not exactly sure what the “np.argmax(preds)” is supposed to output. I added the print(preds[:2]) to see what preds was actually equal to. If the “np.argmax(preds)” outputs which type of image it thinks it is which is what I thought it did then it seems to get most of them wrong. There are also dramatic swings in what the preds is equal to when you retrain the model. Could someone try to explain this to me? Thanks. Here is the code.

How long ago did you update the fastai library? Seems like your predict_array does not have model.eval() in it.

np.argmax(preds) returns an index of predicted class (from learn.data.classes)

I git pulled and didn’t get any noticeable change. I also haven’t gotten any positive numbers from print(preds).

Sorry, for confusion, but my first post was related to @arifoyong question.
Try running this:

learn.data.classes[np.argmax(preds)]

Do you get a correct class?

Suppose I’m using a saved model for prediction. What is the correct way to create the learn object ? How to initialize it ?

tfmModel = tfms_from_model(resnet34, imSize, aug_tfms = transforms_side_on, max_zoom = 1.1)
data = ImageClassifierData.from_paths(PATH, tfms = tfmModel, bs = batchSize)
learn = ConvLearner.pretrained(resnet34, data)

I am doing it like above, but if I have to take my saved model to someplace else and make predictions out of it, do I need to take the training data with it too ? as I understand from

ImageClassifierData.from_paths(PATH, ...)

1 Like

Hi @ace139 you just need to serialize the learner to disk like using a serialization library like pickle.

Reload the serialized file using pickle.load

@binarypoet This is a very useful code! Could you suggest a similar dataset that could run as your shopstyle one?