I am trying to build the DataBlocks API for MNIST and trying to figure out why
path = untar_data(URLs.MNIST_TINY)
dblock = DataBlock(blocks=(ImageBlock, CategoryBlock),
get_items=get_image_files,
get_x=PILImage.create,
get_y=parent_label,
splitter=GrandparentSplitter())
This API doesn’t work when I do dls=dblock.dataloaders(path)
.
Here is the stack trace:
AttributeError Traceback (most recent call last)
<ipython-input-59-0353eb4f73af> in <module>
----> 1 dls = dblock.dataloaders(path)
~/repos/fastai2/fastai2/data/block.py in dataloaders(self, source, path, verbose, **kwargs)
96
97 def dataloaders(self, source, path='.', verbose=False, **kwargs):
---> 98 dsets = self.datasets(source)
99 kwargs = {**self.dls_kwargs, **kwargs, 'verbose': verbose}
100 return dsets.dataloaders(path=path, after_item=self.item_tfms, after_batch=self.batch_tfms, **kwargs)
~/repos/fastai2/fastai2/data/block.py in datasets(self, source, verbose)
93 splits = (self.splitter or RandomSplitter())(items)
94 pv(f"{len(splits)} datasets of sizes {','.join([str(len(s)) for s in splits])}", verbose)
---> 95 return Datasets(items, tfms=self._combine_type_tfms(), splits=splits, dl_type=self.dl_type, n_inp=self.n_inp, verbose=verbose)
96
97 def dataloaders(self, source, path='.', verbose=False, **kwargs):
~/repos/fastai2/fastai2/data/core.py in __init__(self, items, tfms, tls, n_inp, dl_type, **kwargs)
272 def __init__(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
273 super().__init__(dl_type=dl_type)
--> 274 self.tls = L(tls if tls else [TfmdLists(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
275 self.n_inp = (1 if len(self.tls)==1 else len(self.tls)-1) if n_inp is None else n_inp
276
~/repos/fastai2/fastai2/data/core.py in <listcomp>(.0)
272 def __init__(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
273 super().__init__(dl_type=dl_type)
--> 274 self.tls = L(tls if tls else [TfmdLists(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
275 self.n_inp = (1 if len(self.tls)==1 else len(self.tls)-1) if n_inp is None else n_inp
276
~/repos/fastai2/fastcore/fastcore/foundation.py in __call__(cls, x, *args, **kwargs)
39 return x
40
---> 41 res = super().__call__(*((x,) + args), **kwargs)
42 res._newchk = 0
43 return res
~/repos/fastai2/fastai2/data/core.py in __init__(self, items, tfms, use_list, do_setup, split_idx, train_setup, splits, types, verbose)
212 if do_setup:
213 pv(f"Setting up {self.tfms}", verbose)
--> 214 self.setup(train_setup=train_setup)
215
216 def _new(self, items, **kwargs): return super()._new(items, tfms=self.tfms, do_setup=False, types=self.types, **kwargs)
~/repos/fastai2/fastai2/data/core.py in setup(self, train_setup)
232 for f in self.tfms.fs:
233 self.types.append(getattr(f, 'input_types', type(x)))
--> 234 x = f(x)
235 self.types.append(type(x))
236 types = L(t if is_listy(t) else [t] for t in self.types).concat().unique()
~/repos/fastai2/fastcore/fastcore/transform.py in __call__(self, x, **kwargs)
70 @property
71 def name(self): return getattr(self, '_name', _get_name(self))
---> 72 def __call__(self, x, **kwargs): return self._call('encodes', x, **kwargs)
73 def decode (self, x, **kwargs): return self._call('decodes', x, **kwargs)
74 def __repr__(self): return f'{self.name}: {self.encodes} {self.decodes}'
~/repos/fastai2/fastcore/fastcore/transform.py in _call(self, fn, x, split_idx, **kwargs)
80 def _call(self, fn, x, split_idx=None, **kwargs):
81 if split_idx!=self.split_idx and self.split_idx is not None: return x
---> 82 return self._do_call(getattr(self, fn), x, **kwargs)
83
84 def _do_call(self, f, x, **kwargs):
~/repos/fastai2/fastcore/fastcore/transform.py in _do_call(self, f, x, **kwargs)
84 def _do_call(self, f, x, **kwargs):
85 if not _is_tuple(x):
---> 86 return x if f is None else retain_type(f(x, **kwargs), x, f.returns_none(x))
87 res = tuple(self._do_call(f, x_, **kwargs) for x_ in x)
88 return retain_type(res, x)
~/repos/fastai2/fastcore/fastcore/dispatch.py in __call__(self, *args, **kwargs)
96 if not f: return args[0]
97 if self.inst is not None: f = MethodType(f, self.inst)
---> 98 return f(*args, **kwargs)
99
100 def __get__(self, inst, owner):
~/repos/fastai2/fastai2/vision/core.py in create(cls, fn, **kwargs)
96 if isinstance(fn,ndarray): return cls(Image.fromarray(fn))
97 if isinstance(fn,bytes): fn = io.BytesIO(fn)
---> 98 return cls(load_image(fn, **merge(cls._open_args, kwargs)))
99
100 def show(self, ctx=None, **kwargs):
AttributeError: 'DataBlock' object has no attribute '_open_args'
Rather:
dblock = DataBlock(blocks=(ImageBlock, CategoryBlock),
get_items=get_image_files,
get_y=parent_label,
splitter=GrandparentSplitter())
Works.