Fastbook: 05_pet_breeds: KeyError during learn.fine_tune(2)

I am leveraging the 05_pet_breeds notebook to for a hackathon project using the “Labelled Faces in the Wild” dataset. I put the dataset which has over 13K images of faces in the same file structure as the Pets dataset, ie. ~/.fastai/data/lfw-deepfunneled/images/xxxxx_ddd.jpg

The DataBlock was created successfully and the output of dls. show_batch looks normal, but I am getting consistent errors during training about a KeyError. Does anyone know what this error message means?

learn = cnn_learner(dls, resnet34, metrics=error_rate)
learn.fine_tune(2)

epoch train_loss valid_loss error_rate time
0 8.869000 None None 00:26


KeyError Traceback (most recent call last)
in
1 learn = cnn_learner(dls, resnet34, metrics=error_rate)
----> 2 learn.fine_tune(2)

~/miniconda3/lib/python3.7/site-packages/fastcore/logargs.py in _f(*args, **kwargs)
54 init_args.update(log)
55 setattr(inst, ‘init_args’, init_args)
—> 56 return inst if to_return else f(*args, **kwargs)
57 return _f

~/miniconda3/lib/python3.7/site-packages/fastai/callback/schedule.py in fine_tune(self, epochs, base_lr, freeze_epochs, lr_mult, pct_start, div, **kwargs)
159 “Fine tune with freeze for freeze_epochs then with unfreeze from epochs using discriminative LR”
160 self.freeze()
–> 161 self.fit_one_cycle(freeze_epochs, slice(base_lr), pct_start=0.99, **kwargs)
162 base_lr /= 2
163 self.unfreeze()

~/miniconda3/lib/python3.7/site-packages/fastcore/logargs.py in _f(*args, **kwargs)
54 init_args.update(log)
55 setattr(inst, ‘init_args’, init_args)
—> 56 return inst if to_return else f(*args, **kwargs)
57 return _f

~/miniconda3/lib/python3.7/site-packages/fastai/callback/schedule.py in fit_one_cycle(self, n_epoch, lr_max, div, div_final, pct_start, wd, moms, cbs, reset_opt)
111 scheds = {‘lr’: combined_cos(pct_start, lr_max/div, lr_max, lr_max/div_final),
112 ‘mom’: combined_cos(pct_start, *(self.moms if moms is None else moms))}
–> 113 self.fit(n_epoch, cbs=ParamScheduler(scheds)+L(cbs), reset_opt=reset_opt, wd=wd)
114
115 # Cell

~/miniconda3/lib/python3.7/site-packages/fastcore/logargs.py in _f(*args, **kwargs)
54 init_args.update(log)
55 setattr(inst, ‘init_args’, init_args)
—> 56 return inst if to_return else f(*args, **kwargs)
57 return _f

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in fit(self, n_epoch, lr, wd, cbs, reset_opt)
205 self.opt.set_hypers(lr=self.lr if lr is None else lr)
206 self.n_epoch = n_epoch
–> 207 self._with_events(self._do_fit, ‘fit’, CancelFitException, self._end_cleanup)
208
209 def _end_cleanup(self): self.dl,self.xb,self.yb,self.pred,self.loss = None,(None,),(None,),None,None

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in with_events(self, f, event_type, ex, final)
153
154 def with_events(self, f, event_type, ex, final=noop):
–> 155 try: self(f’before
{event_type}’) ;f()
156 except ex: self(f’after_cancel
{event_type}’)
157 finally: self(f’after_{event_type}’) ;final()

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in _do_fit(self)
195 for epoch in range(self.n_epoch):
196 self.epoch=epoch
–> 197 self._with_events(self._do_epoch, ‘epoch’, CancelEpochException)
198
199 @log_args(but=‘cbs’)

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in with_events(self, f, event_type, ex, final)
153
154 def with_events(self, f, event_type, ex, final=noop):
–> 155 try: self(f’before
{event_type}’) ;f()
156 except ex: self(f’after_cancel
{event_type}’)
157 finally: self(f’after_{event_type}’) ;final()

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in _do_epoch(self)
190 def _do_epoch(self):
191 self._do_epoch_train()
–> 192 self._do_epoch_validate()
193
194 def _do_fit(self):

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in _do_epoch_validate(self, ds_idx, dl)
186 if dl is None: dl = self.dls[ds_idx]
187 self.dl = dl
–> 188 with torch.no_grad(): self._with_events(self.all_batches, ‘validate’, CancelValidException)
189
190 def _do_epoch(self):

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in with_events(self, f, event_type, ex, final)
153
154 def with_events(self, f, event_type, ex, final=noop):
–> 155 try: self(f’before
{event_type}’) ;f()
156 except ex: self(f’after_cancel
{event_type}’)
157 finally: self(f’after_{event_type}’) ;final()

