
论文:Meta-Dataset: A Dataset of Datasets for Learning to Learn from Few Examples, ICLR 2020
Meta-Dataset 提出的初衷:mini-ImageNet、tiered-ImageNet 等数据集虽然在训练和验证时使用的类别没有交集,但是从外观上看,验证时使用的类别在很大程度上与训练时使用的类相似。导致验证过程仍可 reuse 训练时学习到的 feature embedding。但是,这样就无法验证 model 是否真的能从验证集的 support set中 进行学习。因此,Meta-Datase t融合了多种来源的数据集,想要在该数据集上表现良好,就需要在训练时学习多元信息,并在验证时将其快速 adapt 到完全不同的任务上。
数据来源:Meta-Dataset 由 10个数据集 抽取组成,其中包括自然图像数据集、手写字符及涂鸦数据集。FLUTE 又扩充了3个数据集,包括MNIST,CIFAR-10和CIFAR-100,扩充数据集见 CNAPs。
适用任务:Few-shot Image Classification
数据集使用说明:
| 数据集 | 类别个数 (train/val/test) | 占用 | 转换耗时 |
|---|---|---|---|
| ILSVRC-2012 | 1000 (712/158/130) | ~140GB | 5~13小时 |
| Omniglot | 1623 (25/5/20 ~ 883/81/659) | ~60MB | 几秒 |
| FGVC-Aircraft | 100 (70/15/15) | ~470MB (下载大小~2.6GB) | 5~10分钟 |
| CUB-200-2011 (Birds) | 200 (140/30/30) | ~1.1GB | ~1分钟 |
| Describable Textures (DTD) | 47 (33/7/7) | ~600MB | 几秒 |
| Quick Draw | 345 (241/52/52) | ~50GB | 3~4小时 |
| FGVCx Fungi | 1394 (994/200/200) | ~13GB | 5~15分钟 |
| VGG Flower | 102 (71/15/16) | ~330MB | ~1分钟 |
| German Traffic Sign Recognition Benchmark (GTSRB) | 43 (0/0/43) 仅用于测试 | ~50MB (下载大小~263MB) | ~1分钟 |
| Common Objects in Context (COCO) | 80 (0/40/40) 仅用于验证和测试 | ~5.3GB (下载大小18GB) | 4小时 |
| 所有数据集 | 4934 (3144/598/1192) | ~210GB | 12~24小时 |
下载方式:建议参考 meta-dataset github,我这里对个人的处理过程进行了详细记录。
Meta-Dataset 需要分别下载 10 个数据集,再经过一定的处理将他们转换为同一种组织格式(每个数据类别对应一个TFRecord)。给出的转换脚本以 ILSVRC-2012 为例:
进入 meta-dataset 根目录下,执行转换代码:
python -m meta_dataset.dataset_conversion.convert_datasets_to_records \
--dataset=ilsvrc_2012 \
--ilsvrc_2012_data_root=$DATASRC/ILSVRC2012_img_train \
--splits_root=$SPLITS \
--records_root=$RECORDS
其中:
*_splits.json 文件的存放路径,除了 ilsvrc_2012 和 omniglot 外,其他 8 个数据集都会生成一个 splits 文件,用于划分 train/val/test 类别。如果想要使用作者提供的标准划分,就将 splits_root 设置为 meta_dataset/dataset_conversion,否则当程序找不到需要的 split 文件时,就会自动随机划分数据并生成 split 文件(P.S. 如果不修改源代码,随机生成的结果其实和标准数据划分是一致的,因为作者已经固定的随机数种子,可以通过对照 标准数据划分 来确认一下)查看数据转换代码:./dataset_conversion/dataset_to_records.py 中所有数据集的 Converter 均继承自 DatasetConverter 类,其初始化参数 split_file 用于指定数据集的 split 文件。若提供了数据集 split json 文件,则会通过 read_splits 方法读取,否则会通过 create_splits 方法创建。提供 split_file 的接口作者给出了,但是并没有对应实现,可能是因为只要不修改随机数种子,每个人随机生成的 json 文件其实就是标准划分吧。

