question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

UCF101 datasets with DataLoader returns error when stacking examples in mini-batches

See original GitHub issue

🐛 Bug

UCF101 dataset returns a RunTimeError when combined with standard DataLoader class. It returns the error when trying to stack multiple tensors in batches.

To Reproduce

import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

tfs = transforms.Compose([
            transforms.Lambda(lambda x: x / 255.), # scale in [0, 1]
            transforms.Lambda(lambda x: x.permute(0, 3, 1, 2) ) # reshape into (T, C, H, W)
    ])


# root, root_labels are the directories containing data and labels
d = datasets.UCF101(root, root_labels, frames_per_clip=25, step_between_clips=25, train=False, transform=tfs)
dataset = DataLoader(d, batch_size=7, shuffle=True, drop_last=True)

for i, (v, a, l) in enumerate(dataset):  # <- RunTimeError occurs here
    pass
RuntimeError                              Traceback (most recent call last)
      1 print(len(dataset))
----> 2 for i, (v, a, l) in enumerate(dataset):
      3     pass

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in __next__(self)
    343 
    344     def __next__(self):
--> 345         data = self._next_data()
    346         self._num_yielded += 1
    347         if self._dataset_kind == _DatasetKind.Iterable and \

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/dataloader.py in _next_data(self)
    383     def _next_data(self):
    384         index = self._next_index()  # may raise StopIteration
--> 385         data = self._dataset_fetcher.fetch(index)  # may raise StopIteration
    386         if self._pin_memory:
    387             data = _utils.pin_memory.pin_memory(data)

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/fetch.py in fetch(self, possibly_batched_index)
     45         else:
     46             data = self.dataset[possibly_batched_index]
---> 47         return self.collate_fn(data)

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/collate.py in default_collate(batch)
     77     elif isinstance(elem, container_abcs.Sequence):
     78         transposed = zip(*batch)
---> 79         return [default_collate(samples) for samples in transposed]
     80 
     81     raise TypeError(default_collate_err_msg_format.format(elem_type))

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/collate.py in <listcomp>(.0)
     77     elif isinstance(elem, container_abcs.Sequence):
     78         transposed = zip(*batch)
---> 79         return [default_collate(samples) for samples in transposed]
     80 
     81     raise TypeError(default_collate_err_msg_format.format(elem_type))

~/miniconda3/lib/python3.7/site-packages/torch/utils/data/_utils/collate.py in default_collate(batch)
     53             storage = elem.storage()._new_shared(numel)
     54             out = elem.new(storage)
---> 55         return torch.stack(batch, 0, out=out)
     56     elif elem_type.__module__ == 'numpy' and elem_type.__name__ != 'str_' \
     57             and elem_type.__name__ != 'string_':

RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 0. Got 2 and 1 in dimension 1 at /opt/conda/conda-bld/pytorch_1579022060824/work/aten/src/TH/generic/THTensor.cpp:612

Expected behavior

The iteration over the dataloader should return a video tensor of size (B, T, C, H, W) where B is batch size, T is the number of frames, C are the image channels and H and W the image dimensions.

Environment

  • PyTorch / torchvision Version: 1.4.0 / 0.5.0
  • OS (e.g., Linux): CentOS Linux 7
  • How you installed PyTorch / torchvision (conda, pip, source): conda
  • Python version: 3.7.3

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
AndreaCossucommented, Jun 5, 2020

Perfect, that’s working! I just added return to your last line:

def custom_collate(batch):
    filtered_batch = []
    for video, _, label in batch:
        filtered_batch.append((video, label))
    return torch.utils.data.dataloader.default_collate(filtered_batch)

Final working code

import torchvision.datasets as datasets
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

tfs = transforms.Compose([
             # scale in [0, 1]
             transforms.Lambda(lambda x: x / 255.),
             # reshape into (T, C, H, W)
             transforms.Lambda(lambda x: x.permute(0, 3, 1, 2) ) 
    ])


# root, root_labels are the directories containing data and labels
d = datasets.UCF101(root, root_labels, frames_per_clip=25, 
        step_between_clips=25, train=False, transform=tfs)
dataset = DataLoader(d, batch_size=7, shuffle=True, 
        drop_last=True, collate_fn=custom_collate)

for i, (v, l) in enumerate(dataset): 
    print(v.size())
    print(l)
    break

Thank you very much!!

2reactions
fmassacommented, Jun 5, 2020

Oh, I see, yes, this is an issue with the audio signal.

I would propose that you write a custom collate_fn that you pass to your DataLoader which will remove the audio file, maybe something like

def custom_collate(batch):
    filtered_batch = []
    for video, _, label in batch:
        filtered_batch.append((video, label))
    torch.utils.data.dataloader.default_collate(filtered_batch)
Read more comments on GitHub >

github_iconTop Results From Across the Web

Pytorch DataLoader fails when the number of examples are ...
Long answer. Based on your code making a reduced version of your Dataloader there is no error for batch sizes. Using 9 as...
Read more >
Starter: UCF101 with PyTorch - Kaggle
Explore and run machine learning code with Kaggle Notebooks | Using data from UCF101 Videos.
Read more >
Source code for gluoncv.data.dataloader
NDArray): return nd.stack(*data) elif isinstance(data[0], tuple): data ... the batch size does not evenly divide by the number of examples in the dataset....
Read more >
UCF101 Torchvision Dataset-to-DataLoader - PyTorch Forums
Hi, when I try to iterate on a dataloader object constructed from a UCF101 dataset object (from torchvision) as follows: import torch #TODO: ......
Read more >
An Introduction to Datasets and DataLoader in PyTorch - Wandb
This function is responsible for returning a sample from the dataset based on the index provided. class CustomDataset( ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found