Hi,
I like to build a weed classifier using a number of images where the according label is listed in a csv file.
Hence I tried to write my own function for the get_y parameter of DataBlock().
The lesson 2 example uses parent_label. My function is:
def get_weed_label( o): return df[df[“Filename”].str.contains( o)].Species.iloc[0]
df is a data frame with the csv data. I tested the function and it returns the correct label for each image as a string; which is identical to what parent_label does.
However after calling weeds = Datablock() it gives the below error message/TypeError when calling :
dls = weeds.dataloaders( path).
Who can explain what the issue with my get_weed_label function is??
thanks a lot
Norbert
Error message:
TypeError Traceback (most recent call last)
/tmp/ipykernel_11948/27525593.py in
1 # path = Path( ‘weed_labels_in_directories’)
----> 2 dls = weeds.dataloaders( path)
/opt/conda/lib/python3.7/site-packages/fastai/data/block.py in dataloaders(self, source, path, verbose, **kwargs)
111
112 def dataloaders(self, source, path=’.’, verbose=False, **kwargs):
→ 113 dsets = self.datasets(source, verbose=verbose)
114 kwargs = {**self.dls_kwargs, **kwargs, ‘verbose’: verbose}
115 return dsets.dataloaders(path=path, after_item=self.item_tfms, after_batch=self.batch_tfms, **kwargs)
/opt/conda/lib/python3.7/site-packages/fastai/data/block.py in datasets(self, source, verbose)
108 splits = (self.splitter or RandomSplitter())(items)
109 pv(f"{len(splits)} datasets of sizes {’,’.join([str(len(s)) for s in splits])}", verbose)
→ 110 return Datasets(items, tfms=self._combine_type_tfms(), splits=splits, dl_type=self.dl_type, n_inp=self.n_inp, verbose=verbose)
111
112 def dataloaders(self, source, path=’.’, verbose=False, **kwargs):
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in init(self, items, tfms, tls, n_inp, dl_type, **kwargs)
332 def init(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
333 super().init(dl_type=dl_type)
→ 334 self.tls = L(tls if tls else [TfmdLists(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
335 self.n_inp = ifnone(n_inp, max(1, len(self.tls)-1))
336
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in (.0)
332 def init(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
333 super().init(dl_type=dl_type)
→ 334 self.tls = L(tls if tls else [TfmdLists(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
335 self.n_inp = ifnone(n_inp, max(1, len(self.tls)-1))
336
/opt/conda/lib/python3.7/site-packages/fastcore/foundation.py in call(cls, x, *args, **kwargs)
95 def call(cls, x=None, *args, **kwargs):
96 if not args and not kwargs and x is not None and isinstance(x,cls): return x
—> 97 return super().call(x, *args, **kwargs)
98
99 # Cell
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in init(self, items, tfms, use_list, do_setup, split_idx, train_setup, splits, types, verbose, dl_type)
255 if do_setup:
256 pv(f"Setting up {self.tfms}", verbose)
→ 257 self.setup(train_setup=train_setup)
258
259 def _new(self, items, split_idx=None, **kwargs):
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in setup(self, train_setup)
274
275 def setup(self, train_setup=True):
→ 276 self.tfms.setup(self, train_setup)
277 if len(self) != 0:
278 x = super().getitem(0) if self.splits is None else super().getitem(self.splits[0])[0]
/opt/conda/lib/python3.7/site-packages/fastcore/transform.py in setup(self, items, train_setup)
190 tfms = self.fs[:]
191 self.fs.clear()
→ 192 for t in tfms: self.add(t,items, train_setup)
193
194 def add(self,ts, items=None, train_setup=False):
/opt/conda/lib/python3.7/site-packages/fastcore/transform.py in add(self, ts, items, train_setup)
194 def add(self,ts, items=None, train_setup=False):
195 if not is_listy(ts): ts=[ts]
→ 196 for t in ts: t.setup(items, train_setup)
197 self.fs+=ts
198 self.fs = self.fs.sorted(key=‘order’)
/opt/conda/lib/python3.7/site-packages/fastcore/transform.py in setup(self, items, train_setup)
77 def setup(self, items=None, train_setup=False):
78 train_setup = train_setup if self.train_setup is None else self.train_setup
—> 79 return self.setups(getattr(items, ‘train’, items) if train_setup else items)
80
81 def _call(self, fn, x, split_idx=None, **kwargs):
/opt/conda/lib/python3.7/site-packages/fastcore/dispatch.py in call(self, *args, **kwargs)
121 elif self.inst is not None: f = MethodType(f, self.inst)
122 elif self.owner is not None: f = MethodType(f, self.owner)
→ 123 return f(*args, **kwargs)
124
125 def get(self, inst, owner):
/opt/conda/lib/python3.7/site-packages/fastai/data/transforms.py in setups(self, dsets)
249
250 def setups(self, dsets):
→ 251 if self.vocab is None and dsets is not None: self.vocab = CategoryMap(dsets, sort=self.sort, add_na=self.add_na)
252 self.c = len(self.vocab)
253
/opt/conda/lib/python3.7/site-packages/fastai/data/transforms.py in init(self, col, sort, add_na, strict)
225 if not hasattr(col,‘unique’): col = L(col, use_list=True)
226 # o==o
is the generalized definition of non-NaN used by Pandas
→ 227 items = L(o for o in col.unique() if o==o)
228 if sort: items = items.sorted()
229 self.items = ‘#na#’ + items if add_na else items
/opt/conda/lib/python3.7/site-packages/fastcore/foundation.py in unique(self, sort, bidir, start)
161 def enumerate(self): return L(enumerate(self))
162 def renumerate(self): return L(renumerate(self))
→ 163 def unique(self, sort=False, bidir=False, start=None): return L(uniqueify(self, sort=sort, bidir=bidir, start=start))
164 def val2idx(self): return val2idx(self)
165 def cycle(self): return cycle(self)
/opt/conda/lib/python3.7/site-packages/fastcore/basics.py in uniqueify(x, sort, bidir, start)
661 def uniqueify(x, sort=False, bidir=False, start=None):
662 “Unique elements in x
, optional sort
, optional return reverse correspondence, optional prepend with elements.”
→ 663 res = list(dict.fromkeys(x))
664 if start is not None: res = listify(start)+res
665 if sort: res.sort()
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in (.0)
266 def _after_item(self, o): return self.tfms(o)
267 def repr(self): return f"{self.class.name}: {self.items}\ntfms - {self.tfms.fs}"
→ 268 def iter(self): return (self[i] for i in range(len(self)))
269 def show(self, o, **kwargs): return self.tfms.show(o, **kwargs)
270 def decode(self, o, **kwargs): return self.tfms.decode(o, **kwargs)
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in getitem(self, idx)
302 res = super().getitem(idx)
303 if self._after_item is None: return res
→ 304 return self._after_item(res) if is_indexer(idx) else res.map(self._after_item)
305
306 # Cell
/opt/conda/lib/python3.7/site-packages/fastai/data/core.py in _after_item(self, o)
264 raise
265 def subset(self, i): return self._new(self._get(self.splits[i]), split_idx=i)
→ 266 def _after_item(self, o): return self.tfms(o)
267 def repr(self): return f"{self.class.name}: {self.items}\ntfms - {self.tfms.fs}"
268 def iter(self): return (self[i] for i in range(len(self)))
/opt/conda/lib/python3.7/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]
/opt/conda/lib/python3.7/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
/opt/conda/lib/python3.7/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}’
/opt/conda/lib/python3.7/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):
/opt/conda/lib/python3.7/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)
/opt/conda/lib/python3.7/site-packages/fastcore/dispatch.py in call(self, *args, **kwargs)
121 elif self.inst is not None: f = MethodType(f, self.inst)
122 elif self.owner is not None: f = MethodType(f, self.owner)
→ 123 return f(*args, **kwargs)
124
125 def get(self, inst, owner):
/tmp/ipykernel_11948/34029949.py in get_weed_label(o)
----> 1 def get_weed_label( o): return df[df[“Filename”].str.contains(o)].Species.iloc[0]
/opt/conda/lib/python3.7/site-packages/pandas/core/strings/accessor.py in wrapper(self, *args, **kwargs)
114 )
115 raise TypeError(msg)
→ 116 return func(self, *args, **kwargs)
117
118 wrapper.name = func_name
/opt/conda/lib/python3.7/site-packages/pandas/core/strings/accessor.py in contains(self, pat, case, flags, na, regex)
1151 dtype: bool
1152 “”"
→ 1153 if regex and re.compile(pat).groups:
1154 warnings.warn(
1155 "This pattern has match groups. To actually get the "
/opt/conda/lib/python3.7/re.py in compile(pattern, flags)
234 def compile(pattern, flags=0):
235 “Compile a regular expression pattern, returning a Pattern object.”
→ 236 return _compile(pattern, flags)
237
238 def purge():
/opt/conda/lib/python3.7/re.py in _compile(pattern, flags)
285 return pattern
286 if not sre_compile.isstring(pattern):
→ 287 raise TypeError(“first argument must be string or compiled pattern”)
288 p = sre_compile.compile(pattern, flags)
289 if not (flags & DEBUG):
TypeError: first argument must be string or compiled pattern