*.splits.json 文件示例:

比如我这里使用作者的标准划分,转换后的数据存放在 meta-dataset/:
python -m meta_dataset.dataset_conversion.convert_datasets_to_records \
--dataset=ilsvrc_2012 \
--ilsvrc_2012_data_root=/usr/data/imagenet/ILSVRC2012_img_train \
--splits_root=./ \
--records_root=/usr/data/meta-dataset
(所有数据集的转换脚本都是一样的,只要修改上面的参数即可,后面就不再重复了)
出现这条信息,就说明开始转换了:
Creating ImageNet ILSVRC-2012 specification and records in directory /data/usr/data/imagenet/ILSVRC2012_img_train_convert/ilsvrc_2012...
官方给出的数据集的处理代码基于 Tensorflow 2,因此需要安装 Tensorflow 2,按照官方给出的教程安装即可,但是要注意安装 Tensorflow 2 的系统要求。
我这里是 Ubuntu16.04 系统,在 Conda 环境下进行安装,因此下面只列出我的安装过程:
step1:检查 Conda 环境下的 Python 和 pip 版本,刚好环境 ok,可以直接进入下一步
# 激活conda环境
conda activate xxx
python3 --version
pip3 --version
# 输出
>>> Python 3.7.11
>>> pip 21.2.2 # conda环境下的pip版本
step2:安装 Tensorflow pip 包
# 安装
pip install --upgrade tensorflow
# 检查是否安装成功
python -c "import tensorflow as tf;print(tf.reduce_sum(tf.random.normal([1000, 1000])))"
可以看到成功返回了张量,安装成功~

需要下载 ILSVRC2012,可以参考:ILSVRC-2012 的详细下载方式,我们需要下载的是 Training images (Task 1 & 2),对应压缩包名称为 ILSVRC2012_img_train.tar(138GB)。
关于 train/val/test 划分方式:ILSVRC-2012 共包含1000个类别,Meta-Dataset 仅使用了 ILSVRC-2012 的 training set 部分,并基于 training set 划分训练、验证和测试集。训练/验证/测试按照类别数量划分为 712/158/130。从 论文 中可以看到,作者选择 carnivore 和 device 作为验证集和测试集的 root 结点,其余的都作为训练集。因此,训练集包含 712 个类别,验证集包含 158 个,测试集包含 130 个。
在 数据转换过程 中,Meta-Dataset 会将 ILSVRC-2012 数据中与其他数据集重复的样本跳过,这样就能保证使用其他数据集作为 test set 时,不会已经见过该样本。其中 ILSVRC-2012 与 CUB-200-2011重复 43 张,与 Caltech-101 重复 92 张,与 Caltech-256 重复 286 张。注意:Caltech-101 和 Caltech-256 不包含在 Meta-Dataset 中,但作者还是去掉了,应该是以防其他工作需要用到吧,未雨绸缪了。

ILSVRC-2012 的转换代码:./dataset_conversion/dataset_to_records.py 作者在注释中写的很清楚,这里仅使用了 ImageNet 数据集的 training set 部分,并且与Caltech101、Caltech256、CUBirds这三个数据集有交集的数据在转换过程中都会被 skip 掉。

