-
Notifications
You must be signed in to change notification settings - Fork 7.1k
[WIP] UCF101 prototype with utilities for video loading #4838
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 6 commits
9c9b27e
e00c095
914380f
9dd6786
7ad8357
dc205e9
711adf3
56c1779
65f3c64
017e9b9
666ca6e
acc0e54
c209153
31c0eb7
f5eb8fd
0a66ff0
d29d22b
cf4f354
52b2b67
5e2f15d
b608f6d
4f281c4
ab6a2b8
9800f8e
64b644f
7557931
18eb9c0
587723e
a3737ab
8fce5ff
a10a3a0
697fdfd
ebef4f2
62078b6
a574089
d809cb9
8f57ee6
8f21f0e
8dbda84
788d82a
31a8929
84cdecb
4386c48
97bd457
4609783
1c77e6f
6019ce7
25c3668
08a616c
0675649
381f70e
f1a69e0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
from torchvision.prototype import datasets | ||
from torchvision.prototype.datasets.video_utils import AVKeyframeReader, AVRandomFrameReader, AVClipReader | ||
|
||
|
||
|
||
print("\n \n KEYFRAMES \n \n") | ||
ct = 0 | ||
dataset = AVKeyframeReader(datasets.load("ucf101")) | ||
for i in dataset: | ||
print(i) | ||
ct += 1 | ||
if ct > 5: | ||
break | ||
|
||
|
||
print("\n \n RANDOM FRAMES") | ||
ct = 0 | ||
dataset = AVRandomFrameReader(datasets.load("ucf101"), num_samples=3) | ||
for i in dataset: | ||
print(i) | ||
ct += 1 | ||
if ct > 5: | ||
break | ||
|
||
print("\n \n CLIPS ") | ||
ct = 0 | ||
dataset = AVClipReader(datasets.load("ucf101"), num_frames_per_clip=16, num_clips_per_video=8) | ||
for i in dataset: | ||
print(i['path'], i["range"]) | ||
ct += 1 | ||
if ct > 5: | ||
break |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import io | ||
from pathlib import Path | ||
from typing import Any, Callable, Dict, List, Optional, Tuple | ||
|
||
from torchvision.prototype.datasets.utils._internal import RarArchiveReader, INFINITE_BUFFER_SIZE | ||
|
||
import numpy as np | ||
import torch | ||
from torchdata.datapipes.iter import CSVParser, KeyZipper | ||
from torch.utils.data import IterDataPipe | ||
from torch.utils.data.datapipes.iter import ( | ||
Filter, | ||
Mapper, | ||
ZipArchiveReader, | ||
Shuffler, | ||
) | ||
from torchvision.prototype.datasets.decoder import raw | ||
from torchvision.prototype.datasets.utils import ( | ||
Dataset, | ||
DatasetConfig, | ||
DatasetInfo, | ||
HttpResource, | ||
OnlineResource, | ||
DatasetType, | ||
) | ||
|
||
|
||
class ucf101(Dataset): | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"""This is a base datapipe that returns a file handler of the video. | ||
What we want to do is implement either several decoder options or additional | ||
datapipe extensions to make this work. | ||
""" | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@property | ||
def info(self) -> DatasetInfo: | ||
return DatasetInfo( | ||
"ucf101", | ||
type=DatasetType.VIDEO, | ||
valid_options={'split': ["train", "test"], 'fold': ["1", "2", "3"]}, | ||
# categories=HERE / "ucf101.categories", | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
homepage="https://www.crcv.ucf.edu/data/UCF101.php", | ||
) | ||
|
||
def resources(self, config: DatasetConfig) -> List[OnlineResource]: | ||
return [ | ||
HttpResource( | ||
"https://www.crcv.ucf.edu/data/UCF101/UCF101TrainTestSplits-RecognitionTask.zip", | ||
sha256="", | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
), | ||
HttpResource( | ||
"https://www.crcv.ucf.edu/data/UCF101/UCF101.rar", | ||
sha256="", | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
] | ||
|
||
def _collate_and_decode( | ||
self, | ||
data: Tuple[np.ndarray, int], | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*, | ||
decoder: Optional[Callable[[io.IOBase], Dict[str, Any]]], | ||
) -> Dict[str, Any]: | ||
annotations_d, file_d = data | ||
|
||
label = annotations_d[1] | ||
_path, file_handle = file_d | ||
return {"path": _path, "file": file_handle, "target": label} | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def _filtername(self, data, *, tgt): | ||
return Path(data[0]).name == tgt | ||
|
||
def _getname(self, data): | ||
return Path(data[0]).name | ||
|
||
def _make_datapipe( | ||
self, | ||
resource_dps: List[IterDataPipe], | ||
*, | ||
config: DatasetConfig, | ||
decoder: Optional[Callable[[io.IOBase], torch.Tensor]], | ||
) -> IterDataPipe[Dict[str, Any]]: | ||
|
||
annotations = resource_dps[0] | ||
files = resource_dps[1] | ||
|
||
annotations_dp = ZipArchiveReader(annotations) | ||
annotations_dp = Filter(annotations_dp, | ||
self._filtername, | ||
fn_kwargs=dict(tgt=f"{config.split}list0{config.fold}.txt")) | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
annotations_dp = CSVParser(annotations_dp, delimiter=" ") | ||
# COMMENT OUT FOR TESTING | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, but should be removed before merge. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would really want our datasets to be deterministic outside of a DataLoader though. Making it stochastic will make it much harder to debug. Maybe what we should do instead is have a new Thoughts? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
annotations_dp = Shuffler(annotations_dp, buffer_size=INFINITE_BUFFER_SIZE) | ||
|
||
files_dp = RarArchiveReader(files) | ||
dp = KeyZipper(annotations_dp, files_dp, self._getname, self._getname) | ||
bjuncek marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return Mapper(dp, self._collate_and_decode, fn_kwargs=dict(decoder=decoder)) |
Uh oh!
There was an error while loading. Please reload this page.