From 53084f5456db05a472aa5fba5d6f4ac1f510ec86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 15:05:19 -0500 Subject: [PATCH 01/11] Add fake data generator for UCF101 --- test/fakedata_generation.py | 43 +++++++++++++++++++++++++++++++++++++ test/test_datasets.py | 14 +++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index ab4333b74be..4238f586939 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -7,6 +7,9 @@ import torch from common_utils import get_tmp_dir import pickle +import random +from itertools import cycle +from torchvision.io.video import write_video @contextlib.contextmanager @@ -265,3 +268,43 @@ def voc_root(): f.write('test') yield tmp_dir + + +@contextlib.contextmanager +def ucf101_root(): + with get_tmp_dir() as tmp_dir: + ucf_dir = os.path.join(tmp_dir, 'UCF-101') + video_dir = os.path.join(ucf_dir, 'video') + annotations = os.path.join(ucf_dir, 'annotations') + + os.makedirs(ucf_dir) + os.makedirs(video_dir) + os.makedirs(annotations) + + fold_files = [] + for split in {'train', 'test'}: + for fold in range(1, 4): + fold_file = '{0}_list{:02d}.txt'.format(split, fold) + fold_files.append(os.path.join(annotations, fold_file)) + + file_handles = [open(x, 'w') for x in fold_files] + file_iter = cycle(file_handles) + + for i in range(0, 20): + current_class = 'class_{0}'.format(i + 1) + class_dir = os.path.join(video_dir, current_class) + os.makedirs(class_dir) + for group in range(0, 3): + for clip in range(0, 4): + # Save sample file + clip_name = 'v_{0}_g{1}_c{2}.avi'.format( + current_class, group, clip) + clip_path = os.path.join(class_dir, clip_name) + length = random.randrange(1, 20) + this_clip = torch.rand(length * 25, 320, 240, 3) + write_video(clip_path, this_clip, 25) + # Add to annotations + ann_file = next(file_iter) + ann_file.write('{0}\n'.format( + os.path.join(current_class, clip_name))) + yield (video_dir, annotations) diff --git a/test/test_datasets.py b/test/test_datasets.py index 60445b1d98a..b2d3dc9ed7b 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -9,7 +9,7 @@ import torchvision from common_utils import get_tmp_dir from fakedata_generation import mnist_root, cifar_root, imagenet_root, \ - cityscapes_root, svhn_root, voc_root + cityscapes_root, svhn_root, voc_root, ucf101_root import xml.etree.ElementTree as ET @@ -19,6 +19,12 @@ except ImportError: HAS_SCIPY = False +try: + import av + HAS_PYAV = True +except ImportError: + HAS_PYAV = False + class Tester(unittest.TestCase): def generic_classification_dataset_test(self, dataset, num_images=1): @@ -254,6 +260,12 @@ def test_voc_parse_xml(self, mock_download_extract): }] }}) + @unittest.skipIf(not HAS_SCIPY, "scipy unavailable") + def test_ucf101(self): + with ucf101_root() as (root, ann_root): + dataset = torchvision.datasets.UCF101(root, ann_root, 10) + self.assertEqual(len(dataset), 0) + if __name__ == '__main__': unittest.main() From b482ebf689ef244d960c8ede197aa43366c93f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 15:09:07 -0500 Subject: [PATCH 02/11] Minor error correction --- test/fakedata_generation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index 4238f586939..d8c5cf114c2 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -284,7 +284,7 @@ def ucf101_root(): fold_files = [] for split in {'train', 'test'}: for fold in range(1, 4): - fold_file = '{0}_list{:02d}.txt'.format(split, fold) + fold_file = '{:s}_list{:02d}.txt'.format(split, fold) fold_files.append(os.path.join(annotations, fold_file)) file_handles = [open(x, 'w') for x in fold_files] From fb22b545a7c0af04ea47cb7d9c2b6935698a4fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 15:11:55 -0500 Subject: [PATCH 03/11] Reduce total number of categories --- test/fakedata_generation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index d8c5cf114c2..2a2fa5f6077 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -290,7 +290,7 @@ def ucf101_root(): file_handles = [open(x, 'w') for x in fold_files] file_iter = cycle(file_handles) - for i in range(0, 20): + for i in range(0, 2): current_class = 'class_{0}'.format(i + 1) class_dir = os.path.join(video_dir, current_class) os.makedirs(class_dir) From ce769536fb5aece883d304b239a10277b94a1e0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 15:13:37 -0500 Subject: [PATCH 04/11] Fix naming --- test/fakedata_generation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index 2a2fa5f6077..d12e278e051 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -284,7 +284,7 @@ def ucf101_root(): fold_files = [] for split in {'train', 'test'}: for fold in range(1, 4): - fold_file = '{:s}_list{:02d}.txt'.format(split, fold) + fold_file = '{:s}list{:02d}.txt'.format(split, fold) fold_files.append(os.path.join(annotations, fold_file)) file_handles = [open(x, 'w') for x in fold_files] From ace42e95a13edd6abb91b4260d8665798a33b6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 17:34:21 -0500 Subject: [PATCH 05/11] Increase length --- test/fakedata_generation.py | 2 +- test/test_datasets.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index d12e278e051..39231ac7eaa 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -300,7 +300,7 @@ def ucf101_root(): clip_name = 'v_{0}_g{1}_c{2}.avi'.format( current_class, group, clip) clip_path = os.path.join(class_dir, clip_name) - length = random.randrange(1, 20) + length = random.randrange(10, 21) this_clip = torch.rand(length * 25, 320, 240, 3) write_video(clip_path, this_clip, 25) # Add to annotations diff --git a/test/test_datasets.py b/test/test_datasets.py index b2d3dc9ed7b..1320266001b 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -260,7 +260,7 @@ def test_voc_parse_xml(self, mock_download_extract): }] }}) - @unittest.skipIf(not HAS_SCIPY, "scipy unavailable") + @unittest.skipIf(not HAS_PYAV, "PyAV unavailable") def test_ucf101(self): with ucf101_root() as (root, ann_root): dataset = torchvision.datasets.UCF101(root, ann_root, 10) From 2797409b19993bcd746c94bcecea2392fd1ca005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 18:04:10 -0500 Subject: [PATCH 06/11] Store in uint8 --- test/fakedata_generation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index 39231ac7eaa..c7839c7e576 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -301,7 +301,8 @@ def ucf101_root(): current_class, group, clip) clip_path = os.path.join(class_dir, clip_name) length = random.randrange(10, 21) - this_clip = torch.rand(length * 25, 320, 240, 3) + this_clip = torch.randint( + 0, 256, (length * 25, 320, 240, 3), dtype=torch.uint8) write_video(clip_path, this_clip, 25) # Add to annotations ann_file = next(file_iter) From dbce58b6714f43651ac4819421219c94ba726d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 18:40:38 -0500 Subject: [PATCH 07/11] Close fds --- test/fakedata_generation.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/fakedata_generation.py b/test/fakedata_generation.py index c7839c7e576..cc984d3e693 100644 --- a/test/fakedata_generation.py +++ b/test/fakedata_generation.py @@ -308,4 +308,7 @@ def ucf101_root(): ann_file = next(file_iter) ann_file.write('{0}\n'.format( os.path.join(current_class, clip_name))) + # Close all file descriptors + for f in file_handles: + f.close() yield (video_dir, annotations) From f22e84fdcc1ae6d7b52b5319af8475e1185b31c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 19:15:01 -0500 Subject: [PATCH 08/11] Add assertGreater --- test/test_datasets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_datasets.py b/test/test_datasets.py index 1320266001b..c165b2edc43 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -264,7 +264,7 @@ def test_voc_parse_xml(self, mock_download_extract): def test_ucf101(self): with ucf101_root() as (root, ann_root): dataset = torchvision.datasets.UCF101(root, ann_root, 10) - self.assertEqual(len(dataset), 0) + self.assertGreater(len(dataset), 0) if __name__ == '__main__': From a2bb8ba48036946f4bd0deffd2116548af9066eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 20:01:06 -0500 Subject: [PATCH 09/11] Add dimension tests --- test/test_datasets.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/test_datasets.py b/test/test_datasets.py index c165b2edc43..cf144dc7074 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -266,6 +266,16 @@ def test_ucf101(self): dataset = torchvision.datasets.UCF101(root, ann_root, 10) self.assertGreater(len(dataset), 0) + video, audio, label = dataset[0] + self.assertEqual(video.size(), (10, 320, 240, 3)) + self.assertEqual(audio.size(), (1, 0)) + self.assertEqual(label, 0) + + video, audio, label = dataset[len(dataset) - 1] + self.assertEqual(video.size(), (10, 320, 240, 3)) + self.assertEqual(audio.size(), (1, 0)) + self.assertEqual(label, 1) + if __name__ == '__main__': unittest.main() From 9011aed02f8c8cfc4393c10fe91309dfbd3fffda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 20:58:55 -0500 Subject: [PATCH 10/11] Use numel instead of size --- test/test_datasets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_datasets.py b/test/test_datasets.py index cf144dc7074..39c8e18baf8 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -268,12 +268,12 @@ def test_ucf101(self): video, audio, label = dataset[0] self.assertEqual(video.size(), (10, 320, 240, 3)) - self.assertEqual(audio.size(), (1, 0)) + self.assertEqual(audio.numel(), 0) self.assertEqual(label, 0) video, audio, label = dataset[len(dataset) - 1] self.assertEqual(video.size(), (10, 320, 240, 3)) - self.assertEqual(audio.size(), (1, 0)) + self.assertEqual(audio.numel(), 0) self.assertEqual(label, 1) From 8467b2dfdc67e3c6c3fef0a97acd5ac65ac54baf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Andr=C3=A9s=20Margffoy=20Tuay?= Date: Mon, 3 Aug 2020 21:15:20 -0500 Subject: [PATCH 11/11] Iterate over folds and splits --- test/test_datasets.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/test/test_datasets.py b/test/test_datasets.py index 39c8e18baf8..6a0dee4c4c8 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -263,18 +263,22 @@ def test_voc_parse_xml(self, mock_download_extract): @unittest.skipIf(not HAS_PYAV, "PyAV unavailable") def test_ucf101(self): with ucf101_root() as (root, ann_root): - dataset = torchvision.datasets.UCF101(root, ann_root, 10) - self.assertGreater(len(dataset), 0) - - video, audio, label = dataset[0] - self.assertEqual(video.size(), (10, 320, 240, 3)) - self.assertEqual(audio.numel(), 0) - self.assertEqual(label, 0) - - video, audio, label = dataset[len(dataset) - 1] - self.assertEqual(video.size(), (10, 320, 240, 3)) - self.assertEqual(audio.numel(), 0) - self.assertEqual(label, 1) + for split in {True, False}: + for fold in range(1, 4): + for length in {10, 15, 20}: + dataset = torchvision.datasets.UCF101( + root, ann_root, length, fold=fold, train=split) + self.assertGreater(len(dataset), 0) + + video, audio, label = dataset[0] + self.assertEqual(video.size(), (length, 320, 240, 3)) + self.assertEqual(audio.numel(), 0) + self.assertEqual(label, 0) + + video, audio, label = dataset[len(dataset) - 1] + self.assertEqual(video.size(), (length, 320, 240, 3)) + self.assertEqual(audio.numel(), 0) + self.assertEqual(label, 1) if __name__ == '__main__':