~/miniconda3/lib/python3.7/site-packages/fastai/learner.py in all_batches(self)
159 def all_batches(self):
160 self.n_iter = len(self.dl)
–> 161 for o in enumerate(self.dl): self.one_batch(*o)
162
163 def _do_one_batch(self):

~/miniconda3/lib/python3.7/site-packages/fastai/data/load.py in iter(self)
100 self.before_iter()
101 self.__idxs=self.get_idxs() # called in context of main process (not workers/subprocesses)
–> 102 for b in _loadersself.fake_l.num_workers==0:
103 if self.device is not None: b = to_device(b, self.device)
104 yield self.after_batch(b)

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in next(self)
361
362 def next(self):
–> 363 data = self._next_data()
364 self._num_yielded += 1
365 if self._dataset_kind == _DatasetKind.Iterable and \

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in _next_data(self)
987 else:
988 del self._task_info[idx]
–> 989 return self._process_data(data)
990
991 def _try_put_index(self):

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in _process_data(self, data)
1012 self._try_put_index()
1013 if isinstance(data, ExceptionWrapper):
-> 1014 data.reraise()
1015 return data
1016

~/miniconda3/lib/python3.7/site-packages/torch/_utils.py in reraise(self)
393 # (https://bugs.python.org/issue2651), so we work around it.
394 msg = KeyErrorMessage(msg)
–> 395 raise self.exc_type(msg)

KeyError: Caught KeyError in DataLoader worker process 0.
Original Traceback (most recent call last):
File “/home/user/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/worker.py”, line 185, in _worker_loop
data = fetcher.fetch(index)
File “/home/user/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py”, line 34, in fetch
data = next(self.dataset_iter)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/load.py”, line 111, in create_batches
yield from map(self.do_batch, self.chunkify(res))
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/utils.py”, line 380, in chunked
res = list(itertools.islice(it, chunk_sz))
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/load.py”, line 124, in do_item
try: return self.after_item(self.create_item(s))
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/load.py”, line 130, in create_item
def create_item(self, s): return next(self.it) if s is None else self.dataset[s]
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/core.py”, line 314, in getitem
res = tuple([tl[it] for tl in self.tls])
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/core.py”, line 314, in
res = tuple([tl[it] for tl in self.tls])
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/core.py”, line 280, in getitem
return self._after_item(res) if is_indexer(idx) else res.map(self._after_item)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/core.py”, line 242, in _after_item
def _after_item(self, o): return self.tfms(o)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/transform.py”, line 198, in call
def call(self, o): return compose_tfms(o, tfms=self.fs, split_idx=self.split_idx)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/transform.py”, line 150, in compose_tfms
x = f(x, **kwargs)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/transform.py”, line 73, in call
def call(self, x, **kwargs): return self._call(‘encodes’, x, **kwargs)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/transform.py”, line 83, in _call
return self._do_call(getattr(self, fn), x, **kwargs)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/transform.py”, line 89, in _do_call
return retain_type(f(x, **kwargs), x, ret)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastcore/dispatch.py”, line 112, in call
return f(*args, **kwargs)
File “/home/user/miniconda3/lib/python3.7/site-packages/fastai/data/transforms.py”, line 240, in encodes
def encodes(self, o): return TensorCategory(self.vocab.o2i[o])
KeyError: ‘Charles_Chandler_IV’

It means there were labels in your validation set that were not present in the training set (so your split wound up completely removing some classes, potentially because they’re so rare). The solution would be to pass in a vocab to CategoryBlock

3 Likes

BTW: If you install the dev version/the next release from now will include a more verbose warning for both this and MultiCategoryBlock

2 Likes

Thank you, Zachary!