How do I predict a batch of images without labels

I haven’t tested yet but I guess this post can help you. https://forums.fast.ai/t/how-to-get-an-empty-convlearner-for-single-image-prediction/28245/50 . This is for single image but I think I will work with a batch of image too. Load the model you have trained and predict your images in pure Pytorch .

I am facing a similar problem and so do many people. I guess fastai will make a friendly API for this soon :smiley:

The correct way to do this is to use a test set (it’s literally what test sets are for in fastai). You’ll just have an empty train and validation set in your databunch - which is fine, since you won’t be using them.

DataBunch handles all the serialization for you now of your preprocessors (such as your list of classes), and makes life far easier than doing things manually with Pytorch.

3 Likes

Thanks for the clarification here – That’s what I suspected after reading as much as possible on the forums, but I wasn’t sure :slight_smile:

After the course we’ll be simplifying this further, by serializing data processing/metadata with the learner. But I just added some tiny tweaks to make it a bit simpler, as well as adding some docs to the inference tutorial to show an example. https://docs.fast.ai/tutorial.inference.html#A-classification-problem

11 Likes

That’s literally perfect :slight_smile:

Great, thanks this is what I was after. I seem to remember trying with an empty train, val dataset but it threw an index out of range error. This looks much simpler. Will give it a shot!

@jeremy that’s working great thanks. One small request though…

LabelLists seems to be taking the path from the location of the original training data, despite me trying to override it. This forces me to replicate the folder structure used to train the model in order to load my test set. This happens even if I explicity set the path of the LabelList object i.e.

sd = LabelLists.load_empty(test_path/'export.pkl', tfms=get_transforms(), size=224).add_test_folder('test')
sd.path = test_path
empty_data = sd.databunch().normalize(imagenet_stats)

I think the problem lies in this method:

@classmethod
def load_empty(cls, fn:PathOrStr, tfms:TfmList=None, tfm_y:bool=False, **kwargs):
    train_ds = LabelList.load_empty(fn, tfms=tfms[0], tfm_y=tfm_y, **kwargs)
    valid_ds = LabelList.load_empty(fn, tfms=tfms[1], tfm_y=tfm_y, **kwargs)
    return LabelLists(valid_ds.path, train=train_ds, valid=valid_ds)

Suggest changing it to something like:

def load_empty(cls, fn:PathOrStr, tfms:TfmList=None, tfm_y:bool=False, **kwargs):
	path = os.path.dirname(fn)
    train_ds = LabelList.load_empty(fn, tfms=tfms[0], tfm_y=tfm_y, **kwargs)
    valid_ds = LabelList.load_empty(fn, tfms=tfms[1], tfm_y=tfm_y, **kwargs)
    return LabelLists(path, train=train_ds, valid=valid_ds)

EDIT: My bad, if I override the path before before I add_test_folder then it works. But my suggestion stands…

2 Likes

Just pushed a fix, you should now pass path and fn (defaults to export.pkl) separately and the path you give will override the one of the training.

1 Like

Thanks both!


Not the most elegant way, but it may be useful to others, so here’s how I did it.

P.S. I don’t classify vans for fun, this is actually for work!

5 Likes

Sorry to hijack this thread, but version 1.034 of the library doesn’t have load_empty under LabelLists

Hey, it’s definitely there. See https://github.com/fastai/fastai/blob/master/fastai/data_block.py#L460

Although I have a feeling (not sure) they may have moved ItemLists to a different file so your error could be a red herring. You might just need to restart your kernel.

import fastai.utils
show_install()

Make sure you are in fact using 1.0.34. I haven’t testing the load_empty stuff yet, but it seems like a good way to go about it.

load_empty isn’t available until 1.0.36 according to this: https://github.com/fastai/fastai/blob/master/CHANGES.md#1036-2018-12-08

Major kudos for using CHANGES.md! :smiley:

2 Likes

As a minor related question, is there a way to ensure that your image transforms are actually being applied? Because I followed @safekidda 's screenshot but my classifier labeled everything as a single class - but if I shuffled the images into my test set things worked fine. The only explanation I can think of is that the images are different dimensions than the transformed training images and that the LabelList method is enforcing a different set of transformations even though my parameters to get_transforms() are the same.

It’s probably not the transforms. Most likely the image size. Also, I don’t know if you followed my code exactly, but I only had two classes so I just sliced the tensor that was returned. You’ll obviously need to do something else such as a max if you have more than two classes.

EDIT: Just read your post again, and I’m not sure what you’re doing. Best post an example. But usually you wouldn’t augment your Val/test set so I don’t think it’s transforms.

On a side note I just looked at the docs for transforms and they’re awesome. Loads of work has gone into this - really nice.

I am a beginner and using fastai ‘1.0.41’ but @jeremy suggestions approach does not work for the Unet Learner. I am bit confuse about it and these are problems:

  • The LabelLists.loadempty reads the state x_cls which is not available the exported file from Unet Learner

~/anaconda3/envs/fastaiV1/lib/python3.7/site-packages/fastai/data_block.py in load_state(cls, state)
600 def load_state(cls, state:dict) -> ‘LabelList’:
601 “Create a LabelList from state.”
–> 602 x = state[‘x_cls’]([], path=state[‘path’], processor=state[‘x_proc’], ignore_empty=True)

If I read it normally by

state = pickle.load(open(PATH/‘export.pkl’, ‘rb’))

Then the state’s keys are

dict_keys([‘opt_func’, ‘loss_func’, ‘metrics’, ‘true_wd’, ‘bn_wd’, ‘wd’, ‘train_bn’, ‘model_dir’, ‘callback_fns’, ‘cb_state’, ‘model’, ‘data’, ‘cls’])

  • That problem could be from the Unet model description as there are no classes.
  • Then, I read the docs and start to use a Data_block API which is really impressive. But the second problem is from the label_empty() function.
  • I want to create a general way to get ‘test’ images, without label, in the tensor shape with batch, normalized by imagenet_stats. This is the code

data = (ImageItemList.from_folder(path_img)
.no_split()
.label_empty()
.add_test_folder(‘test’)
.transform(get_transforms(), size=64)
.databunch()
.normalize(imagenet_stats))

  • But

~/anaconda3/envs/fastaiV1/lib/python3.7/site-packages/fastai/data_block.py in _inner(*args, **kwargs)
420 assert isinstance(self.train, LabelList)
421 kwargs[‘label_cls’] = self.train.y.class
–> 422 self.valid = fv(*args, **kwargs)
423 self.class = LabelLists
424 self.process()

TypeError: label_empty() got an unexpected keyword argument ‘label_cls’

  • This may be come from no validation set but I have no idea to fix it.

It is a long reply but hope we can find a way to fix this for Unet learner.