import json import os import sys import warnings from subprocess import call import torch from torch.utils.data import default_collate from torchvision.datasets import (CIFAR10, CIFAR100, DTD, GTSRB, MNIST, PCAM, STL10, SUN397, CocoCaptions, Country211, EuroSAT, FGVCAircraft, Flowers102, Food101, ImageFolder, ImageNet, OxfordIIITPet, RenderedSST2, StanfordCars) from . import (audiocaps, babel_imagenet, caltech101, clotho_v2, flickr, imagenetv2, objectnet, pos_neg_caption_dataset, video_classification_dataset, video_retrieval_dataset, voc2007, winoground) MSRVTT_ANN = "PATH_TO/MSRVTT_JSFUSION_test.csv" MSRVTT_DATA = "PATH_TO/msrvtt/videos/all/" PVD_ANN = "PATH_TO/imago/annotations/imago15k.csv" PVD_DATA = "PATH_TO/imago/videos/" MSVD_ANN = "PATH_TO/msvd/msvd_test_multi.csv" MSVD_DATA = "PATH_TO/msvd/video/YouTubeClips/" DIDEMO_ANN = "PATH_TO/didemo/didemo_test.csv" DIDEMO_DATA = "PATH_TO/didemo/all_videos/videos/" ANET_ANN = "PATH_TO/anet/anet_test_valid.csv" ANET_DATA = "PATH_TO/anet/videos/" K400_ROOT = "PATH_TO/video_datasets/k400" K600_ROOT = "PATH_TO/video_datasets/k600" K700_ROOT = "PATH_TO/video_datasets/k700" UCF_ROOT = "PATH_TO/ucf/videos" UCF_PROMPT = "PATH_TO/ucf/custom_labels.txt" HMDB_ROOT = "PATH_TO/hmdb/112018/data" HMDB_PROMPT = "PATH_TO/hmdb/hmdb.txt" MITV1_ROOT = "PATH_TO/Multi-Moments/Multi_Moments_in_Time/videos" SSV2_ROOT = "PATH_TO/SSv2/videos/val_processed/" def build_dataset( dataset_name, root="root", transform=None, split="test", download=True, annotation_file=None, language="en", task="zeroshot_classification", wds_cache_dir=None, custom_classname_file=None, custom_template_file=None, num_frames=8, **kwargs, ): """ Main function to use in order to build a dataset instance, dataset_name: str name of the dataset root: str root folder where the dataset is downloaded and stored. can be shared among datasets. transform: torchvision transform applied to images split: str split to use, depending on the dataset can have different options. In general, `train` and `test` are available. For specific splits, please look at the corresponding dataset. annotation_file: str or None only for datasets with captions (used for retrieval) such as COCO and Flickr. custom_classname_file: str or None Custom classname file where keys are dataset names and values are list of classnames. custom_template_file: str or None Custom template file where keys are dataset names and values are list of prompts, or dicts where keys are classnames and values are class-specific prompts. """ use_classnames_and_templates = task in ("zeroshot_classification", "linear_probe") if use_classnames_and_templates: # Only load templates and classnames if we have to current_folder = os.path.dirname(__file__) # Load _classnames.json (packaged with CLIP benchmark that are used by default) default_classname_file = os.path.join( current_folder, language + "_classnames.json" ) if os.path.exists(default_classname_file): with open(default_classname_file, "r") as f: default_classnames = json.load(f) else: default_classnames = None # Load _zeroshot_classification_templates.json (packaged with CLIP benchmark that are used by default) default_template_file = os.path.join( current_folder, language + "_zeroshot_classification_templates.json" ) if os.path.exists(default_template_file): with open(default_template_file, "r") as f: default_templates = json.load(f) else: default_templates = None # Load custom classnames file if --custom_classname_file is specified if custom_classname_file: if not os.path.exists(custom_classname_file): custom_classname_file = os.path.join( current_folder, custom_classname_file ) assert os.path.exists( custom_classname_file ), f"Custom classname file '{custom_classname_file}' does not exist" with open(custom_classname_file, "r") as f: custom_classnames = json.load(f) else: custom_classnames = None # Load custom template file if --custom_template_file is specified if custom_template_file: if not os.path.exists(custom_template_file): # look at current_folder custom_template_file = os.path.join( current_folder, custom_template_file ) assert os.path.exists( custom_template_file ), f"Custom template file '{custom_template_file}' does not exist" with open(custom_template_file, "r") as f: custom_templates = json.load(f) else: custom_templates = None def download_imagenet(r): os.makedirs(r, exist_ok=True) call( f"wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_devkit_t12.tar.gz --output-document={r}/ILSVRC2012_devkit_t12.tar.gz", shell=True, ) call( f"wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_img_val.tar --output-document={r}/ILSVRC2012_img_val.tar", shell=True, ) train = split == "train" if dataset_name in video_classification_datasets.keys(): task_config = video_classification_datasets[dataset_name] ds = video_classification_dataset.VideoClassificationDataset( "", task_config, transform, num_frames=num_frames ) elif dataset_name == "clotho-v2": ds = clotho_v2.ClothoV2(transform) elif dataset_name == "audiocaps-audio-text": ds = audiocaps.AudiocapsAudioText(transform, root=root) elif dataset_name == "audiocaps-video-text": ds = audiocaps.AudiocapsVideoText(transform, root=root) elif dataset_name == "audiocaps-audio-video": ds = audiocaps.AudiocapsAudioVideo(transform, root=root) elif dataset_name == "msrvtt": ds = video_retrieval_dataset.VideoRetrievalDataset( MSRVTT_ANN, MSRVTT_DATA, transform, num_frames=num_frames, ) elif dataset_name == "imago_video": ds = video_retrieval_dataset.VideoRetrievalDataset( PVD_ANN, PVD_DATA, transform, num_frames=num_frames, ) elif dataset_name == "msvd": ds = video_retrieval_dataset.VideoRetrievalDataset( MSVD_ANN, MSVD_DATA, transform, num_frames=num_frames, video_ext="avi", multi_sent=True, ) elif dataset_name == "didemo": ds = video_retrieval_dataset.VideoRetrievalDataset( DIDEMO_ANN, DIDEMO_DATA, transform, num_frames=num_frames, ) elif dataset_name == "anet": ds = video_retrieval_dataset.VideoRetrievalDataset( ANET_ANN, ANET_DATA, transform, num_frames=32, ) elif dataset_name == "cifar10": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = CIFAR10( root=root, train=train, transform=transform, download=download, **kwargs ) elif dataset_name == "cifar100": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = CIFAR100( root=root, train=train, transform=transform, download=download, **kwargs ) elif dataset_name == "imagenet1k": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" if not os.path.exists(root): download_imagenet(root) ds = ImageNet( root=root, split="train" if train else "val", transform=transform, **kwargs ) ds.classes = default_classnames["imagenet1k"] elif dataset_name == "imagenet-w": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" from imagenet_w import AddWatermark from torchvision.transforms import CenterCrop, Normalize if not os.path.exists(root): download_imagenet(root) index_normalize = None crop_size = None for i, t in enumerate(transform.transforms): if isinstance(t, Normalize): index_normalize = i elif isinstance(t, CenterCrop): crop_size = min(t.size) assert crop_size is not None, "CenterCrop not found in transform" assert index_normalize is not None, "Normalize not found in transform" transform.transforms.insert(index_normalize, AddWatermark(crop_size)) ds = ImageNet( root=root, split="train" if train else "val", transform=transform, **kwargs ) ds.classes = custom_classnames["imagenet1k"] elif dataset_name == "babel_imagenet": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" # babel ImageNet from https://github.com/gregor-ge/Babel-ImageNet if not os.path.exists(root): download_imagenet(root) classnames = json.load( open(os.path.join(current_folder, "babel_imagenet.json")) ) assert ( language.upper() in classnames ), f"Language '{language}' not supported for Babel-ImageNet" classnames = classnames[language.upper()] templates = json.load( open(os.path.join(current_folder, "nllb_dist13b_prompts.json")) ) templates = templates[language.upper()] templates = [t.replace("{}", "{c}") for t in templates] idxs, classnames = classnames ds = babel_imagenet.BabelImageNet( root=root, idxs=idxs, split="train" if train else "val", transform=transform, **kwargs, ) ds.classes = classnames ds.templates = templates elif dataset_name == "imagenet1k-unverified": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" split = "train" if train else "val" ds = ImageFolder(root=os.path.join(root, split), transform=transform, **kwargs) # use classnames from OpenAI ds.classes = default_classnames["imagenet1k"] elif dataset_name == "imagenetv2": assert split == "test", f"Only `test` split available for {dataset_name}" os.makedirs(root, exist_ok=True) ds = imagenetv2.ImageNetV2Dataset( variant="matched-frequency", transform=transform, location=root ) ds.classes = default_classnames["imagenet1k"] elif dataset_name == "imagenet_sketch": assert split == "test", f"Only `test` split available for {dataset_name}" # Downloadable from https://drive.google.com/open?id=1Mj0i5HBthqH1p_yeXzsg22gZduvgoNeA if not os.path.exists(root): # Automatic download print("Downloading imagenet_sketch...") if not has_gdown(): print( "GDown is needed to download the dataset. Please install it via `pip install gdown`" ) sys.exit(1) # Download ImageNet-Sketch.zip call("gdown --id 1Mj0i5HBthqH1p_yeXzsg22gZduvgoNeA", shell=True) assert os.path.exists("ImageNet-Sketch.zip") # Unzip and move to `root` call("unzip ImageNet-Sketch.zip", shell=True) call(f"mv sketch {root}", shell=True) ds = ImageFolder(root=root, transform=transform, **kwargs) ds.classes = default_classnames["imagenet1k"] elif dataset_name == "imagenet-a": assert split == "test", f"Only `test` split available for {dataset_name}" # Downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-a.tar if not os.path.exists(root): print("Downloading imagenet-a...") call( "wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-a.tar", shell=True, ) # Untar and move to `root` call("tar xvf imagenet-a.tar", shell=True) call(f"mv imagenet-a {root}", shell=True) ds = ImageFolder(root=root, transform=transform, **kwargs) ds.classes = default_classnames["imagenet1k"] imagenet_a_wnids = [ "n01498041", "n01531178", "n01534433", "n01558993", "n01580077", "n01614925", "n01616318", "n01631663", "n01641577", "n01669191", "n01677366", "n01687978", "n01694178", "n01698640", "n01735189", "n01770081", "n01770393", "n01774750", "n01784675", "n01819313", "n01820546", "n01833805", "n01843383", "n01847000", "n01855672", "n01882714", "n01910747", "n01914609", "n01924916", "n01944390", "n01985128", "n01986214", "n02007558", "n02009912", "n02037110", "n02051845", "n02077923", "n02085620", "n02099601", "n02106550", "n02106662", "n02110958", "n02119022", "n02123394", "n02127052", "n02129165", "n02133161", "n02137549", "n02165456", "n02174001", "n02177972", "n02190166", "n02206856", "n02219486", "n02226429", "n02231487", "n02233338", "n02236044", "n02259212", "n02268443", "n02279972", "n02280649", "n02281787", "n02317335", "n02325366", "n02346627", "n02356798", "n02361337", "n02410509", "n02445715", "n02454379", "n02486410", "n02492035", "n02504458", "n02655020", "n02669723", "n02672831", "n02676566", "n02690373", "n02701002", "n02730930", "n02777292", "n02782093", "n02787622", "n02793495", "n02797295", "n02802426", "n02814860", "n02815834", "n02837789", "n02879718", "n02883205", "n02895154", "n02906734", "n02948072", "n02951358", "n02980441", "n02992211", "n02999410", "n03014705", "n03026506", "n03124043", "n03125729", "n03187595", "n03196217", "n03223299", "n03250847", "n03255030", "n03291819", "n03325584", "n03355925", "n03384352", "n03388043", "n03417042", "n03443371", "n03444034", "n03445924", "n03452741", "n03483316", "n03584829", "n03590841", "n03594945", "n03617480", "n03666591", "n03670208", "n03717622", "n03720891", "n03721384", "n03724870", "n03775071", "n03788195", "n03804744", "n03837869", "n03840681", "n03854065", "n03888257", "n03891332", "n03935335", "n03982430", "n04019541", "n04033901", "n04039381", "n04067472", "n04086273", "n04099969", "n04118538", "n04131690", "n04133789", "n04141076", "n04146614", "n04147183", "n04179913", "n04208210", "n04235860", "n04252077", "n04252225", "n04254120", "n04270147", "n04275548", "n04310018", "n04317175", "n04344873", "n04347754", "n04355338", "n04366367", "n04376876", "n04389033", "n04399382", "n04442312", "n04456115", "n04482393", "n04507155", "n04509417", "n04532670", "n04540053", "n04554684", "n04562935", "n04591713", "n04606251", "n07583066", "n07695742", "n07697313", "n07697537", "n07714990", "n07718472", "n07720875", "n07734744", "n07749582", "n07753592", "n07760859", "n07768694", "n07831146", "n09229709", "n09246464", "n09472597", "n09835506", "n11879895", "n12057211", "n12144580", "n12267677", ] imagenet_a_mask = [ wnid in set(imagenet_a_wnids) for wnid in all_imagenet_wordnet_ids ] ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_a_mask) if mask] elif dataset_name == "imagenet-r": assert split == "test", f"Only `test` split available for {dataset_name}" # downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-r.tar if not os.path.exists(root): print("Downloading imagenet-r...") call( "wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-r.tar", shell=True, ) # Untar and move to `root` call("tar xvf imagenet-r.tar", shell=True) call(f"mv imagenet-r {root}", shell=True) imagenet_r_wnids = { "n01443537", "n01484850", "n01494475", "n01498041", "n01514859", "n01518878", "n01531178", "n01534433", "n01614925", "n01616318", "n01630670", "n01632777", "n01644373", "n01677366", "n01694178", "n01748264", "n01770393", "n01774750", "n01784675", "n01806143", "n01820546", "n01833805", "n01843383", "n01847000", "n01855672", "n01860187", "n01882714", "n01910747", "n01944390", "n01983481", "n01986214", "n02007558", "n02009912", "n02051845", "n02056570", "n02066245", "n02071294", "n02077923", "n02085620", "n02086240", "n02088094", "n02088238", "n02088364", "n02088466", "n02091032", "n02091134", "n02092339", "n02094433", "n02096585", "n02097298", "n02098286", "n02099601", "n02099712", "n02102318", "n02106030", "n02106166", "n02106550", "n02106662", "n02108089", "n02108915", "n02109525", "n02110185", "n02110341", "n02110958", "n02112018", "n02112137", "n02113023", "n02113624", "n02113799", "n02114367", "n02117135", "n02119022", "n02123045", "n02128385", "n02128757", "n02129165", "n02129604", "n02130308", "n02134084", "n02138441", "n02165456", "n02190166", "n02206856", "n02219486", "n02226429", "n02233338", "n02236044", "n02268443", "n02279972", "n02317335", "n02325366", "n02346627", "n02356798", "n02363005", "n02364673", "n02391049", "n02395406", "n02398521", "n02410509", "n02423022", "n02437616", "n02445715", "n02447366", "n02480495", "n02480855", "n02481823", "n02483362", "n02486410", "n02510455", "n02526121", "n02607072", "n02655020", "n02672831", "n02701002", "n02749479", "n02769748", "n02793495", "n02797295", "n02802426", "n02808440", "n02814860", "n02823750", "n02841315", "n02843684", "n02883205", "n02906734", "n02909870", "n02939185", "n02948072", "n02950826", "n02951358", "n02966193", "n02980441", "n02992529", "n03124170", "n03272010", "n03345487", "n03372029", "n03424325", "n03452741", "n03467068", "n03481172", "n03494278", "n03495258", "n03498962", "n03594945", "n03602883", "n03630383", "n03649909", "n03676483", "n03710193", "n03773504", "n03775071", "n03888257", "n03930630", "n03947888", "n04086273", "n04118538", "n04133789", "n04141076", "n04146614", "n04147183", "n04192698", "n04254680", "n04266014", "n04275548", "n04310018", "n04325704", "n04347754", "n04389033", "n04409515", "n04465501", "n04487394", "n04522168", "n04536866", "n04552348", "n04591713", "n07614500", "n07693725", "n07695742", "n07697313", "n07697537", "n07714571", "n07714990", "n07718472", "n07720875", "n07734744", "n07742313", "n07745940", "n07749582", "n07753275", "n07753592", "n07768694", "n07873807", "n07880968", "n07920052", "n09472597", "n09835506", "n10565667", "n12267677", } imagenet_r_mask = [ wnid in imagenet_r_wnids for wnid in all_imagenet_wordnet_ids ] ds = ImageFolder(root=root, transform=transform, **kwargs) ds.classes = default_classnames["imagenet1k"] ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_r_mask) if mask] elif dataset_name == "imagenet-o": assert split == "test", f"Only `test` split available for {dataset_name}" # downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-o.tar if not os.path.exists(root): print("Downloading imagenet-o...") call( "wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-o.tar", shell=True, ) # Untar and move to `root` call("tar xvf imagenet-o.tar", shell=True) call(f"mv imagenet-o {root}", shell=True) ds = ImageFolder(root=root, transform=transform, **kwargs) ds.classes = default_classnames["imagenet1k"] imagenet_o_wnids = [ "n01443537", "n01704323", "n01770081", "n01784675", "n01819313", "n01820546", "n01910747", "n01917289", "n01968897", "n02074367", "n02317335", "n02319095", "n02395406", "n02454379", "n02606052", "n02655020", "n02666196", "n02672831", "n02730930", "n02777292", "n02783161", "n02786058", "n02787622", "n02791270", "n02808304", "n02817516", "n02841315", "n02865351", "n02877765", "n02892767", "n02906734", "n02910353", "n02916936", "n02948072", "n02965783", "n03000134", "n03000684", "n03017168", "n03026506", "n03032252", "n03075370", "n03109150", "n03126707", "n03134739", "n03160309", "n03196217", "n03207743", "n03218198", "n03223299", "n03240683", "n03271574", "n03291819", "n03297495", "n03314780", "n03325584", "n03344393", "n03347037", "n03372029", "n03376595", "n03388043", "n03388183", "n03400231", "n03445777", "n03457902", "n03467068", "n03482405", "n03483316", "n03494278", "n03530642", "n03544143", "n03584829", "n03590841", "n03598930", "n03602883", "n03649909", "n03661043", "n03666591", "n03676483", "n03692522", "n03706229", "n03717622", "n03720891", "n03721384", "n03724870", "n03729826", "n03733131", "n03733281", "n03742115", "n03786901", "n03788365", "n03794056", "n03804744", "n03814639", "n03814906", "n03825788", "n03840681", "n03843555", "n03854065", "n03857828", "n03868863", "n03874293", "n03884397", "n03891251", "n03908714", "n03920288", "n03929660", "n03930313", "n03937543", "n03942813", "n03944341", "n03961711", "n03970156", "n03982430", "n03991062", "n03995372", "n03998194", "n04005630", "n04023962", "n04033901", "n04040759", "n04067472", "n04074963", "n04116512", "n04118776", "n04125021", "n04127249", "n04131690", "n04141975", "n04153751", "n04154565", "n04201297", "n04204347", "n04209133", "n04209239", "n04228054", "n04235860", "n04243546", "n04252077", "n04254120", "n04258138", "n04265275", "n04270147", "n04275548", "n04330267", "n04332243", "n04336792", "n04347754", "n04371430", "n04371774", "n04372370", "n04376876", "n04409515", "n04417672", "n04418357", "n04423845", "n04429376", "n04435653", "n04442312", "n04482393", "n04501370", "n04507155", "n04525305", "n04542943", "n04554684", "n04557648", "n04562935", "n04579432", "n04591157", "n04597913", "n04599235", "n06785654", "n06874185", "n07615774", "n07693725", "n07695742", "n07697537", "n07711569", "n07714990", "n07715103", "n07716358", "n07717410", "n07718472", "n07720875", "n07742313", "n07745940", "n07747607", "n07749582", "n07753275", "n07753592", "n07754684", "n07768694", "n07836838", "n07871810", "n07873807", "n07880968", "n09229709", "n09472597", "n12144580", "n12267677", "n13052670", ] imagenet_o_mask = [ wnid in set(imagenet_o_wnids) for wnid in all_imagenet_wordnet_ids ] ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_o_mask) if mask] elif dataset_name == "objectnet": assert split == "test", f"Only `test` split available for {dataset_name}" # downloadable from https://objectnet.dev/downloads/objectnet-1.0.zip or https://www.dropbox.com/s/raw/cxeztdtm16nzvuw/objectnet-1.0.zip if not os.path.exists(root): print("Downloading objectnet...") call("wget https://objectnet.dev/downloads/objectnet-1.0.zip", shell=True) # Untar and move to `root` call( "UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE unzip -P objectnetisatestset objectnet-1.0.zip", shell=True, ) os.makedirs(root) call(f"mv objectnet-1.0 {root}", shell=True) call(f"cp {root}/objectnet-1.0/mappings/* {root}", shell=True) ds = objectnet.ObjectNetDataset(root=root, transform=transform) elif dataset_name == "voc2007": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = voc2007.PASCALVoc2007Cropped( root=root, set=split, transform=transform, download=download, **kwargs ) elif dataset_name == "voc2007_multilabel": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = voc2007.PASCALVoc2007( root=root, set=split, transform=transform, download=download, **kwargs ) elif dataset_name == "aro_visual_attribution": images_dir = os.path.join(root, "images") annotation_file = os.path.join(root, "annotations.json") ds = pos_neg_caption_dataset.PosNegCaptionDataset( root=images_dir, ann_file=annotation_file, transform=transform, crop_images=True, **kwargs, ) elif dataset_name.startswith("sugar_crepe"): # https://github.com/RAIVNLab/sugar-crepe/tree/main base_dir_name, task = dataset_name.split("/") assert task in ( "add_att", "add_obj", "replace_att", "replace_obj", "replace_rel", "swap_att", "swap_obj", ), f"Unknown task {task} for {dataset_name}" assert split == "test", f"Only `test` split available for {dataset_name}" dataset_dir = os.path.join(os.path.dirname(root.rstrip("/")), base_dir_name) images_dir = os.path.join(dataset_dir, "val2017") annotation_file = os.path.join(dataset_dir, f"{task}.json") ds = pos_neg_caption_dataset.PosNegCaptionDataset( root=images_dir, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "winoground": ds = winoground.WinoGround(root=root, transform=transform) elif dataset_name == "mscoco_captions": # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations) if split == "train": archive_name = "train2014.zip" elif split in ("val", "test"): archive_name = "val2014.zip" else: raise ValueError( f"split should be `train` or `val` or `test` for `{dataset_name}`" ) root_split = os.path.join(root, archive_name.replace(".zip", "")) if not os.path.exists(root_split): print(f"Downloading mscoco_captions {archive_name}...") if not os.path.exists(os.path.join(root, archive_name)): call( f"wget http://images.cocodataset.org/zips/{archive_name} --output-document={root}/{archive_name}", shell=True, ) call(f"unzip {root}/{archive_name} -d {root}", shell=True) if not annotation_file: annotation_file = f"{root}/coco_{split}_karpathy.json" if not os.path.exists(annotation_file): call( f"wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/coco_{split}_karpathy.json --output-document={annotation_file}", shell=True, ) ds = CocoCaptions( root=root_split, annFile=annotation_file, transform=transform, **kwargs ) elif dataset_name == "multilingual_mscoco_captions": from clip_benchmark.datasets import multilingual_mscoco if language not in multilingual_mscoco.SUPPORTED_LANGUAGES: raise ValueError("Unsupported language for multilingual_ms_coco:", language) annotation_file = os.path.join( root, multilingual_mscoco.OUTPUT_FILENAME_TEMPLATE.format(language) ) if not os.path.exists(annotation_file): multilingual_mscoco.create_annotation_file(root, language) ds = multilingual_mscoco.Multilingual_MSCOCO( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "crossmodal3600": from clip_benchmark.datasets import crossmodal3600 if language not in crossmodal3600.SUPPORTED_LANGUAGES: raise ValueError("Unsupported language for Crossmodal-3600:", language) annotation_file = os.path.join( root, crossmodal3600.OUTPUT_FILENAME_TEMPLATE.format(language) ) if not os.path.exists(annotation_file): crossmodal3600.create_annotation_file(root, language) ds = crossmodal3600.Crossmodal3600( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "xtd200": from clip_benchmark.datasets import xtd200 if language not in xtd200.SUPPORTED_LANGUAGES: raise ValueError("Unsupported language for xtd200:", language) annotation_file = os.path.join( root, xtd200.OUTPUT_FILENAME_TEMPLATE.format(language) ) if not os.path.exists(annotation_file): xtd200.create_annotation_file(root, language) ds = xtd200.XTD200( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "flickr30k-200": from clip_benchmark.datasets import flickr30k_200 if language not in flickr30k_200.SUPPORTED_LANGUAGES: raise ValueError("Unsupported language for flickr30k-200:", language) annotation_file = os.path.join( root, flickr30k_200.OUTPUT_FILENAME_TEMPLATE.format(language) ) if not os.path.exists(annotation_file): flickr30k_200.create_annotation_file(root, language) ds = flickr30k_200.Flickr30k_200( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "flickr30k": # downloadable from https://www.kaggle.com/datasets/adityajn105/flickr30k # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations) # `kaggle datasets download -d adityajn105/flickr30k` assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" if not os.path.exists(root): # Automatic download print("Downloading flickr30k...") if not has_kaggle(): print( "Kaggle is needed to download the dataset. Please install it via `pip install kaggle`" ) sys.exit(1) call( "kaggle datasets download -d hsankesara/flickr-image-dataset", shell=True, ) call(f"unzip flickr-image-dataset.zip", shell=True) call( f"mv flickr30k_images/flickr30k_images {root} && rm -rf flickr30k_images", shell=True, ) if not annotation_file: if language == "en": annotation_file = f"{root}/flickr30k_{split}_karpathy.txt" elif language == "zh": annotation_file = f"{root}/flickr30k_{split}_zh.txt" else: raise ValueError( f"Unsupported language {language} for `{dataset_name}`" ) if not os.path.exists(annotation_file): # Download Flickr30K Karpathy test set if language == "en": call( f"wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr30k_{split}_karpathy.txt --output-document={annotation_file}", shell=True, ) elif language == "zh": call( f"wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr30k_{split}_zh.txt --output-document={annotation_file}", shell=True, ) else: raise ValueError( f"Unsupported language {language} for `{dataset_name}`" ) ds = flickr.Flickr( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "flickr8k": assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" # downloadable from https://www.kaggle.com/datasets/adityajn105/flickr8k # `kaggle datasets download -d adityajn105/flickr8k` # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations) if not os.path.exists(root): # Automatic download print("Downloading flickr8k...") if not has_kaggle(): print( "Kaggle is needed to download the dataset. Please install it via `pip install kaggle`" ) sys.exit(1) call("kaggle datasets download -d adityajn105/flickr8k", shell=True) call(f"unzip flickr8k.zip", shell=True) call(f"mv Images {root}", shell=True) call(f"mv captions.txt {root}", shell=True) if not annotation_file: if language == "en": annotation_file = f"{root}/flickr8k_{split}_karpathy.txt" elif language == "zh": annotation_file = f"{root}/flickr8k_{split}_zh.txt" else: raise ValueError( f"Unsupported language {language} for `{dataset_name}`" ) if not os.path.exists(annotation_file): # Download Flickr8K Karpathy test set if language == "en": call( f"wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr8k_{split}_karpathy.txt --output-document={annotation_file}", shell=True, ) elif language == "zh": call( f"wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr8k_{split}_zh.txt --output-document={annotation_file}", shell=True, ) else: raise ValueError( f"Unsupported language {language} for `{dataset_name}`" ) ds = flickr.Flickr( root=root, ann_file=annotation_file, transform=transform, **kwargs ) elif dataset_name == "food101": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = Food101( root=root, split=split, transform=transform, download=download, **kwargs ) # we use the default class names, we just replace "_" by spaces # to delimit words ds.classes = [cl.replace("_", " ") for cl in ds.classes] elif dataset_name == "sun397": warnings.warn( f"split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset" ) # we use the default class names, we just replace "_" and "/" by spaces # to delimit words ds = SUN397(root=root, transform=transform, download=download, **kwargs) ds.classes = [cl.replace("_", " ").replace("/", " ") for cl in ds.classes] elif dataset_name == "cars": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = StanfordCars( root=root, split=split, transform=transform, download=download, **kwargs ) elif dataset_name == "fgvc_aircraft": assert split in ( "train", "val", "trainval", "test", ), f"Only `train` and `val` and `trainval` and `test` split available for {dataset_name}" ds = FGVCAircraft( root=root, annotation_level="variant", split=split, transform=transform, download=download, **kwargs, ) elif dataset_name == "dtd": assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" ds = DTD( root=root, split=split, transform=transform, download=download, **kwargs ) elif dataset_name == "pets": assert split in ( "trainval", "test", ), f"Only `trainval` and `test` split available for {dataset_name}" ds = OxfordIIITPet( root=root, split=split, target_types="category", transform=transform, download=download, **kwargs, ) elif dataset_name == "caltech101": warnings.warn( f"split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset" ) # broken download link (can't download google drive), fixed by this PR https://github.com/pytorch/vision/pull/5645 # also available in "vtab/caltech101" using VTAB splits, we advice to use VTAB version rather than this one # since in this one (torchvision) there are no pre-defined test splits ds = caltech101.Caltech101( root=root, target_type="category", transform=transform, download=download, **kwargs, ) ds.classes = default_classnames["caltech101"] elif dataset_name == "flowers": assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" ds = Flowers102( root=root, split=split, transform=transform, download=download, **kwargs ) # class indices started by 1 until it was fixed in a PR (#TODO link of the PR) # if older torchvision version, fix it using a target transform that decrements label index # TODO figure out minimal torchvision version needed instead of decrementing if ds[0][1] == 1: ds.target_transform = lambda y: y - 1 ds.classes = default_classnames["flowers"] elif dataset_name == "mnist": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = MNIST( root=root, train=train, transform=transform, download=download, **kwargs ) ds.classes = default_classnames["mnist"] elif dataset_name == "stl10": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = STL10( root=root, split=split, transform=transform, download=download, **kwargs ) elif dataset_name == "eurosat": warnings.warn( f"split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset" ) ds = EuroSAT(root=root, transform=transform, download=download, **kwargs) ds.classes = default_classnames["eurosat"] elif dataset_name == "gtsrb": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" ds = GTSRB( root=root, split=split, transform=transform, download=download, **kwargs ) ds.classes = default_classnames["gtsrb"] elif dataset_name == "country211": assert split in ( "train", "valid", "test", ), f"Only `train` and `valid` and `test` split available for {dataset_name}" ds = Country211( root=root, split=split, transform=transform, download=download, **kwargs ) ds.classes = default_classnames["country211"] elif dataset_name == "pcam": assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" # Dead link. Fixed by this PR on torchvision https://github.com/pytorch/vision/pull/5645 # TODO figure out minimal torchvision version needed ds = PCAM( root=root, split=split, transform=transform, download=download, **kwargs ) ds.classes = default_classnames["pcam"] elif dataset_name == "renderedsst2": assert split in ( "train", "val", "test", ), f"Only `train` and `val` and `test` split available for {dataset_name}" ds = RenderedSST2( root=root, split=split, transform=transform, download=download, **kwargs ) elif dataset_name == "fer2013": assert split in ( "train", "test", ), f"Only `train` and `test` split available for {dataset_name}" # Downloadable from https://www.kaggle.com/datasets/msambare/fer2013 # `kaggle datasets download -d msambare/fer2013` if not os.path.exists(root): # Automatic download print("Downloading fer2013...") if not has_kaggle(): print( "Kaggle is needed to download the dataset. Please install it via `pip install kaggle`" ) sys.exit(1) call("kaggle datasets download -d msambare/fer2013", shell=True) call(f"unzip fer2013.zip -d {root}", shell=True) root = os.path.join(root, "train" if train else "test") ds = ImageFolder(root=root, transform=transform) ds.classes = default_classnames["fer2013"] elif dataset_name.startswith("tfds/"): # TFDS datasets support using `timm` and `tensorflow_datasets` prefix, *name_list = dataset_name.split("/") name = "/".join(name_list) ds = build_tfds_dataset( name, download=download, split=split, data_dir=root, transform=transform ) elif dataset_name.startswith("vtab/"): # VTAB datasets support using `tensorflow_datasets` and `task_adaptation` prefix, *name_list = dataset_name.split("/") name = "/".join(name_list) ds = build_vtab_dataset( name, download=download, split=split, data_dir=root, transform=transform, classnames=default_classnames, ) elif dataset_name.startswith("wds/"): # WebDataset support using `webdataset` library name = dataset_name.split("/", 1)[1] ds = build_wds_dataset( name, transform=transform, split=split, data_dir=root, cache_dir=wds_cache_dir, ) # WDS specify classnames and templates on its own. elif dataset_name == "dummy": ds = Dummy() else: raise ValueError(f"Unsupported dataset: {dataset_name}.") default_dataset_for_templates = "imagenet1k" if ( dataset_name.startswith("tfds/") or dataset_name.startswith("vtab/") or dataset_name.startswith("wds/") ): prefix, *rest = dataset_name.split("/") short_name = "/".join(rest) # if it's a vtab/tfds/wds/ dataset, we look for e.g. vtab/ # as well as in the custom template file/classname file, # whichever is found. keys_to_lookup = [dataset_name, short_name] else: keys_to_lookup = [dataset_name] if use_classnames_and_templates: # Specify templates for the dataset (if needed) if custom_templates: # We override with custom templates ONLY if they are provided, # which is the case when `custom_templates` is loaded. ds.templates = value_from_first_key_found( custom_templates, keys=keys_to_lookup + [default_dataset_for_templates] ) assert ( ds.templates is not None ), f"Templates not specified for {dataset_name}" elif not hasattr(ds, "templates"): # No templates specified by the dataset itself, # so we use templates are packaged with CLIP benchmark # (loaded from _zeroshot_classification_templates.json). ds.templates = value_from_first_key_found( default_templates, keys=keys_to_lookup + [default_dataset_for_templates] ) assert ( ds.templates is not None ), f"Templates not specified for {dataset_name}" else: # dataset has templates already (e.g., WDS case), so we keep it as is. pass # We override with custom classnames ONLY if they are provided. if custom_classnames: ds.classes = value_from_first_key_found( custom_classnames, keys=keys_to_lookup ) assert ds.classes is not None, f"Classes not specified for {dataset_name}" assert ds.templates is not None, f"Templates not specified for {dataset_name}" return ds def value_from_first_key_found(dic, keys): for k in keys: if k in dic: return dic[k] class Dummy: def __init__(self): self.classes = ["blank image", "noisy image"] def __getitem__(self, i): return torch.zeros(3, 224, 224), 0 def __len__(self): return 1 def get_dataset_default_task(dataset): dataset = dataset.split("wds_")[-1] if dataset in ( "flickr30k", "flickr8k", "mscoco_captions", "multilingual_mscoco_captions", "flickr30k-200", "crossmodal3600", "xtd200", "flickr8k_ocr", "rendered_ocr", "flickr30k_ocr", "mscoco_ocr", "text_cap", "pug_spar", "msrvtt", "imago_video", "msvd", "didemo", "anet", "clotho-v2", "audiocaps-audio-text", "audiocaps-video-text", "audiocaps-audio-video", ): return "zeroshot_retrieval" elif dataset in ("pug_animals"): return "multiclass_retrieval" elif ( dataset.startswith("sugar_crepe") or dataset == "winoground" or dataset == "aro_visual_attribution" or dataset.startswith("pug_animals") ): return "image_caption_selection" else: return "zeroshot_classification" def is_video_dataset(dataset): if dataset in ( "k400_val", "k600_val", "k700_val", "ucf101_val", "hmdb_test", "mitv1_val", "ssv2_mc_val", "msrvtt", "imago_video", "msvd", "didemo", "anet", "audiocaps-video-text", "audiocaps-audio-video", ): return True else: return False def is_audio_dataset(dataset): return dataset in ( "clotho-v2", "audiocaps-audio-text", "audiocaps-audio-video", ) def get_dataset_collate_fn(dataset_name): dataset_name = dataset_name.split("wds_")[-1] if ( dataset_name in ( "mscoco_captions", "multilingual_mscoco_captions", "flickr30k", "flickr8k", "flickr30k-200", "crossmodal3600", "xtd200", "winoground", "rendered_ocr", "flickr30k_ocr", "flickr8k_ocr", "mscoco_ocr", "aro_visual_attribution", "text_cap", "pug_spar", "msrvtt", "imago_video", "msvd", "didemo", "anet", ) or dataset_name.startswith("sugar_crepe") or dataset_name.startswith("pug_animals") ): return image_captions_collate_fn else: return default_collate def has_gdown(): return call("which gdown", shell=True) == 0 def has_kaggle(): return call("which kaggle", shell=True) == 0 def build_vtab_dataset( dataset_name, transform, download=True, split="test", data_dir="root", classnames=[] ): # Using VTAB splits instead of default TFDS splits from .tfds import (VTABIterableDataset, disable_gpus_on_tensorflow, download_tfds_dataset) # avoid Tensorflow owning GPUs to not clash with PyTorch disable_gpus_on_tensorflow() # by default we take classes from TFDS (default behavior if `classes` stays None), # except for the datasets that will override `classes` (e.g., clevr_*) classes = None if dataset_name == "caltech101": from task_adaptation.data.caltech import Caltech101 tfds_dataset = Caltech101(data_dir=data_dir) classes = classnames["caltech101_vtab"] elif dataset_name == "cars": from task_adaptation.data.cars import CarsData tfds_dataset = CarsData(data_dir=data_dir) elif dataset_name in ("cifar10", "cifar100"): from task_adaptation.data.cifar import CifarData tfds_dataset = CifarData( data_dir=data_dir, num_classes=10 if dataset_name == "cifar10" else 100 ) elif dataset_name.startswith("clevr_"): from task_adaptation.data.clevr import CLEVRData task = _extract_task(dataset_name) assert task in ("count_all", "closest_object_distance") tfds_dataset = CLEVRData(task=task, data_dir=data_dir) if task == "count_all": classes = classnames["clevr_count_all"] elif task == "closest_object_distance": classes = classnames["clevr_closest_object_distance"] else: raise ValueError(f"non supported: {task}") elif dataset_name == "cub": from task_adaptation.data.cub import CUB2011Data tfds_dataset = CUB2011Data(data_dir=data_dir) elif dataset_name == "diabetic_retinopathy": # Needs manual download from Kaggle # 1) `kaggle competitions download -c diabetic-retinopathy-detection` on $ROOT/downloads/manual # 2) extract archives on $ROOT/downloads/manual if not os.path.exists(data_dir): # Automatic download print("Downloading diabetic_retinopathy...") if not has_kaggle(): print( "Kaggle is needed to download the dataset. Please install it via `pip install kaggle`" ) sys.exit(1) os.makedirs(os.path.join(data_dir, "downloads", "manual")) call( f"kaggle competitions download -c diabetic-retinopathy-detection -p {data_dir}/downloads/manual", shell=True, ) call( f"cd {data_dir}/downloads/manual;unzip diabetic-retinopathy-detection.zip;cat train.zip*>train.zip;cat test.zip*>test.zip;unzip train.zip; unzip test.zip;unzip sample.zip;unzip trainLabels.csv.zip", shell=True, ) from task_adaptation.data.diabetic_retinopathy import RetinopathyData tfds_dataset = RetinopathyData(config="btgraham-300", data_dir=data_dir) classes = classnames["diabetic_retinopathy"] elif dataset_name == "dmlab": from task_adaptation.data.dmlab import DmlabData download_tfds_dataset( "dmlab", data_dir=data_dir ) # it's not called in the original VTAB code, so we do it explictly tfds_dataset = DmlabData(data_dir=data_dir) classes = classnames["dmlab"] elif dataset_name.startswith("dsprites_"): from task_adaptation.data.dsprites import DSpritesData task = _extract_task(dataset_name) assert task in ( "label_shape", "label_scale", "label_orientation", "label_x_position", "label_y_position", ) tfds_dataset = DSpritesData(task, data_dir=data_dir) classes = tfds_dataset._dataset_builder.info.features[task].names elif dataset_name == "dtd": from task_adaptation.data.dtd import DTDData tfds_dataset = DTDData(data_dir=data_dir) elif dataset_name == "eurosat": from task_adaptation.data.eurosat import EurosatData tfds_dataset = EurosatData(subset="rgb", data_key="image", data_dir=data_dir) classes = classnames["eurosat"] elif dataset_name == "food101": from task_adaptation.data.food101 import Food101Data tfds_dataset = Food101Data(data_dir=data_dir) elif dataset_name == "inaturalist": from task_adaptation.data.inaturalist import INaturalistData tfds_dataset = INaturalistData(data_dir=data_dir, year=2017) elif dataset_name.startswith("kitti_"): from .kitti import KittiData task = _extract_task(dataset_name) assert task in ( "count_all", "count_left", "count_far", "count_near", "closest_object_distance", "closest_object_x_location", "count_vehicles", "closest_vehicle_distance", ) tfds_dataset = KittiData(task=task, data_dir=data_dir) if task == "closest_vehicle_distance": classes = classnames["kitti_closest_vehicle_distance"] else: raise ValueError(f"Unsupported task: {task}") elif dataset_name == "flowers": from task_adaptation.data.oxford_flowers102 import OxfordFlowers102Data tfds_dataset = OxfordFlowers102Data(data_dir=data_dir) elif dataset_name == "pets": from task_adaptation.data.oxford_iiit_pet import OxfordIIITPetData tfds_dataset = OxfordIIITPetData(data_dir=data_dir) classes = classnames["pets"] elif dataset_name == "pcam": from task_adaptation.data.patch_camelyon import PatchCamelyonData tfds_dataset = PatchCamelyonData(data_dir=data_dir) classes = classnames["pcam"] elif dataset_name == "resisc45": # Needs download from OneDrive: https://1drv.ms/u/s!AmgKYzARBl5ca3HNaHIlzp_IXjs # The archive needs to to be put at /downloads/manual then extracted if not os.path.exists(data_dir): os.makedirs(os.path.join(data_dir, "downloads", "manual")) call( f"wget 'https://onedrive.live.com/download?resid=5C5E061130630A68!107&authkey=!AHHNaHIlzp_IXjs' --output-document={data_dir}/downloads/manual/resisc45.rar", shell=True, ) call(f"cd {data_dir}/downloads/manual;unrar x resisc45.rar", shell=True) from task_adaptation.data.resisc45 import Resisc45Data tfds_dataset = Resisc45Data(data_dir=data_dir) elif dataset_name.startswith("smallnorb_"): from task_adaptation.data.smallnorb import SmallNORBData task = _extract_task(dataset_name) assert task in ( "label_category", "label_elevation", "label_azimuth", "label_lighting", ) tfds_dataset = SmallNORBData(predicted_attribute=task, data_dir=data_dir) classes = tfds_dataset._dataset_builder.info.features[task].names elif dataset_name == "sun397": from task_adaptation.data.sun397 import Sun397Data # FIXME There is a problem in `sun397`, when TFDS tries download it # there is an image that cannot be decoded. For the time being # we will use torchvision's SUN397 instead. tfds_dataset = Sun397Data(config="tfds", data_dir=data_dir) elif dataset_name == "svhn": from task_adaptation.data.svhn import SvhnData tfds_dataset = SvhnData(data_dir=data_dir) classes = classnames["svhn"] else: raise ValueError(f"Unsupported dataset: {dataset_name}") ds = VTABIterableDataset( tfds_dataset, input_name="image", label_name="label", transform=transform, target_transform=int, split=split, classes=classes, ) return ds def build_tfds_dataset( name, transform, download=True, split="test", data_dir="root", classes=None ): from .tfds import disable_gpus_on_tensorflow disable_gpus_on_tensorflow() import tensorflow_datasets as tfds import timm builder = tfds.builder(name, data_dir=data_dir) if download: builder.download_and_prepare() splits = list(builder.info.splits.keys()) assert split in splits, (split, splits) ds = timm.data.create_dataset( f"tfds/{name}", data_dir, split=split, transform=transform, target_transform=int ) ds.classes = builder.info.features["label"].names if classes is None else classes return ds def build_wds_dataset( dataset_name, transform, split="test", data_dir="root", cache_dir=None ): """ Load a dataset in WebDataset format. Either local paths or HTTP URLs can be specified. Expected file structure is: ``` data_dir/ train/ nshards.txt 0.tar 1.tar ... test/ nshards.txt 0.tar 1.tar ... classnames.txt zeroshot_classification_templates.txt dataset_type.txt ``` Classnames and templates are required for zeroshot classification, while dataset type (equal to "retrieval") is required for zeroshot retrieval datasets. You can use the `clip_benchmark_export_wds` or corresponding API (`clip_benchmark.webdataset_builder.convert_dataset`) to convert datasets to this format. Set `cache_dir` to a path to cache the dataset, otherwise, no caching will occur. """ import webdataset as wds def read_txt(fname): if "://" in fname: stream = os.popen("curl -L -s --fail '%s'" % fname, "r") value = stream.read() if stream.close(): raise FileNotFoundError("Failed to retreive data") else: with open(fname, "r") as file: value = file.read() return value # Special handling for Huggingface datasets # Git LFS files have a different file path to access the raw data than other files if data_dir.startswith("https://huggingface.co/datasets"): # Format: https://huggingface.co/datasets///tree/ *split_url_head, _, url_path = data_dir.split("/", 7) url_head = "/".join(split_url_head) metadata_dir = "/".join([url_head, "raw", url_path]) tardata_dir = "/".join([url_head, "resolve", url_path]) else: metadata_dir = tardata_dir = data_dir # Get number of shards nshards_fname = os.path.join(metadata_dir, split, "nshards.txt") nshards = int( read_txt(nshards_fname) ) # Do not catch FileNotFound, nshards.txt should be mandatory # Get dataset type (classification or retrieval) type_fname = os.path.join(metadata_dir, "dataset_type.txt") try: dataset_type = read_txt(type_fname).strip().lower() except FileNotFoundError: # print("WARNING: dataset_type.txt not found, assuming type=classification") dataset_type = "classification" # filepattern = os.path.join(tardata_dir, split, "{0..%d}.tar" % (nshards - 1)) # Load webdataset (support WEBP, PNG, and JPG for now) if not cache_dir or not isinstance(cache_dir, str): cache_dir = None dataset = wds.WebDataset( filepattern, cache_dir=cache_dir, nodesplitter=lambda src: src ).decode( wds.autodecode.ImageHandler("pil", extensions=["webp", "png", "jpg", "jpeg"]) ) # Load based on classification or retrieval task if dataset_type == "retrieval": dataset = dataset.to_tuple(["webp", "png", "jpg", "jpeg"], "txt").map_tuple( transform, str.splitlines ) dataset.classes = dataset.templates = None elif dataset_type == "multiclass-retrieval": dataset = dataset.to_tuple(["webp", "png", "jpg", "jpeg"], "txt").map_tuple( transform, str.splitlines ) dataset.retrieval_template = json.load( open(os.path.join(metadata_dir, "retrieval_template.json")) ) else: label_type = ( "npy" if dataset_type == "multilabel" else "cls" ) # Special case for multilabel dataset = dataset.to_tuple( ["webp", "png", "jpg", "jpeg"], label_type ).map_tuple(transform, None) # Get class names if present classnames_fname = os.path.join(metadata_dir, "classnames.txt") try: dataset.classes = [ line.strip() for line in read_txt(classnames_fname).splitlines() ] except FileNotFoundError: print("WARNING: classnames.txt not found") dataset.classes = None # Get zeroshot classification templates if present templates_fname = os.path.join( metadata_dir, "zeroshot_classification_templates.txt" ) try: dataset.templates = [ line.strip() for line in read_txt(templates_fname).splitlines() ] except FileNotFoundError: print("WARNING: zeroshot_classification_templates.txt not found") dataset.templates = None return dataset def _extract_task(dataset_name): prefix, *task_name_list = dataset_name.split("_") task = "_".join(task_name_list) return task def image_captions_collate_fn(batch): transposed = list(zip(*batch)) imgs = default_collate(transposed[0]) texts = transposed[1] return imgs, texts def get_dataset_collection_from_file(path): datasets = [] for line in open(path).readlines(): line = line.strip() if line != "" and not line.startswith("#"): datasets.append(line) print(f"Found {len(datasets)} datasets in {path}:") print(datasets) return datasets dataset_collection = { "vtab": [ "vtab/caltech101", "vtab/cifar100", "vtab/clevr_count_all", "vtab/clevr_closest_object_distance", "vtab/diabetic_retinopathy", "vtab/dmlab", "vtab/dsprites_label_orientation", "vtab/dsprites_label_x_position", "vtab/dtd", "vtab/eurosat", "vtab/kitti_closest_vehicle_distance", "vtab/flowers", "vtab/pets", "vtab/pcam", "vtab/resisc45", "vtab/smallnorb_label_azimuth", "vtab/smallnorb_label_elevation", "sun397", "vtab/svhn", ], "vtab+": [ "imagenet1k", "imagenetv2", "imagenet_sketch", "imagenet-a", "imagenet-r", "objectnet", "fer2013", "voc2007", "voc2007_multilabel", "sun397", "cars", "fgvc_aircraft", "mnist", "stl10", "gtsrb", "country211", "renderedsst2", "vtab/caltech101", "vtab/cifar10", "vtab/cifar100", "vtab/clevr_count_all", "vtab/clevr_closest_object_distance", "vtab/diabetic_retinopathy", "vtab/dmlab", "vtab/dsprites_label_orientation", "vtab/dsprites_label_x_position", "vtab/dtd", "vtab/eurosat", "vtab/kitti_closest_vehicle_distance", "vtab/flowers", "vtab/pets", "vtab/pcam", "vtab/resisc45", "vtab/smallnorb_label_azimuth", "vtab/smallnorb_label_elevation", "vtab/svhn", ], "retrieval": [ "mscoco_captions", "flickr8k", "flickr30k", ], "imagenet_robustness": [ "imagenetv2", "imagenet_sketch", "imagenet-a", "imagenet-r", "objectnet", ], "sugar_crepe": [ "sugar_crepe/add_att", "sugar_crepe/add_obj", "sugar_crepe/replace_att", "sugar_crepe/replace_obj", "sugar_crepe/replace_rel", "sugar_crepe/swap_att", "sugar_crepe/swap_obj", ], } video_classification_datasets = { "k400_val": { "media": K400_ROOT, "labels": None, "media_type": "video", "templates": None, }, "k600_val": { "media": K600_ROOT, "labels": None, "media_type": "video", "templates": None, }, "k700_val": { "media": K700_ROOT, "labels": None, "media_type": "video", "templates": None, }, "ucf101_val": { "media": UCF_ROOT, "labels": UCF_PROMPT, "media_type": "video", "templates": None, }, "hmdb_test": { "media": HMDB_ROOT, "labels": HMDB_PROMPT, "media_type": "video", "templates": None, }, "mitv1_val": { "media": MITV1_ROOT, "labels": None, "media_type": "video", "templates": None, }, "ssv2_mc_val": { "media": SSV2_ROOT, "labels": None, "media_type": "video", "templates": None, }, } # use by imagenet robustness datasets all_imagenet_wordnet_ids = [ "n01440764", "n01443537", "n01484850", "n01491361", "n01494475", "n01496331", "n01498041", "n01514668", "n01514859", "n01518878", "n01530575", "n01531178", "n01532829", "n01534433", "n01537544", "n01558993", "n01560419", "n01580077", "n01582220", "n01592084", "n01601694", "n01608432", "n01614925", "n01616318", "n01622779", "n01629819", "n01630670", "n01631663", "n01632458", "n01632777", "n01641577", "n01644373", "n01644900", "n01664065", "n01665541", "n01667114", "n01667778", "n01669191", "n01675722", "n01677366", "n01682714", "n01685808", "n01687978", "n01688243", "n01689811", "n01692333", "n01693334", "n01694178", "n01695060", "n01697457", "n01698640", "n01704323", "n01728572", "n01728920", "n01729322", "n01729977", "n01734418", "n01735189", "n01737021", "n01739381", "n01740131", "n01742172", "n01744401", "n01748264", "n01749939", "n01751748", "n01753488", "n01755581", "n01756291", "n01768244", "n01770081", "n01770393", "n01773157", "n01773549", "n01773797", "n01774384", "n01774750", "n01775062", "n01776313", "n01784675", "n01795545", "n01796340", "n01797886", "n01798484", "n01806143", "n01806567", "n01807496", "n01817953", "n01818515", "n01819313", "n01820546", "n01824575", "n01828970", "n01829413", "n01833805", "n01843065", "n01843383", "n01847000", "n01855032", "n01855672", "n01860187", "n01871265", "n01872401", "n01873310", "n01877812", "n01882714", "n01883070", "n01910747", "n01914609", "n01917289", "n01924916", "n01930112", "n01943899", "n01944390", "n01945685", "n01950731", "n01955084", "n01968897", "n01978287", "n01978455", "n01980166", "n01981276", "n01983481", "n01984695", "n01985128", "n01986214", "n01990800", "n02002556", "n02002724", "n02006656", "n02007558", "n02009229", "n02009912", "n02011460", "n02012849", "n02013706", "n02017213", "n02018207", "n02018795", "n02025239", "n02027492", "n02028035", "n02033041", "n02037110", "n02051845", "n02056570", "n02058221", "n02066245", "n02071294", "n02074367", "n02077923", "n02085620", "n02085782", "n02085936", "n02086079", "n02086240", "n02086646", "n02086910", "n02087046", "n02087394", "n02088094", "n02088238", "n02088364", "n02088466", "n02088632", "n02089078", "n02089867", "n02089973", "n02090379", "n02090622", "n02090721", "n02091032", "n02091134", "n02091244", "n02091467", "n02091635", "n02091831", "n02092002", "n02092339", "n02093256", "n02093428", "n02093647", "n02093754", "n02093859", "n02093991", "n02094114", "n02094258", "n02094433", "n02095314", "n02095570", "n02095889", "n02096051", "n02096177", "n02096294", "n02096437", "n02096585", "n02097047", "n02097130", "n02097209", "n02097298", "n02097474", "n02097658", "n02098105", "n02098286", "n02098413", "n02099267", "n02099429", "n02099601", "n02099712", "n02099849", "n02100236", "n02100583", "n02100735", "n02100877", "n02101006", "n02101388", "n02101556", "n02102040", "n02102177", "n02102318", "n02102480", "n02102973", "n02104029", "n02104365", "n02105056", "n02105162", "n02105251", "n02105412", "n02105505", "n02105641", "n02105855", "n02106030", "n02106166", "n02106382", "n02106550", "n02106662", "n02107142", "n02107312", "n02107574", "n02107683", "n02107908", "n02108000", "n02108089", "n02108422", "n02108551", "n02108915", "n02109047", "n02109525", "n02109961", "n02110063", "n02110185", "n02110341", "n02110627", "n02110806", "n02110958", "n02111129", "n02111277", "n02111500", "n02111889", "n02112018", "n02112137", "n02112350", "n02112706", "n02113023", "n02113186", "n02113624", "n02113712", "n02113799", "n02113978", "n02114367", "n02114548", "n02114712", "n02114855", "n02115641", "n02115913", "n02116738", "n02117135", "n02119022", "n02119789", "n02120079", "n02120505", "n02123045", "n02123159", "n02123394", "n02123597", "n02124075", "n02125311", "n02127052", "n02128385", "n02128757", "n02128925", "n02129165", "n02129604", "n02130308", "n02132136", "n02133161", "n02134084", "n02134418", "n02137549", "n02138441", "n02165105", "n02165456", "n02167151", "n02168699", "n02169497", "n02172182", "n02174001", "n02177972", "n02190166", "n02206856", "n02219486", "n02226429", "n02229544", "n02231487", "n02233338", "n02236044", "n02256656", "n02259212", "n02264363", "n02268443", "n02268853", "n02276258", "n02277742", "n02279972", "n02280649", "n02281406", "n02281787", "n02317335", "n02319095", "n02321529", "n02325366", "n02326432", "n02328150", "n02342885", "n02346627", "n02356798", "n02361337", "n02363005", "n02364673", "n02389026", "n02391049", "n02395406", "n02396427", "n02397096", "n02398521", "n02403003", "n02408429", "n02410509", "n02412080", "n02415577", "n02417914", "n02422106", "n02422699", "n02423022", "n02437312", "n02437616", "n02441942", "n02442845", "n02443114", "n02443484", "n02444819", "n02445715", "n02447366", "n02454379", "n02457408", "n02480495", "n02480855", "n02481823", "n02483362", "n02483708", "n02484975", "n02486261", "n02486410", "n02487347", "n02488291", "n02488702", "n02489166", "n02490219", "n02492035", "n02492660", "n02493509", "n02493793", "n02494079", "n02497673", "n02500267", "n02504013", "n02504458", "n02509815", "n02510455", "n02514041", "n02526121", "n02536864", "n02606052", "n02607072", "n02640242", "n02641379", "n02643566", "n02655020", "n02666196", "n02667093", "n02669723", "n02672831", "n02676566", "n02687172", "n02690373", "n02692877", "n02699494", "n02701002", "n02704792", "n02708093", "n02727426", "n02730930", "n02747177", "n02749479", "n02769748", "n02776631", "n02777292", "n02782093", "n02783161", "n02786058", "n02787622", "n02788148", "n02790996", "n02791124", "n02791270", "n02793495", "n02794156", "n02795169", "n02797295", "n02799071", "n02802426", "n02804414", "n02804610", "n02807133", "n02808304", "n02808440", "n02814533", "n02814860", "n02815834", "n02817516", "n02823428", "n02823750", "n02825657", "n02834397", "n02835271", "n02837789", "n02840245", "n02841315", "n02843684", "n02859443", "n02860847", "n02865351", "n02869837", "n02870880", "n02871525", "n02877765", "n02879718", "n02883205", "n02892201", "n02892767", "n02894605", "n02895154", "n02906734", "n02909870", "n02910353", "n02916936", "n02917067", "n02927161", "n02930766", "n02939185", "n02948072", "n02950826", "n02951358", "n02951585", "n02963159", "n02965783", "n02966193", "n02966687", "n02971356", "n02974003", "n02977058", "n02978881", "n02979186", "n02980441", "n02981792", "n02988304", "n02992211", "n02992529", "n02999410", "n03000134", "n03000247", "n03000684", "n03014705", "n03016953", "n03017168", "n03018349", "n03026506", "n03028079", "n03032252", "n03041632", "n03042490", "n03045698", "n03047690", "n03062245", "n03063599", "n03063689", "n03065424", "n03075370", "n03085013", "n03089624", "n03095699", "n03100240", "n03109150", "n03110669", "n03124043", "n03124170", "n03125729", "n03126707", "n03127747", "n03127925", "n03131574", "n03133878", "n03134739", "n03141823", "n03146219", "n03160309", "n03179701", "n03180011", "n03187595", "n03188531", "n03196217", "n03197337", "n03201208", "n03207743", "n03207941", "n03208938", "n03216828", "n03218198", "n03220513", "n03223299", "n03240683", "n03249569", "n03250847", "n03255030", "n03259280", "n03271574", "n03272010", "n03272562", "n03290653", "n03291819", "n03297495", "n03314780", "n03325584", "n03337140", "n03344393", "n03345487", "n03347037", "n03355925", "n03372029", "n03376595", "n03379051", "n03384352", "n03388043", "n03388183", "n03388549", "n03393912", "n03394916", "n03400231", "n03404251", "n03417042", "n03424325", "n03425413", "n03443371", "n03444034", "n03445777", "n03445924", "n03447447", "n03447721", "n03450230", "n03452741", "n03457902", "n03459775", "n03461385", "n03467068", "n03476684", "n03476991", "n03478589", "n03481172", "n03482405", "n03483316", "n03485407", "n03485794", "n03492542", "n03494278", "n03495258", "n03496892", "n03498962", "n03527444", "n03529860", "n03530642", "n03532672", "n03534580", "n03535780", "n03538406", "n03544143", "n03584254", "n03584829", "n03590841", "n03594734", "n03594945", "n03595614", "n03598930", "n03599486", "n03602883", "n03617480", "n03623198", "n03627232", "n03630383", "n03633091", "n03637318", "n03642806", "n03649909", "n03657121", "n03658185", "n03661043", "n03662601", "n03666591", "n03670208", "n03673027", "n03676483", "n03680355", "n03690938", "n03691459", "n03692522", "n03697007", "n03706229", "n03709823", "n03710193", "n03710637", "n03710721", "n03717622", "n03720891", "n03721384", "n03724870", "n03729826", "n03733131", "n03733281", "n03733805", "n03742115", "n03743016", "n03759954", "n03761084", "n03763968", "n03764736", "n03769881", "n03770439", "n03770679", "n03773504", "n03775071", "n03775546", "n03776460", "n03777568", "n03777754", "n03781244", "n03782006", "n03785016", "n03786901", "n03787032", "n03788195", "n03788365", "n03791053", "n03792782", "n03792972", "n03793489", "n03794056", "n03796401", "n03803284", "n03804744", "n03814639", "n03814906", "n03825788", "n03832673", "n03837869", "n03838899", "n03840681", "n03841143", "n03843555", "n03854065", "n03857828", "n03866082", "n03868242", "n03868863", "n03871628", "n03873416", "n03874293", "n03874599", "n03876231", "n03877472", "n03877845", "n03884397", "n03887697", "n03888257", "n03888605", "n03891251", "n03891332", "n03895866", "n03899768", "n03902125", "n03903868", "n03908618", "n03908714", "n03916031", "n03920288", "n03924679", "n03929660", "n03929855", "n03930313", "n03930630", "n03933933", "n03935335", "n03937543", "n03938244", "n03942813", "n03944341", "n03947888", "n03950228", "n03954731", "n03956157", "n03958227", "n03961711", "n03967562", "n03970156", "n03976467", "n03976657", "n03977966", "n03980874", "n03982430", "n03983396", "n03991062", "n03992509", "n03995372", "n03998194", "n04004767", "n04005630", "n04008634", "n04009552", "n04019541", "n04023962", "n04026417", "n04033901", "n04033995", "n04037443", "n04039381", "n04040759", "n04041544", "n04044716", "n04049303", "n04065272", "n04067472", "n04069434", "n04070727", "n04074963", "n04081281", "n04086273", "n04090263", "n04099969", "n04111531", "n04116512", "n04118538", "n04118776", "n04120489", "n04125021", "n04127249", "n04131690", "n04133789", "n04136333", "n04141076", "n04141327", "n04141975", "n04146614", "n04147183", "n04149813", "n04152593", "n04153751", "n04154565", "n04162706", "n04179913", "n04192698", "n04200800", "n04201297", "n04204238", "n04204347", "n04208210", "n04209133", "n04209239", "n04228054", "n04229816", "n04235860", "n04238763", "n04239074", "n04243546", "n04251144", "n04252077", "n04252225", "n04254120", "n04254680", "n04254777", "n04258138", "n04259630", "n04263257", "n04264628", "n04265275", "n04266014", "n04270147", "n04273569", "n04275548", "n04277352", "n04285008", "n04286575", "n04296562", "n04310018", "n04311004", "n04311174", "n04317175", "n04325704", "n04326547", "n04328186", "n04330267", "n04332243", "n04335435", "n04336792", "n04344873", "n04346328", "n04347754", "n04350905", "n04355338", "n04355933", "n04356056", "n04357314", "n04366367", "n04367480", "n04370456", "n04371430", "n04371774", "n04372370", "n04376876", "n04380533", "n04389033", "n04392985", "n04398044", "n04399382", "n04404412", "n04409515", "n04417672", "n04418357", "n04423845", "n04428191", "n04429376", "n04435653", "n04442312", "n04443257", "n04447861", "n04456115", "n04458633", "n04461696", "n04462240", "n04465501", "n04467665", "n04476259", "n04479046", "n04482393", "n04483307", "n04485082", "n04486054", "n04487081", "n04487394", "n04493381", "n04501370", "n04505470", "n04507155", "n04509417", "n04515003", "n04517823", "n04522168", "n04523525", "n04525038", "n04525305", "n04532106", "n04532670", "n04536866", "n04540053", "n04542943", "n04548280", "n04548362", "n04550184", "n04552348", "n04553703", "n04554684", "n04557648", "n04560804", "n04562935", "n04579145", "n04579432", "n04584207", "n04589890", "n04590129", "n04591157", "n04591713", "n04592741", "n04596742", "n04597913", "n04599235", "n04604644", "n04606251", "n04612504", "n04613696", "n06359193", "n06596364", "n06785654", "n06794110", "n06874185", "n07248320", "n07565083", "n07579787", "n07583066", "n07584110", "n07590611", "n07613480", "n07614500", "n07615774", "n07684084", "n07693725", "n07695742", "n07697313", "n07697537", "n07711569", "n07714571", "n07714990", "n07715103", "n07716358", "n07716906", "n07717410", "n07717556", "n07718472", "n07718747", "n07720875", "n07730033", "n07734744", "n07742313", "n07745940", "n07747607", "n07749582", "n07753113", "n07753275", "n07753592", "n07754684", "n07760859", "n07768694", "n07802026", "n07831146", "n07836838", "n07860988", "n07871810", "n07873807", "n07875152", "n07880968", "n07892512", "n07920052", "n07930864", "n07932039", "n09193705", "n09229709", "n09246464", "n09256479", "n09288635", "n09332890", "n09399592", "n09421951", "n09428293", "n09468604", "n09472597", "n09835506", "n10148035", "n10565667", "n11879895", "n11939491", "n12057211", "n12144580", "n12267677", "n12620546", "n12768682", "n12985857", "n12998815", "n13037406", "n13040303", "n13044778", "n13052670", "n13054560", "n13133613", "n15075141", ]