I applied your proposed code and now when get_preds
is executed, it returns the following error:
PermissionError: [Errno 13] Permission denied: ‘Datasets/roi_detection_subset/test/’.
The full stack trace is:
---------------------------------------------------------------------------
PermissionError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_15560\664772027.py in <module>
----> 1 preds, targs = learn.get_preds(dl=test_dl)
2
3 predicted_bboxes = ((preds + 1) / 2).numpy()
4 # (preds + 1) is used to make negative predictions turn into positive
5 # NOTE: Why is ((preds + 1) divided by 2? are the predictions too big (I GET THAT IT'S A NORMALIZATION OF PREDICTIONS)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\learner.py in get_preds(self, ds_idx, dl, with_input, with_decoded, with_loss, act, inner, reorder, cbs, **kwargs)
251 if with_loss: ctx_mgrs.append(self.loss_not_reduced())
252 with ContextManagers(ctx_mgrs):
--> 253 self._do_epoch_validate(dl=dl)
254 if act is None: act = getattr(self.loss_func, 'activation', noop)
255 res = cb.all_tensors()
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\learner.py in _do_epoch_validate(self, ds_idx, dl)
201 if dl is None: dl = self.dls[ds_idx]
202 self.dl = dl
--> 203 with torch.no_grad(): self._with_events(self.all_batches, 'validate', CancelValidException)
204
205 def _do_epoch(self):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\learner.py in _with_events(self, f, event_type, ex, final)
161
162 def _with_events(self, f, event_type, ex, final=noop):
--> 163 try: self(f'before_{event_type}'); f()
164 except ex: self(f'after_cancel_{event_type}')
165 self(f'after_{event_type}'); final()
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\learner.py in all_batches(self)
167 def all_batches(self):
168 self.n_iter = len(self.dl)
--> 169 for o in enumerate(self.dl): self.one_batch(*o)
170
171 def _do_one_batch(self):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\load.py in __iter__(self)
107 self.before_iter()
108 self.__idxs=self.get_idxs() # called in context of main process (not workers/subprocesses)
--> 109 for b in _loaders[self.fake_l.num_workers==0](self.fake_l):
110 if self.device is not None: b = to_device(b, self.device)
111 yield self.after_batch(b)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\utils\data\dataloader.py in __next__(self)
528 if self._sampler_iter is None:
529 self._reset()
--> 530 data = self._next_data()
531 self._num_yielded += 1
532 if self._dataset_kind == _DatasetKind.Iterable and \
~\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\utils\data\dataloader.py in _next_data(self)
568 def _next_data(self):
569 index = self._next_index() # may raise StopIteration
--> 570 data = self._dataset_fetcher.fetch(index) # may raise StopIteration
571 if self._pin_memory:
572 data = _utils.pin_memory.pin_memory(data)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\torch\utils\data\_utils\fetch.py in fetch(self, possibly_batched_index)
37 raise StopIteration
38 else:
---> 39 data = next(self.dataset_iter)
40 return self.collate_fn(data)
41
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\load.py in create_batches(self, samps)
116 if self.dataset is not None: self.it = iter(self.dataset)
117 res = filter(lambda o:o is not None, map(self.do_item, samps))
--> 118 yield from map(self.do_batch, self.chunkify(res))
119
120 def new(self, dataset=None, cls=None, **kwargs):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\basics.py in chunked(it, chunk_sz, drop_last, n_chunks)
215 if not isinstance(it, Iterator): it = iter(it)
216 while True:
--> 217 res = list(itertools.islice(it, chunk_sz))
218 if res and (len(res)==chunk_sz or not drop_last): yield res
219 if len(res)<chunk_sz: return
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\load.py in do_item(self, s)
131 def prebatched(self): return self.bs is None
132 def do_item(self, s):
--> 133 try: return self.after_item(self.create_item(s))
134 except SkipItemException: return None
135 def chunkify(self, b): return b if self.prebatched else chunked(b, self.bs, self.drop_last)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\load.py in create_item(self, s)
138 def retain(self, res, b): return retain_types(res, b[0] if is_listy(b) else b)
139 def create_item(self, s):
--> 140 if self.indexed: return self.dataset[s or 0]
141 elif s is None: return next(self.it)
142 else: raise IndexError("Cannot index an iterable dataset numerically - must use `None`.")
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\core.py in __getitem__(self, it)
330
331 def __getitem__(self, it):
--> 332 res = tuple([tl[it] for tl in self.tls])
333 return res if is_indexer(it) else list(zip(*res))
334
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\core.py in <listcomp>(.0)
330
331 def __getitem__(self, it):
--> 332 res = tuple([tl[it] for tl in self.tls])
333 return res if is_indexer(it) else list(zip(*res))
334
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\core.py in __getitem__(self, idx)
296 res = super().__getitem__(idx)
297 if self._after_item is None: return res
--> 298 return self._after_item(res) if is_indexer(idx) else res.map(self._after_item)
299
300 # Cell
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\data\core.py in _after_item(self, o)
258 return super()._new(items, tfms=self.tfms, do_setup=False, types=self.types, split_idx=split_idx, **kwargs)
259 def subset(self, i): return self._new(self._get(self.splits[i]), split_idx=i)
--> 260 def _after_item(self, o): return self.tfms(o)
261 def __repr__(self): return f"{self.__class__.__name__}: {self.items}\ntfms - {self.tfms.fs}"
262 def __iter__(self): return (self[i] for i in range(len(self)))
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\transform.py in __call__(self, o)
198 self.fs = self.fs.sorted(key='order')
199
--> 200 def __call__(self, o): return compose_tfms(o, tfms=self.fs, split_idx=self.split_idx)
201 def __repr__(self): return f"Pipeline: {' -> '.join([f.name for f in self.fs if f.name != 'noop'])}"
202 def __getitem__(self,i): return self.fs[i]
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\transform.py in compose_tfms(x, tfms, is_enc, reverse, **kwargs)
148 for f in tfms:
149 if not is_enc: f = f.decode
--> 150 x = f(x, **kwargs)
151 return x
152
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\transform.py in __call__(self, x, **kwargs)
71 @property
72 def name(self): return getattr(self, '_name', _get_name(self))
---> 73 def __call__(self, x, **kwargs): return self._call('encodes', x, **kwargs)
74 def decode (self, x, **kwargs): return self._call('decodes', x, **kwargs)
75 def __repr__(self): return f'{self.name}:\nencodes: {self.encodes}decodes: {self.decodes}'
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\transform.py in _call(self, fn, x, split_idx, **kwargs)
81 def _call(self, fn, x, split_idx=None, **kwargs):
82 if split_idx!=self.split_idx and self.split_idx is not None: return x
---> 83 return self._do_call(getattr(self, fn), x, **kwargs)
84
85 def _do_call(self, f, x, **kwargs):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\transform.py in _do_call(self, f, x, **kwargs)
87 if f is None: return x
88 ret = f.returns(x) if hasattr(f,'returns') else None
---> 89 return retain_type(f(x, **kwargs), x, ret)
90 res = tuple(self._do_call(f, x_, **kwargs) for x_ in x)
91 return retain_type(res, x)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastcore\dispatch.py in __call__(self, *args, **kwargs)
116 elif self.inst is not None: f = MethodType(f, self.inst)
117 elif self.owner is not None: f = MethodType(f, self.owner)
--> 118 return f(*args, **kwargs)
119
120 def __get__(self, inst, owner):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\vision\core.py in create(cls, fn, **kwargs)
108 if isinstance(fn,ndarray): return cls(Image.fromarray(fn))
109 if isinstance(fn,bytes): fn = io.BytesIO(fn)
--> 110 return cls(load_image(fn, **merge(cls._open_args, kwargs)))
111
112 def show(self, ctx=None, **kwargs):
~\AppData\Local\Programs\Python\Python37\lib\site-packages\fastai\vision\core.py in load_image(fn, mode)
83 def load_image(fn, mode=None):
84 "Open and load a `PIL.Image` and convert to `mode`"
---> 85 im = Image.open(fn)
86 im.load()
87 im = im._new(im.im)
~\AppData\Local\Programs\Python\Python37\lib\site-packages\PIL\Image.py in open(fp, mode, formats)
2951
2952 if filename:
-> 2953 fp = builtins.open(filename, "rb")
2954 exclusive_fp = True
2955
PermissionError: [Errno 13] Permission denied: 'Datasets/roi_detection_subset/test/'
According to the stack trace I understand the error is due to the fact that in the last inner function, the open function, there is expected to be an image filename as the parameter but instead a path is passed (the path is ‘Datasets/roi_detection_subset/test/’).
My original code of inference/batch prediction was done by taking as reference the example code shown at the following website: Inference With fast.ai | Just Stir It Some More.
After reading the documentation of fast.ai on DataLoaders.test_dl
(Data core | fastai) I understand the appropiate way to create the test dataloader is how I was doing, that is, passing a list of the test image filenames, instead of their path.
I hope anyone can give me any suggestions on how I can fix the original error stated at the start of this topic.