Error at get_preds() when exported model has OverSamplingCallback

I’m having and error when the model is trained with the callback OverSamplingCallback and when it is imported using load_learner(). Error occurs after calling learn.get_preds.

IndexError                                Traceback (most recent call last)
<ipython-input-12-5a5f3d8917f7> in <module>
 13         ids_test.append(match.group(0))
 14         learn = load_learner(learner_exported, 'final_vgg19_8.pkl',    test=ImageList.from_folder(subdir)).to_fp16()
---> 15         preds, y = learn.get_preds(ds_type=DatasetType.Test)
 16         preds_test.append(activation(preds))
 17         preds_test_mxp.append(max_proba(preds))

/opt/anaconda3/lib/python3.7/site-packages/fastai/basic_train.py in get_preds(self, ds_type, activ, with_loss, n_batch, pbar)
340             if not getattr(self, 'opt', False): self.create_opt(lr, wd)
341             else: self.opt.lr,self.opt.wd = lr,wd
--> 342             self.callbacks = [cb(self) for cb in self.callback_fns + listify(defaults.extra_callback_fns)] + listify(self.callbacks)
343             self.cb_fns_registered = True
344         return get_preds(self.model, self.dl(ds_type), cb_handler=CallbackHandler(self.callbacks),

/opt/anaconda3/lib/python3.7/site-packages/fastai/basic_train.py in <listcomp>(.0)
340             if not getattr(self, 'opt', False): self.create_opt(lr, wd)
341             else: self.opt.lr,self.opt.wd = lr,wd
--> 342             self.callbacks = [cb(self) for cb in self.callback_fns + listify(defaults.extra_callback_fns)] + listify(self.callbacks)
343             self.cb_fns_registered = True
344         return get_preds(self.model, self.dl(ds_type), cb_handler=CallbackHandler(self.callbacks),

/opt/anaconda3/lib/python3.7/site-packages/fastai/callbacks/oversampling.py in __init__(self, learn, weights)
 15         _, counts = np.unique(self.labels,return_counts=True)
 16         self.weights = (weights if weights is not None else
---> 17                         torch.DoubleTensor((1/counts)[self.labels]))
 18         self.label_counts = np.bincount([self.learn.data.train_dl.dataset.y[i].data for i in range(len(self.learn.data.train_dl.dataset))])
 19         self.total_len_oversample = int(self.learn.data.c*np.max(self.label_counts))

IndexError: arrays used as indices must be of integer (or boolean) type

Callback is used because I try to do the week 1 assignment with an unbalanced data set having x2 labels with 7 to 100 ratio.

Removing the OverSamplingCallback callback during the training solves the issue.
Also, this problem does not occur when I use Learner.save()->Learner.load() instead of Learner.export()->load_learner.
Thanks in advance for you help.

1 Like

I think this should be fixed by this pull request. Try to use the OverSamplingCallback from the developer install on Github. If you don’t want to retrain the model with the developer install of fastai, you can just remove the OversamplingCallback from callback list.

1 Like

Thank you, indeed it was already cover.
I followed your advice and tried the developer install.
Now at load_learner() stage I’m getting a different error:

AttributeError                            Traceback (most recent call last)
<ipython-input-15-21f0d6aa534c> in <module>
     12     if match:
     13         ids_test.append(match.group(0))
---> 14         learn = load_learner(learner_exported, 'export-vgg16-48-osp.pkl', 
test=ImageList.from_folder(subdir)).to_fp16()
     15         preds, y = learn.get_preds(ds_type=DatasetType.Test)
     16         preds_test.append(activation(preds))

/opt/anaconda3/src/fastai/fastai/fastai/basic_train.py in load_learner(path, file, test, **db_kwargs)
    620     res = clas_func(data, model, **state)
    621     res.callback_fns = state['callback_fns'] #to avoid duplicates
--> 622     res.callbacks = [load_callback(c,s, res) for c,s in cb_state.items()]
   623     return res

/opt/anaconda3/src/fastai/fastai/fastai/basic_train.py in <listcomp>(.0)
    620     res = clas_func(data, model, **state)
    621     res.callback_fns = state['callback_fns'] #to avoid duplicates
--> 622     res.callbacks = [load_callback(c,s, res) for c,s in cb_state.items()]
    623     return res

/opt/anaconda3/src/fastai/fastai/fastai/basic_train.py in load_callback(class_func, state, learn)
    604 def load_callback(class_func, state, learn:Learner):
    605     init_kwargs, others = split_kwargs_by_func(state, class_func.__init__)
--> 606     res = class_func(learn, **init_kwargs) if issubclass(class_func, LearnerCallback) else 
class_func(**init_kwargs)
    607     for k,v in others.items(): setattr(res, k, v)
    608     return res

/opt/anaconda3/src/fastai/fastai/fastai/basic_train.py in __init__(self, learn, add_time, silent)
    453     def __init__(self, learn:Learner, add_time:bool=True, silent:bool=False):
    454         super().__init__(learn)
--> 455         self.opt = self.learn.opt
    456         self.train_dl = self.learn.data.train_dl
    457         self.no_val,self.silent,self.add_time = False,silent,add_time

AttributeError: 'Learner' object has no attribute 'opt'

After checking fastai github and forum, I could not find any mention of this error.

1 Like

Same error here…
I am working with cnn_learner as follows,

learn.export(‘resnet34_mnist.pkl’)

df_test = pd.DataFrame(list(map(lambda f: f.split(os.sep)[-1], glob(str(IMAGE_DATA_PATH/‘test/*.jpg’)))), columns=[‘name’])

il_test = ImageList.from_df(df_test, IMAGE_DATA_PATH/‘test’)

learn_final = load_learner(IMAGE_DATA_PATH, file=‘resnet34_mnist.pkl’, test=il_test)

See git issue raised for more details…

Should be fixed as mentioned here. Make sure to do the developer install again.