fastai / fastai_dev

fast.ai early development experiments
Apache License 2.0
641 stars 351 forks source link

Passing Pipeline to item_tfms causes 'TypeError: '<' not supported between instances of 'L' and 'int'' #284

Closed rbracco closed 5 years ago

rbracco commented 5 years ago

I pulled the latest code and it breaks the DataBlock in our audio code.

Full stack trace:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-2a4703583e30> in <module>
      3 #a2s = AudioToSpec.from_cfg(cfg_voice)
      4 tfms = Pipeline(funcs=[CropSignal(2000), AudioToSpec()], as_item=True)
----> 5 dbunch = auds.databunch(p10speakers, item_tfms=tfms, bs=64)

~/rob/dev_fastai/dev/local/data/block.py in databunch(self, source, path, type_tfms, item_tfms, batch_tfms, **kwargs)
     84         batch_tfms = _merge_tfms(self.default_batch_tfms, batch_tfms)
     85         kwargs = {**self.dbunch_kwargs, **kwargs}
---> 86         return dsrc.databunch(path=path, after_item=item_tfms, after_batch=batch_tfms, **kwargs)
     87 
     88     _docs = dict(datasource="Create a `Datasource` from `source` with `type_tfms`",

~/rob/dev_fastai/dev/local/data/core.py in databunch(self, bs, val_bs, shuffle_train, n, path, dl_type, dl_kwargs, **kwargs)
    149         if dl_type is None: dl_type = self._dl_type
    150         dls = [dl_type(self.subset(i), bs=b, shuffle=s, drop_last=s, n=n if i==0 else None, **kwargs, **dk)
--> 151                for i,(b,s,dk) in enumerate(zip(bss,shuffles,dl_kwargs))]
    152         return DataBunch(*dls, path=path)
    153 

~/rob/dev_fastai/dev/local/data/core.py in <listcomp>(.0)
    149         if dl_type is None: dl_type = self._dl_type
    150         dls = [dl_type(self.subset(i), bs=b, shuffle=s, drop_last=s, n=n if i==0 else None, **kwargs, **dk)
--> 151                for i,(b,s,dk) in enumerate(zip(bss,shuffles,dl_kwargs))]
    152         return DataBunch(*dls, path=path)
    153 

~/rob/dev_fastai/dev/local/data/core.py in __init__(self, dataset, bs, shuffle, num_workers, **kwargs)
     37         if num_workers is None: num_workers = min(16, defaults.cpus)
     38         for nm in _batch_tfms:
---> 39             kwargs[nm] = Pipeline(kwargs.get(nm,None), as_item=(nm=='before_batch'))
     40         super().__init__(dataset, bs=bs, shuffle=shuffle, num_workers=num_workers, **kwargs)
     41         for nm in _batch_tfms: kwargs[nm].setup(self)

~/rob/dev_fastai/dev/local/core/transform.py in __init__(self, funcs, as_item, split_idx)
    178         else:
    179             if isinstance(funcs, Transform): funcs = [funcs]
--> 180             self.fs = L(ifnone(funcs,[noop])).map(mk_transform).sorted(key='order')
    181         for f in self.fs:
    182             name = camel2snake(type(f).__name__)

~/rob/dev_fastai/dev/local/core/foundation.py in sorted(self, key, reverse)
    331             k=itemgetter(key)
    332         else: k=key
--> 333         return self._new(sorted(self.items, key=k, reverse=reverse))
    334 
    335     @classmethod

TypeError: '<' not supported between instances of 'L' and 'int'

%debug shows us what's going on...

image

funcs contains a single Transform (toTensor) and a pipeline, when it tries to sort them by order...

image

the order of the single transform is an int, and the pipeline's order is an L and trying to compare them causes the error.

Hope this was clear enough, please let me know if you need any other info.

sgugger commented 5 years ago

You can't directly pass a Pipeline for item_tfms and batch_tfms, just a list of transforms, since it adds other to it (like ToTensor in your example). Just remove the Pipeline and you should be fine.

rbracco commented 5 years ago

Thanks that fixes it.