step 1:准备数据(解压过程大约需要30分钟)
数据下载好之后解压:
# cd到数据存放目录,将tar包解压到指定文件夹下
mkdir ILSVRC2012_img_train
tar -xvf ILSVRC2012_img_train.tar -C ILSVRC2012_img_train/
在文件夹 ILSVRC2012_img_train 下面包含了1000个子压缩包 nxxxxxxx.tar,继续对每个子压缩包进行解压。在当前目录下创建脚本文件tar.sh:
cd ILSVRC2012_img_train/
vi tar.sh
直接复制粘贴下面代码内容:
for FILE in *.tar;
do
mkdir ${FILE/.tar/};
cd ${FILE/.tar/};
tar xvf ../$FILE;
cd ..;
done
执行脚本文件进行解压:
chmod +x tar.sh
./tar.sh
下载 wordnet.is_a.txt 和 words.txt 两个文件,放在 ILSVRC2012_img_train/ 目录下。
step 2:转换数据
进入 meta-dataset 根目录下,执行转换代码(--dataset改为ilsvrc_2012),最终转换完成的文件在 meta-dataset/ilsvrc_2012/ 下,包含:
.tfrecords 文件,编号为 0~999dataset_spec.json 文件,关于数据集的一些信息num_leaf_images.json 文件Meta-Dataset 只需要使用 Omniglot 中的 images_background.zip 和 images_evaluation.zip 两个文件。Omniglot 的下载可以参考 Omniglot 的详细下载方式。
Omniglot 的类别划分为了两级,第一级为 alphabet,第二级为 character。Meta-Dataset 使用了 Omniglot 的原始划分方式,即 background 作为训练集,evaluation 作为测试集,不同的是,Omniglot 没有设置验证集,因此 Meta-Dataset 从训练集中划分出了 5 个最小的 alphabet 集合作为验证集,因此实际上的训练集只有 25 个 alphabet。
step1:准备数据
下载 images_background.zip 和 images_evaluation.zip,保存在文件夹 omniglot 下,解压两个数据压缩包到当前文件夹。
cd omniglot
unzip images_background.zip
unzip images_evaluation.zip
step2:转换数据
进入 meta-dataset 根目录下,执行转换代码(--dataset改为omniglot),最终转换完成的文件在 meta-dataset/omniglot/ 下,包含:
.tfrecords 文件,编号为 0~1622dataset_spec.json 文件step1:准备数据
下载 fgvc-aircraft-2013b.tar.gz 到目录 aircraft,即可在当前目录下解压:
cd aircraft
tar -xzvf fgvc-aircraft-2013b.tar.gz
step2:转换数据
进入 meta-dataset 根目录下,执行转换代码(--dataset改为aircraft),最终转换完成的文件在 meta-dataset/aircraft/ 下,包含:
.tfrecords 文件,编号为 0~99dataset_spec.json 文件Meta-Dataset 使用 CUB-200-2011 数据集的分类部分数据 ,即下载 Images and annotations (1.1 GB)。关于 CUB-200-2011 的详细内容解释参考:CUB-200-2011 的使用与下载。
step1:准备数据
下载数据到目录 cub-200-2011,即可在当前目录下解压:
cd cub-200-2011
tar -zxvf CUB_200_2011.tgz
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为cu_birds),最终转换完成的文件在 meta-dataset/cu_birds/ 下,包含:
.tfrecords 文件,编号为 0~199dataset_spec.json 文件step1:准备数据
下载 dtd-r1.0.1.tar.gz 到目录 dtd,即可在当前目录下解压:
cd dtd
tar -xzvf dtd-r1.0.1.tar.gz
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为dtd),最终转换完成的文件在 meta-dataset/dtd/ 下,包含:
.tfrecords 文件,编号为 0~46dataset_spec.json 文件step1:准备数据
需要从 Google Cloud 下载 345 个 .npy 文件,直接手动下载太麻烦,可以安装 gsutil 工具来下载。我这里在服务器上直接下载,首先要保证当前环境有 Python,执行如下:
# 安装gsutil
pip install gsutil
# 下载数据集,./表示下载到当前文件夹
cd quickdraw
gsutil -m cp gs://quickdraw_dataset/full/numpy_bitmap/*.npy ./
最后一行显示了下载进度:

step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为quickdraw),最终转换完成的文件在 meta-dataset/quickdraw/ 下,包含:
.tfrecords 文件,编号为 0~344dataset_spec.json 文件step1:准备数据
下载 fungi_train_val.tgz 和 train_val_annotations.tgz 到目录 fungi,即可在当前目录下解压:
cd fungi
tar -zxvf fungi_train_val.tgz
tar -zxvf train_val_annotations.tgz
解压出的文件包含一个 images 文件夹和 train.json、val.json 文件。
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为fungi),最终转换完成的文件在 meta-dataset/fungi/ 下,包含:
.tfrecords 文件,编号为 0~1393dataset_spec.json 文件step1:准备数据
下载 102flowers.tgz 和 imagelabels.mat 到目录 vgg_flower,即可在当前目录下解压:
cd vgg_flower
tar -zxvf 102flowers.tgz
解压完成仅包含一个 jpg 文件夹,包含了所有图像。
P.S. 注意 imagelabels.mat 由于特殊后缀,浏览器可能不会直接解析并下载,此时可以右键选择 “将链接另存为” 或者直接在命令行输入:
wget http://www.robots.ox.ac.uk/~vgg/data/flowers/102/imagelabels.mat
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为vgg_flower),最终转换完成的文件在 meta-dataset/vgg_flower/ 下,包含:
.tfrecords 文件,编号为 0~101dataset_spec.json 文件step1:准备数据
下载 GTSRB_Final_Training_Images.zip 到目录 traffic_sign(备用链接 website),即可在当前目录下解压:
cd traffic_sign
unzip GTSRB_Final_Training_Images.zip
解压完成后得到一个 GTSRB 文件夹。
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为traffic_sign),最终转换完成的文件在 meta-dataset/traffic_sign/ 下,包含:
.tfrecords 文件,编号为 0~42dataset_spec.json 文件P.S. 转换代码的 --traffic_sign_data_root 指定到 GTSRB 文件夹下。
step1:准备数据
Meta-Dataset 使用 MSCOCO 数据集的 training 部分数据,在 COCO官网 下载 train2017.zip 和 annotations_trainval2017.zip 到目录 coco。
P.S. 使用 gsutil 下载的方式目前(2022-07-04)不可行,好像是因为 bucket 不可用,因此会报错:
BucketNotFoundException: 404 gs://images.cocodataset.org bucket does not exist.
不过没准呢,说不定你看到的时候就可以下载了,可以按照下面的方式下载:
cd <your path to mscoco>
mkdir train2017
gsutil -m rsync gs://images.cocodataset.org/train2017 train2017
gsutil -m cp gs://images.cocodataset.org/annotations/annotations_trainval2017.zip
unzip annotations_trainval2017.zip
解压数据:
cd coco
unzip train2017.zip
unzip annotations_trainval2017.zip
step2:转换数据
进入 meta-dataset 根目录下执行转换代码(--dataset改为mscoco),最终转换完成的文件在 meta-dataset/mscoco/ 下,包含:
.tfrecords 文件,编号为 0~79dataset_spec.json 文件FLUTE 在 Meta-Dataset 基础上又扩充了 3 个测试数据集,分别是 MNIST,CIFAR-10 和 CIFAR-100,扩充数据集见 CNAPs。
首先仍然进入存放 meta-dataset 10 个数据集的根目录下。
cd $DATASRC
step1:准备数据
# MNIST test images
wget http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz
# MNIST test labels
wget http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz
# CIFAR10 dataset
wget https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz
tar -zxvf cifar-10-python.tar.gz
# CIFAR100 dataset
wget https://www.cs.toronto.edu/~kriz/cifar-100-python.tar.gz
tar -zxvf cifar-100-python.tar.gz
step2:转换数据
cd 进入 cnaps/src 目录,执行:
export DATASRC=/usr/data/meta-dataset # 原始数据存放位置
export SPLITS=/usr/data/meta-dataset # 数据集划分文件存放路径
export RECORDS=/usr/data/meta-dataset # 转换数据存放路径
export META_DATASET_ROOT=/usr/code/meta-dataset-main # 原始meta-daata代码路径
python prepare_extra_datasets.py
处理完毕后,会在 RECORDS 目录下分别生成 MNIST,CIFAR-10 和 CIFAR-100 的数据文件夹。