Skip to content

explode_types() feeds retain_type() with surprising arguments. #539

@fakedrake

Description

@fakedrake
data_block = DataBlock(
    blocks=(ImageBlock, CategoryBlock), 
    get_x=existing(ColReader('thumbnail_path')),
    get_y=ColReader('label'),
    splitter=RandomSplitter(),
    item_tfms=Resize(224),
    batch_tfms=aug_transforms()
)
train = data_block.dataloaders(train_df, bs=4)

train.show_batch(4)

Gets

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[20], line 11
      1 data_block = DataBlock(
      2     blocks=(ImageBlock, CategoryBlock), 
      3     get_x=existing(ColReader('thumbnail_path')),
   (...)
      7     batch_tfms=aug_transforms()
      8 )
      9 train = data_block.dataloaders(train_df, bs=4)
---> 11 train.show_batch(4)

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:151, in TfmdDL.show_batch(self, b, max_n, ctxs, show, unique, **kwargs)
    149 if b is None: b = self.one_batch()
    150 if not show: return self._pre_show_batch(b, max_n=max_n)
--> 151 show_batch(*self._pre_show_batch(b, max_n=max_n), ctxs=ctxs, max_n=max_n, **kwargs)
    152 if unique: self.get_idxs = old_get_idxs

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:131, in TfmdDL._pre_show_batch(self, b, max_n)
    129 def _pre_show_batch(self, b, max_n=9):
    130     "Decode `b` to be ready for `show_batch`"
--> 131     b = self.decode(b)
    132     if hasattr(b, 'show'): return b,None,None
    133     its = self._decode_batch(b, max_n, full=False)

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:115, in TfmdDL.decode(self, b)
    112 def decode(self, 
    113     b # Batch to decode
    114 ):
--> 115     return to_cpu(self.after_batch.decode(self._retain_dl(b)))

File /opt/conda/lib/python3.10/site-packages/fastai/data/core.py:86, in TfmdDL._retain_dl(self, b)
     84 def _retain_dl(self,b):
     85     if not getattr(self, '_types', None): self._one_pass()
---> 86     return retain_types(b, typs=self._types)

File /opt/conda/lib/python3.10/site-packages/fastcore/dispatch.py:199, in retain_types(new, old, typs)
    197 def retain_types(new, old=None, typs=None):
    198     "Cast each item of `new` to type of matching item in `old` if it's a superclass"
--> 199     if not is_listy(new): return retain_type(new, old, typs)
    200     if typs is not None:
    201         if isinstance(typs, dict):

File /opt/conda/lib/python3.10/site-packages/fastcore/dispatch.py:193, in retain_type(new, old, typ, as_copy)
    191     typ = old if isinstance(old,type) else type(old)
    192 # Do nothing the new type is already an instance of requested type (i.e. same type)
--> 193 if typ==NoneType or isinstance(new, typ): return new
    194 return retain_meta(old, cast(new, typ), as_copy=as_copy)

TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union

The problem seems to be that explode_types() sometimes returns a dictionary which surprises retain_type() with a non-listy type.

ipdb>  p typ
{<class 'tuple'>: [<class 'fastai.torch_core.TensorImage'>, <class 'fastai.torch_core.TensorCategory'>]}

I am new to fastai and struggling to understand how to fix this without breaking anything else. Any advice?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions