Learner.predict does not work

I get the following error log when calling learner.predict(imagepath: pathlib.Path)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-c05bd1db6d14> in <module>
----> 1 learner.predict( Path('/nfs_storage/fs-mnt6/vaibhavg/data/images/male/0bf9fabd-4243-4075-852c-971b3593e9c5WPOsErwsRM0L5gQH.jpg') )

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastai/learner.py in predict(self, item, rm_type_tfms, with_input)
    257         i = getattr(self.dls, 'n_inp', -1)
    258         inp = (inp,) if i==1 else tuplify(inp)
--> 259         dec = self.dls.decode_batch(inp + tuplify(dec_preds))[0]
    260         dec_inp,dec_targ = map(detuplify, [dec[:i],dec[i:]])
    261         res = dec_targ,dec_preds[0],preds[0]

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastai/data/core.py in decode_batch(self, b, max_n, full)
     78 
     79     def decode(self, b): return to_cpu(self.after_batch.decode(self._retain_dl(b)))
---> 80     def decode_batch(self, b, max_n=9, full=True): return self._decode_batch(self.decode(b), max_n, full)
     81 
     82     def _decode_batch(self, b, max_n=9, full=True):

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastai/data/core.py in decode(self, b)
     77             if isinstance(f,Pipeline): f.split_idx=split_idx
     78 
---> 79     def decode(self, b): return to_cpu(self.after_batch.decode(self._retain_dl(b)))
     80     def decode_batch(self, b, max_n=9, full=True): return self._decode_batch(self.decode(b), max_n, full)
     81 

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastai/data/core.py in _retain_dl(self, b)
     57     def _retain_dl(self,b):
     58         if not getattr(self, '_types', None): self._one_pass()
---> 59         return retain_types(b, typs=self._types)
     60 
     61     @delegates(DataLoader.new)

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/dispatch.py in retain_types(new, old, typs)
    202         else: t,typs = typs,None
    203     else: t = type(old) if old is not None and isinstance(old,type(new)) else type(new)
--> 204     return t(L(new, old, typs).map_zip(retain_types, cycled=True))
    205 
    206 # Cell

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/foundation.py in map_zip(self, f, cycled, *args, **kwargs)
    176     def zip(self, cycled=False): return self._new((zip_cycle if cycled else zip)(*self))
    177     def zipwith(self, *rest, cycled=False): return self._new([self, *rest]).zip(cycled=cycled)
--> 178     def map_zip(self, f, *args, cycled=False, **kwargs): return self.zip(cycled=cycled).starmap(f, *args, **kwargs)
    179     def map_zipwith(self, f, *rest, cycled=False, **kwargs): return self.zipwith(*rest, cycled=cycled).starmap(f, **kwargs)
    180     def shuffle(self):

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/foundation.py in starmap(self, f, *args, **kwargs)
    173         return self.map(lambda o: o.get(k,default) if isinstance(o, dict) else nested_attr(o,k,default))
    174 
--> 175     def starmap(self, f, *args, **kwargs): return self._new(itertools.starmap(partial(f,*args,**kwargs), self))
    176     def zip(self, cycled=False): return self._new((zip_cycle if cycled else zip)(*self))
    177     def zipwith(self, *rest, cycled=False): return self._new([self, *rest]).zip(cycled=cycled)

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/foundation.py in _new(self, items, *args, **kwargs)
    108     @property
    109     def _xtra(self): return None
--> 110     def _new(self, items, *args, **kwargs): return type(self)(items, *args, use_list=None, **kwargs)
    111     def __getitem__(self, idx): return self._get(idx) if is_indexer(idx) else L(self._get(idx), use_list=None)
    112     def copy(self): return self._new(self.items.copy())

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/foundation.py in __call__(cls, x, *args, **kwargs)
     95     def __call__(cls, x=None, *args, **kwargs):
     96         if not args and not kwargs and x is not None and isinstance(x,cls): return x
---> 97         return super().__call__(x, *args, **kwargs)
     98 
     99 # Cell

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/foundation.py in __init__(self, items, use_list, match, *rest)
    103     def __init__(self, items=None, *rest, use_list=False, match=None):
    104         if (use_list is not None) or not is_array(items):
--> 105             items = listify(items, *rest, use_list=use_list, match=match)
    106         super().__init__(items)
    107 

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/basics.py in listify(o, use_list, match, *rest)
     54     elif isinstance(o, list): res = o
     55     elif isinstance(o, str) or is_array(o): res = [o]
---> 56     elif is_iter(o): res = list(o)
     57     else: res = [o]
     58     if match is not None:

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/dispatch.py in retain_types(new, old, typs)
    195 def retain_types(new, old=None, typs=None):
    196     "Cast each item of `new` to type of matching item in `old` if it's a superclass"
--> 197     if not is_listy(new): return retain_type(new, old, typs)
    198     if typs is not None:
    199         if isinstance(typs, dict):

/nfs_storage/fs-mnt6/vaibhavg/conda3/envs/hikemoji/lib/python3.8/site-packages/fastcore/dispatch.py in retain_type(new, old, typ, as_copy)
    189         typ = old if isinstance(old,type) else type(old)
    190     # Do nothing the new type is already an instance of requested type (i.e. same type)
--> 191     if typ==NoneType or isinstance(new, typ): return new
    192     return retain_meta(old, cast(new, typ), as_copy=as_copy)
    193 

TypeError: isinstance() arg 2 must be a type or tuple of types

For reference, here is my datablock, dataloaders and learner creation snippets:-

dblock = DataBlock(
    blocks=(ImageBlock, RegressionBlock),
    get_x = get_x,
    get_y = get_y,
    
    splitter=splitter,
    item_tfms=(Resize(224)),
    batch_tfms=[
        FlipItem(p=0.5),
        Brightness(max_lighting=0.3, p=0.7, draw=None, batch=False),
        Saturation(max_lighting=0.3, p=0.7, draw=None, batch=False),
        Hue(max_hue=0.1, p=0.75, draw=None, batch=False),
        RandomErasing(p=0.2, sl=0.0, sh=0.15, max_count=6, min_aspect=0.2)
    ],
)

dls = dblock.dataloaders(trp_df, bs=128)

learner = cnn_learner(dls, resnet18, n_out=15, loss_func=partial(loss, trp_wt=1, group_loss_wt=10, point_loss_wt=0), 
                      metrics=[mae_winner, mae_loser])

I have tried searching forums and StackOverflow, but I have not found any more occurrences of this error. Seems like I am doing something wrong, but can’t put my finger on it.

1 Like

What is get_x here? Predict needs exactly how get_x grabs the data

My functions get_x and get_y have the following definitions:-

def get_x(row):
    return Path(row['human_lips_path'])

def get_y(row):
    return get_lips_params_avatar_imagename(row['winner']), \
           get_lips_params_avatar_imagename(row['loser']), \
           row['round_num']

I am redefining these functions in the script where I am calling load_learner and learner.predict in exactly the same manner.

I hope that answers your question.

So your get_x is expecting a row, so you should pass in a row on inference

Thanks @muellerzr
I will try this out. This should definitely be the problem.