Can't pickle local object 'Metrics.best_fthresh.<locals>.opt_th'

I have this metric defined for v2 … works fine during training …

   def best_fthresh(cls, beta=1, sigmoid=True, start=0.17, end=0.24, step=0.01, **kwargs):

        def opt_th(preds, targs):
            with warnings.catch_warnings():
                warnings.simplefilter("ignore")

                ths = np.arange(start, end, step)
                idx = np.argmax([ skm.fbeta_score(targs, (preds > th), beta, average='samples') for th in ths ])
                return ths[idx]

        return AccumMetric(opt_th, sigmoid=sigmoid, to_np=True, invert_arg=False, flatten=False, **kwargs)

… but when I export the learner I get this error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-59-d911b0280f19> in <module>
----> 1 learn.export(fname=f'{m_pre}export_clas{m_suf}.pkl')

~/development/_training/ml/nlp-playground/_libs/fastai2/fastai2/learner.py in export(self, fname)
    494         #To avoid the warning that come from PyTorch about model not being checked
    495         warnings.simplefilter("ignore")
--> 496         torch.save(self, self.path/fname)
    497     self.create_opt()
    498     self.opt.load_state_dict(state)

~/anaconda3/envs/playground-nlp/lib/python3.7/site-packages/torch/serialization.py in save(obj, f, pickle_module, pickle_protocol, _use_new_zipfile_serialization)
    326 
    327     with _open_file_like(f, 'wb') as opened_file:
--> 328         _legacy_save(obj, opened_file, pickle_module, pickle_protocol)
    329 
    330 

~/anaconda3/envs/playground-nlp/lib/python3.7/site-packages/torch/serialization.py in _legacy_save(obj, f, pickle_module, pickle_protocol)
    399     pickler = pickle_module.Pickler(f, protocol=pickle_protocol)
    400     pickler.persistent_id = persistent_id
--> 401     pickler.dump(obj)
    402 
    403     serialized_storage_keys = sorted(serialized_storages.keys())

AttributeError: Can't pickle local object 'Metrics.best_fthresh.<locals>.opt_th'

You’ll probably want to replace it with a class, or simply define opt_th outside of best_fthresh.

5 Likes

Yah I tried the import dill as pickle … which did not fix things as this is happening in the pytorch source code.

I guess approach 1 is the only viable alternative.

I think it is a Win10 problem.
Reference to this post BigData, databunch and training loop

Unfortunately, I only train on linux … the solution was to follow Jeremy’s advice which turned out to work fine.