Predicting on a single image

Hi guys

I am working on a Image Regression task. The model is working fine and now I would like to test this on some real life sample cases. However, I am unable to use learn.predict and getting errors:

  1. Here is my model:

    learn = Learner(data, model, loss_func = F.l1_loss, model_dir = “/temp/model/”)

I used Learner approach because I customized cnn_learner model to add few linear layers in the end for my regression task.

Now I am using following method to predict on a single image:

img = open_image('../input/pic.jpg')
learn.predict(img.data)

But this is giving me following error:
’Tensor’ object has no attribute 'apply_tfms’

Can anyone please tell me how to resolve this issue?

Best Regards
Abhik

Try:
learn.predict(img)
The result of open should be and Image(ItemBase) that has apply_tfms method

Thanks Stefano, but unfortunately, it didn’t work. I tried everything but apply_tfms is unwilling to go.

Here is the screen shot of error:

This is what I tried for the above error:
learn.predict(img.data)

I am marking @sgugger here if I am doing something horribly wrong

You should do learn.predict(img), as Stefano said, not img.data.

2 Likes

Thanks @sgugger, I did exactly that and the error was the same which I pasted above as screen-shot (Tensor object has no attribute ‘apply_tfms’)

Here is the code:

img = open_image('../input/picture-1/55632758_1035600193317551_7808214316078858240_n.jpg')
`learn.predict(img)`

In the screenshot above you said you typed learn.predict(img.data) not learn.predict(img).
This code should work, so we can’t help without knowing more about how that learner was created.

Here is the data creation:

    tfms = get_transforms(max_zoom=1., max_lighting=0.20,
                      max_warp=0., xtra_tfms=[crop_pad(size=600, padding_mode='zeros', row_pct=0.,col_pct=0.), symmetric_warp(magnitude=(-0.1,0.1)) ])
path_csv = '../input/appa-real-face-cropped/'
path_folder = '../input/appa-real-face-cropped/final_files/final_files/'

data = ImageList.from_csv(path, csv_name = '/kaggle/input/appa-real-face-cropped/labels.csv', folder = '.').split_by_rand_pct(0.2).label_from_df(label_cls=FloatList).transform(tfms, size=224).databunch(bs=64).normalize(imagenet_stats)

Here is the model I created:

class AgeModel(nn.Module):
    def __init__(self):
        super().__init__()
        layers = list(models.resnet50(pretrained=True).children())[:-2]
        layers += [AdaptiveConcatPool2d(),Flatten()]
        layers += [nn.Linear(4096, 1024), nn.ReLU(), nn.Linear(1024,256), nn.ReLU(), nn.Linear(256,64), nn.ReLU(), nn.Linear(64,1)]
        self.agemodel = nn.Sequential(*layers)
    def forward(self, x):
        return self.agemodel(x).squeeze() 

Here is the learner:

learn = Learner(data, model, loss_func = F.l1_loss, model_dir = "/temp/model/")

Then I am splitting the model like this:

learn.split([model.agemodel[2],model.agemodel[5], model.agemodel[-7]])

Then training:

learn.freeze_to(-1)
learn.fit_one_cycle(5)

Ok, and the full stack trace please. You truncated the error message up there.

Sorry, I had to get the code running again to get the error :slight_smile:

Here is the full error (this time I got something different :slight_smile: ):

How do you created your data bunch?

This is how I created my databunch:

tfms = get_transforms(max_zoom=1., max_lighting=0.20,
                      max_warp=0., xtra_tfms=[crop_pad(size=600, padding_mode='zeros', row_pct=0.,col_pct=0.), symmetric_warp(magnitude=(-0.1,0.1)) ])
path_csv = '../input/appa-real-face-cropped/'
path_folder = '../input/appa-real-face-cropped/final_files/final_files/'

data = ImageList.from_csv(path, csv_name = '/kaggle/input/appa-real-face-cropped/labels.csv', folder = '.').split_by_rand_pct(0.2).label_from_df(label_cls=FloatList).transform(tfms, size=224).databunch(bs=64).normalize(imagenet_stats)

This is the line that’s causing your problem. You should only squeeze the last axis because when you want to predict, you pass a batch of size 1 and you end up squeezing that dimension, which makes your output a rank-0 tensor instead of being a tensor of size 1.

2 Likes

Hi @sgugger: thanks a lot! But can I ask you how to squeeze only the last axis? Sorry for troubling you on this…

Last dimension is -1, so self.agemodel(x).squeeze(-1).

1 Like

Thanks a lot!! :slight_smile:

I will make the changes and let you know if this solution worked.

Thanks again for your time and help.

@sgugger : it worked like magic… thanks again!! :smiley:

1 Like