pythonimagefast-ai

FastAI resizing works counterintuitive


I'm trying to use fastai for categorization purpose. I've splitted my images in to 3 directories: train, test and val, images are in different shapes.

This code produces "desirable" output with image scaled correctly:

from fastai.vision.all import *

train_dataloader = ImageDataLoaders.from_folder(
    path="data",
    train="train",
    test = "test",
    valid="val",
    bs=1,
    seed=42,
    batch_tfms=[*aug_transforms(size=(244,244)),
                Normalize.from_stats(*imagenet_stats)],
)

train_dataloader.show_batch()

"Correct" output

But when I try to increase bs parameter and then call train_dataloader.show_batch() I've got error suggesting that images haven't been reshaped.

from fastai.vision.all import *

train_dataloader = ImageDataLoaders.from_folder(
    path="data",
    train="train",
    test = "test",
    valid="val",
    bs=2,
    seed=42,
    batch_tfms=[*aug_transforms(size=(244,244)),
                Normalize.from_stats(*imagenet_stats)],
)

train_dataloader.show_batch()


---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In [13], line 1
----> 1 train_dataloader.show_batch()

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\fastai\data\core.py:149, in TfmdDL.show_batch(self, b, max_n, ctxs, show, unique, **kwargs)
    147     old_get_idxs = self.get_idxs
    148     self.get_idxs = lambda: Inf.zeros
--> 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)

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\fastai\data\load.py:172, in DataLoader.one_batch(self)
    170 def one_batch(self):
    171     if self.n is not None and len(self)==0: raise ValueError(f'This DataLoader does not contain any batches')
--> 172     with self.fake_l.no_multiproc(): res = first(self)
    173     if hasattr(self, 'it'): delattr(self, 'it')
    174     return res

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\fastcore\basics.py:660, in first(x, f, negate, **kwargs)
    658 x = iter(x)
    659 if f: x = filter_ex(x, f=f, negate=negate, gen=True, **kwargs)
--> 660 return next(x, None)

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\fastai\data\load.py:127, in DataLoader.__iter__(self)
    125 self.before_iter()
    126 self.__idxs=self.get_idxs() # called in context of main process (not workers/subprocesses)
--> 127 for b in _loaders[self.fake_l.num_workers==0](self.fake_l):
    128     # pin_memory causes tuples to be converted to lists, so convert them back to tuples
    129     if self.pin_memory and type(b) == list: b = tuple(b)
    130     if self.device is not None: b = to_device(b, self.device)

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\torch\utils\data\dataloader.py:628, in _BaseDataLoaderIter.__next__(self)
    625 if self._sampler_iter is None:
    626     # TODO(https://github.com/pytorch/pytorch/issues/76750)
    627     self._reset()  # type: ignore[call-arg]
--> 628 data = self._next_data()
    629 self._num_yielded += 1
    630 if self._dataset_kind == _DatasetKind.Iterable and \
    631         self._IterableDataset_len_called is not None and \
    632         self._num_yielded > self._IterableDataset_len_called:

File c:\USERS\DAWID\ANACONDA3\ENVS\415\lib\site-packages\torch\utils\data\dataloader.py:671, in _SingleProcessDataLoaderIter._next_data(self)
    669 def _next_data(self):
    670     index = self._next_index()  # may raise StopIteration
...
Mismatch found on axis 0 of the batch and is of type `TensorImage`:
    Item at index 0 has shape: torch.Size([3, 644, 800])
    Item at index 1 has shape: torch.Size([3, 420, 630])

Please include a transform in `after_item` that ensures all data of type TensorImage is the same size

I've tried other pythons version, reinsatlled FastAI via pip and anaconda, this one is from python 3.10.8 and fastai 2.7.10 I've also tried Resize insted of aug_transforms(size=(244,244)


Solution

  • Answer from future me: You have to add paramiter item_tfms with argument Resize(244).

    from fastai.vision.all import *
    
    train_dataloader = ImageDataLoaders.from_folder(
        path="data",
        train="train",
        test = "test",
        valid="val",
        bs=2,
        seed=42,
        item_tfms = Resize(244),
        batch_tfms=[*aug_transforms(size=(244,244)),
                    Normalize.from_stats(*imagenet_stats)],
    )
    
    train_dataloader.show_batch()