deepcopy exception occurred while running lr_find
csaroff opened this issue · comments
Great library! I had actually independently implemented some of the loss utilities that you wrote. Glad to see them in a public repo with better names.
Unfortunately, when I try to load the packages with from fastxtend.vision.all import *
, running learn.lr_find
fails because it attempts to deepcopy learn.dls
.
Here's the headline of the stacktrace:
RuntimeError: Exception occured in `LRFinder` when calling event `before_fit`:
The default implementation of __deepcopy__() for non-wrapper subclasses only works for subclass types that
implement new_empty() and for which that function returns another instance of the same subclass. You should either
properly implement new_empty() for your subclass or override __deepcopy__() if it is intended behavior for
new_empty() to return an instance of a different type.
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py(185)__deepcopy__()
183 new_tensor = self.new_empty([])
184 if type(new_tensor) is not type(self):
--> 185 raise RuntimeError(
186 "The default implementation of __deepcopy__() for non-wrapper subclasses "
187 "only works for subclass types that implement new_empty() and for which "
I tried opening the debugger and it seems like targ_pts
is unable to be deepcopied.
I wasn't sure if you've run into this before and might have some insight. In case it's helpful, I'm running fastai version 2.7.11
and fastxtend version 0.0.18
.
>>> fastai.__version__
'2.7.11'
tor>>> torch.__version__
'1.13.1+cu116'
>>> fastxtend.__version__
'0.0.18'
I also tried downgrading to 2.7.10
, but had the same issue.
Full Stacktrace
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ <ipython-input-19-c2db1576f5af>:14 in <cell line: 14> │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastxtend/callback/lr_finder.py:81 in │
│ lr_find │
│ │
│ 78 │ """ │
│ 79 │ n_epoch = num_it//len(self.dls.train) + 1 │
│ 80 │ cb=LRFinder(start_lr=start_lr, end_lr=end_lr, num_it=num_it, stop_div=stop_div,resto │
│ ❱ 81 │ with self.no_logging(): self.fit(n_epoch, cbs=cb) │
│ 82 │ if suggest_funcs is not None: │
│ 83 │ │ lrs, losses = tensor(self.recorder.lrs[num_it//10:-5]), tensor(self.recorder.los │
│ 84 │ │ nan_idxs = torch.nonzero(torch.isnan(losses.view(-1))) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/learner.py:264 in fit │
│ │
│ 261 │ │ │ if wd is not None: self.opt.set_hypers(wd=wd) │
│ 262 │ │ │ self.opt.set_hypers(lr=self.lr if lr is None else lr) │
│ 263 │ │ │ self.n_epoch = n_epoch │
│ ❱ 264 │ │ │ self._with_events(self._do_fit, 'fit', CancelFitException, self._end_cleanup │
│ 265 │ │
│ 266 │ def _end_cleanup(self): self.dl,self.xb,self.yb,self.pred,self.loss = None,(None,),( │
│ 267 │ def __enter__(self): self(_before_epoch); return self │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/learner.py:199 in _with_events │
│ │
│ 196 │ │ self.xb,self.yb = b[:i],b[i:] │
│ 197 │ │
│ 198 │ def _with_events(self, f, event_type, ex, final=noop): │
│ ❱ 199 │ │ try: self(f'before_{event_type}'); f() │
│ 200 │ │ except ex: self(f'after_cancel_{event_type}') │
│ 201 │ │ self(f'after_{event_type}'); final() │
│ 202 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/learner.py:172 in __call__ │
│ │
│ 169 │ │ finally: self.add_cbs(cbs) │
│ 170 │ │
│ 171 │ def ordered_cbs(self, event): return [cb for cb in self.cbs.sorted('order') if hasat │
│ ❱ 172 │ def __call__(self, event_name): L(event_name).map(self._call_one) │
│ 173 │ │
│ 174 │ def _call_one(self, event_name): │
│ 175 │ │ if not hasattr(event, event_name): raise Exception(f'missing {event_name}') │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastcore/foundation.py:156 in map │
│ │
│ 153 │ @classmethod │
│ 154 │ def range(cls, a, b=None, step=None): return cls(range_of(a, b=b, step=step)) │
│ 155 │ │
│ ❱ 156 │ def map(self, f, *args, gen=False, **kwargs): return self._new(map_ex(self, f, *args │
│ 157 │ def argwhere(self, f, negate=False, **kwargs): return self._new(argwhere(self, f, ne │
│ 158 │ def argfirst(self, f, negate=False): return first(i for i,o in self.enumerate() if f │
│ 159 │ def filter(self, f=noop, negate=False, gen=False, **kwargs): │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastcore/basics.py:840 in map_ex │
│ │
│ 837 │ │ else f.__getitem__) │
│ 838 │ res = map(g, iterable) │
│ 839 │ if gen: return res │
│ ❱ 840 │ return list(res) │
│ 841 │
│ 842 # %% ../nbs/01_basics.ipynb 336 │
│ 843 def compose(*funcs, order=None): │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastcore/basics.py:825 in __call__ │
│ │
│ 822 │ │ for k,v in kwargs.items(): │
│ 823 │ │ │ if isinstance(v,_Arg): kwargs[k] = args.pop(v.i) │
│ 824 │ │ fargs = [args[x.i] if isinstance(x, _Arg) else x for x in self.pargs] + args[sel │
│ ❱ 825 │ │ return self.func(*fargs, **kwargs) │
│ 826 │
│ 827 # %% ../nbs/01_basics.ipynb 326 │
│ 828 def mapt(func, *iterables): │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/learner.py:176 in _call_one │
│ │
│ 173 │ │
│ 174 │ def _call_one(self, event_name): │
│ 175 │ │ if not hasattr(event, event_name): raise Exception(f'missing {event_name}') │
│ ❱ 176 │ │ for cb in self.cbs.sorted('order'): cb(event_name) │
│ 177 │ │
│ 178 │ def _bn_bias_state(self, with_bias): return norm_bias_params(self.model, with_bias). │
│ 179 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/callback/core.py:62 in __call__ │
│ │
│ 59 │ │ if self.run and _run: │
│ 60 │ │ │ try: res = getcallable(self, event_name)() │
│ 61 │ │ │ except (CancelBatchException, CancelBackwardException, CancelEpochException, │
│ ❱ 62 │ │ │ except Exception as e: raise modify_exception(e, f'Exception occured in `{se │
│ 63 │ │ if event_name=='after_fit': self.run=True #Reset self.run to True at each end of │
│ 64 │ │ return res │
│ 65 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/callback/core.py:60 in __call__ │
│ │
│ 57 │ │ │ (self.run_valid and not getattr(self, 'training', False))) │
│ 58 │ │ res = None │
│ 59 │ │ if self.run and _run: │
│ ❱ 60 │ │ │ try: res = getcallable(self, event_name)() │
│ 61 │ │ │ except (CancelBatchException, CancelBackwardException, CancelEpochException, │
│ 62 │ │ │ except Exception as e: raise modify_exception(e, f'Exception occured in `{se │
│ 63 │ │ if event_name=='after_fit': self.run=True #Reset self.run to True at each end of │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastxtend/callback/lr_finder.py:36 in │
│ before_fit │
│ │
│ 33 │ │ "Initialize container for hyper-parameters and save the model & optimizer, optio │
│ 34 │ │ super().before_fit() │
│ 35 │ │ if self.restore_state: │
│ ❱ 36 │ │ │ self.old_dls = deepcopy(self.learn.dls) │
│ 37 │ │ │ self.states = get_random_states() │
│ 38 │ │ path = self.path/self.model_dir │
│ 39 │ │ path.mkdir(parents=True, exist_ok=True) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:205 in _deepcopy_list │
│ │
│ 202 │ memo[id(x)] = y │
│ 203 │ append = y.append │
│ 204 │ for a in x: │
│ ❱ 205 │ │ append(deepcopy(a, memo)) │
│ 206 │ return y │
│ 207 d[list] = _deepcopy_list │
│ 208 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:205 in _deepcopy_list │
│ │
│ 202 │ memo[id(x)] = y │
│ 203 │ append = y.append │
│ 204 │ for a in x: │
│ ❱ 205 │ │ append(deepcopy(a, memo)) │
│ 206 │ return y │
│ 207 d[list] = _deepcopy_list │
│ 208 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:205 in _deepcopy_list │
│ │
│ 202 │ memo[id(x)] = y │
│ 203 │ append = y.append │
│ 204 │ for a in x: │
│ ❱ 205 │ │ append(deepcopy(a, memo)) │
│ 206 │ return y │
│ 207 d[list] = _deepcopy_list │
│ 208 │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:172 in deepcopy │
│ │
│ 169 │ │ │ │ if isinstance(rv, str): │
│ 170 │ │ │ │ │ y = x │
│ 171 │ │ │ │ else: │
│ ❱ 172 │ │ │ │ │ y = _reconstruct(x, memo, *rv) │
│ 173 │ │
│ 174 │ # If is its own copy, don't memoize. │
│ 175 │ if y is not x: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:270 in _reconstruct │
│ │
│ 267 │ │
│ 268 │ if state is not None: │
│ 269 │ │ if deep: │
│ ❱ 270 │ │ │ state = deepcopy(state, memo) │
│ 271 │ │ if hasattr(y, '__setstate__'): │
│ 272 │ │ │ y.__setstate__(state) │
│ 273 │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:146 in deepcopy │
│ │
│ 143 │ │
│ 144 │ copier = _deepcopy_dispatch.get(cls) │
│ 145 │ if copier is not None: │
│ ❱ 146 │ │ y = copier(x, memo) │
│ 147 │ else: │
│ 148 │ │ if issubclass(cls, type): │
│ 149 │ │ │ y = _deepcopy_atomic(x, memo) │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:230 in _deepcopy_dict │
│ │
│ 227 │ y = {} │
│ 228 │ memo[id(x)] = y │
│ 229 │ for key, value in x.items(): │
│ ❱ 230 │ │ y[deepcopy(key, memo)] = deepcopy(value, memo) │
│ 231 │ return y │
│ 232 d[dict] = _deepcopy_dict │
│ 233 if PyStringMap is not None: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/copy.py:153 in deepcopy │
│ │
│ 150 │ │ else: │
│ 151 │ │ │ copier = getattr(x, "__deepcopy__", None) │
│ 152 │ │ │ if copier is not None: │
│ ❱ 153 │ │ │ │ y = copier(memo) │
│ 154 │ │ │ else: │
│ 155 │ │ │ │ reductor = dispatch_table.get(cls) │
│ 156 │ │ │ │ if reductor: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py:100 in __deepcopy__ │
│ │
│ 97 class Tensor(torch._C._TensorBase): │
│ 98 │ def __deepcopy__(self, memo): │
│ 99 │ │ if has_torch_function_unary(self): │
│ ❱ 100 │ │ │ return handle_torch_function(Tensor.__deepcopy__, (self,), self, memo) │
│ 101 │ │ if not self.is_leaf: │
│ 102 │ │ │ raise RuntimeError( │
│ 103 │ │ │ │ "Only Tensors created explicitly by the user " │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/overrides.py:1534 in │
│ handle_torch_function │
│ │
│ 1531 │ │ │
│ 1532 │ │ # Use `public_api` instead of `implementation` so __torch_function__ │
│ 1533 │ │ # implementations can do equality/identity comparisons. │
│ ❱ 1534 │ │ result = torch_func_method(public_api, types, args, kwargs) │
│ 1535 │ │ │
│ 1536 │ │ if result is not NotImplemented: │
│ 1537 │ │ │ return result │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/torch_core.py:372 in │
│ __torch_function__ │
│ │
│ 369 │ def __torch_function__(cls, func, types, args=(), kwargs=None): │
│ 370 │ │ if cls.debug and func.__name__ not in ('__str__','__repr__'): print(func, types, │
│ 371 │ │ if _torch_handled(args, cls._opt, func): types = (torch.Tensor,) │
│ ❱ 372 │ │ res = super().__torch_function__(func, types, args, ifnone(kwargs, {})) │
│ 373 │ │ dict_objs = _find_args(args) if args else _find_args(list(kwargs.values())) │
│ 374 │ │ if issubclass(type(res),TensorBase) and dict_objs: res.set_meta(dict_objs[0],as_ │
│ 375 │ │ elif dict_objs and is_listy(res): [r.set_meta(dict_objs[0],as_copy=True) for r i │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py:1279 in │
│ __torch_function__ │
│ │
│ 1276 │ │ │ return NotImplemented │
│ 1277 │ │ │
│ 1278 │ │ with _C.DisableTorchFunction(): │
│ ❱ 1279 │ │ │ ret = func(*args, **kwargs) │
│ 1280 │ │ │ if func in get_default_nowrap_functions(): │
│ 1281 │ │ │ │ return ret │
│ 1282 │ │ │ else: │
│ │
│ /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py:185 in __deepcopy__ │
│ │
│ 182 │ │ │ │ else: │
│ 183 │ │ │ │ │ new_tensor = self.new_empty([]) │
│ 184 │ │ │ │ │ if type(new_tensor) is not type(self): │
│ ❱ 185 │ │ │ │ │ │ raise RuntimeError( │
│ 186 │ │ │ │ │ │ │ "The default implementation of __deepcopy__() for non-wrappe │
│ 187 │ │ │ │ │ │ │ "only works for subclass types that implement new_empty() an │
│ 188 │ │ │ │ │ │ │ "that function returns another instance of the same subclass │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
RuntimeError: Exception occured in `LRFinder` when calling event `before_fit`:
The default implementation of __deepcopy__() for non-wrapper subclasses only works for subclass types that
implement new_empty() and for which that function returns another instance of the same subclass. You should either
properly implement new_empty() for your subclass or override __deepcopy__() if it is intended behavior for
new_empty() to return an instance of a different type.
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py(185)__deepcopy__()
183 new_tensor = self.new_empty([])
184 if type(new_tensor) is not type(self):
--> 185 raise RuntimeError(
186 "The default implementation of __deepcopy__() for non-wrapper subclasses "
187 "only works for subclass types that implement new_empty() and for which "
PDB Debugger Session
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py(1279)__torch_function__()
1277
1278 with _C.DisableTorchFunction():
-> 1279 ret = func(*args, **kwargs)
1280 if func in get_default_nowrap_functions():
1281 return ret
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/fastai/torch_core.py(372)__torch_function__()
370 if cls.debug and func.__name__ not in ('__str__','__repr__'): print(func, types, args, kwargs)
371 if _torch_handled(args, cls._opt, func): types = (torch.Tensor,)
--> 372 res = super().__torch_function__(func, types, args, ifnone(kwargs, {}))
373 dict_objs = _find_args(args) if args else _find_args(list(kwargs.values()))
374 if issubclass(type(res),TensorBase) and dict_objs: res.set_meta(dict_objs[0],as_copy=True)
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/overrides.py(1534)handle_torch_function()
1532 # Use `public_api` instead of `implementation` so __torch_function__
1533 # implementations can do equality/identity comparisons.
-> 1534 result = torch_func_method(public_api, types, args, kwargs)
1535
1536 if result is not NotImplemented:
ipdb> p result
*** NameError: name 'result' is not defined
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/site-packages/torch/_tensor.py(100)__deepcopy__()
98 def __deepcopy__(self, memo):
99 if has_torch_function_unary(self):
--> 100 return handle_torch_function(Tensor.__deepcopy__, (self,), self, memo)
101 if not self.is_leaf:
102 raise RuntimeError(
ipdb> p self
TensorBase([[[-1., -1.],
[-1., 1.],
[ 1., -1.],
[ 1., 1.]]], device='cuda:0')
ipdb> p self.name
None
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/copy.py(153)deepcopy()
151 copier = getattr(x, "__deepcopy__", None)
152 if copier is not None:
--> 153 y = copier(memo)
154 else:
155 reductor = dispatch_table.get(cls)
ipdb> p memo
*** AttributeError: fs
ipdb> p copier
<bound method Tensor.__deepcopy__ of TensorBase([[[-1., -1.],
[-1., 1.],
[ 1., -1.],
[ 1., 1.]]], device='cuda:0')>
ipdb> up
> /home/csaroff/.miniconda3/lib/python3.9/copy.py(230)_deepcopy_dict()
228 memo[id(x)] = y
229 for key, value in x.items():
--> 230 y[deepcopy(key, memo)] = deepcopy(value, memo)
231 return y
232 d[dict] = _deepcopy_dict
ipdb> p key
'targ_pts'
ipdb> p value
TensorBase([[[-1., -1.],
[-1., 1.],
[ 1., -1.],
[ 1., 1.]]], device='cuda:0')
ipdb>
Thanks for the kind words.
If you pass restore_state=False
to fastxtend's Learner.lr_find
, it should behave exactly like the fastai version of lr_find
and skip the deepcopy (and also skip restoring the random state).
I was able to recreate the error if I pass aug_transforms
to a fastai DataLoader's batch_tfms
. The PyTorch error message and related code suggests that the issue might be with fastai's TensorBase
not correctly implementing required methods for deepcopy
to work, but I need to investigate further.
Perfect! Now I can import *
again. Thanks!
fastai/fastai#3882 should resolve this issue in the next release of fastai.