即大名鼎鼎ImageNet2012竞赛的数据集,在图像分类数据集中属于最常用的跑分数据集和预训练数据集。
主要内容可以参考ILSVRC2012_devkit_t12.gz
的readme.txt
下载的文件主要包括以下几个文件:
ILSVRC2012_img_train.tar
ILSVRC2012_img_val.tar
ILSVRC2012_img_test.tar
ILSVRC2012_devkit_t12.gz
前三个为图像压缩包,分别对应train / val / test三个子集。最后一个为数据说明相关文档。
下载地址可以参考imagenet2012数据集下载直接用迅雷下载,或参考Imagenet 完整数据集下载通过种子下载。
ILSVRC2012_img_train.tar
中有1000个tar压缩包,分别对应1000个类别。每个tar解压后得到对应类别的图片。可以使用一个简单的python程序或shell脚本将数据分别压缩至对应名称的文件夹中。将1000个tar解压至traintar文件夹中,创建train文件夹,将对应图片解压至相应的文件夹中。
shell脚本如下:
# 创建 shell 文件: unzip.sh; shell 文件运行 bash unzip.sh
dir=./
for x in `ls *.tar`
do
filename=`basename $x .tar`
mkdir $filename
tar -xvf $x -C ./$filename
done
python脚本如下:
def un_tar(file_name, output_root='train'):
# untar zip file to folder whose name is same as tar file
tar = tarfile.open(file_name)
names = tar.getnames()
file_name = os.path.basename(file_name)
extract_dir = os.path.join(output_root, file_name.split('.')[0])
# create folder if nessessary
if os.path.isdir(extract_dir):
pass
else:
os.mkdir(extract_dir)
for name in names:
tar.extract(name, extract_dir)
tar.close()
def untar_traintar(traintar='./traintar'):
"""
untar images from traintar and save in corresponding folders
organize like:
/train
/n01440764
images
/n01443537
images
.....
"""
root, _, files = next(os.walk(traintar))
for file in files:
un_tar(os.path.join(root, file))
ILSVRC2012_img_val.tar
中有50000张图片,并没有按照类别区分开,命名方式形如:
ILSVRC2012_val_00000001.JPEG
ILSVRC2012_val_00000002.JPEG
...
ILSVRC2012_val_00049999.JPEG
ILSVRC2012_val_00050000.JPEG
关于val数据集的标签,保存在ILSVRC2012_devkit_t12.gz
中的data文件夹下的ILSVRC2012_validation_ground_truth.txt
中,按照编号顺序每行用1-1000的数字表示一个类别。每个类别有50个样本。可以借助python中的scipy包访问mat文件的内容。scipy.io.loadmat
移动val数据的示例程序如下:
def move_valimg(val_dir='./val', devkit_dir='./ILSVRC2012_devkit_t12'):
"""
move valimg to correspongding folders.
val_id(start from 1) -> ILSVRC_ID(start from 1) -> WIND
organize like:
/val
/n01440764
images
/n01443537
images
.....
"""
# load synset, val ground truth and val images list
synset = scipy.io.loadmat(os.path.join(devkit_dir, 'data', 'meta.mat'))
ground_truth = open(os.path.join(devkit_dir, 'data', 'ILSVRC2012_validation_ground_truth.txt'))
lines = ground_truth.readlines()
labels = [int(line[:-1]) for line in lines]
root, _, filenames = next(os.walk(val_dir))
for filename in filenames:
# val image name -> ILSVRC ID -> WIND
val_id = int(filename.split('.')[0].split('_')[-1])
ILSVRC_ID = labels[val_id-1]
WIND = synset['synsets'][ILSVRC_ID-1][0][1][0]
print("val_id:%d, ILSVRC_ID:%d, WIND:%s" % (val_id, ILSVRC_ID, WIND))
# move val images
output_dir = os.path.join(root, WIND)
if os.path.isdir(output_dir):
pass
else:
os.mkdir(output_dir)
shutil.move(os.path.join(root, filename), os.path.join(output_dir, filename))
ILSVRC2012_img_test.tar
总共有10万张测试图片,命名方式形如:
ILSVRC2012_test_00000001.JPEG
ILSVRC2012_test_00000002.JPEG
...
ILSVRC2012_test_00099999.JPEG
ILSVRC2012_test_00100000.JPEG
除了说明性文件,比较有用的数据主要有val数据的标签文件data/ILSVRC2012_validation_ground_truth.txt
和类别说明data/meta.mat
。
synsets的信息如下:
synsets =
1x1 struct array with fields:
ILSVRC2012_ID
WNID
words
gloss
num_children
children
wordnet_height
num_train_images
这个struct数组每个字段的意义如下:
'ILSVRC2012_ID’是分配给每个synset的整数ID。所有的低等级synsets都被分配了1到1000之间的ID。所有高等级synsets的ID都大于1000。在“synsets”数组中,按照ILSVRC2012_ID对synsets进行排序,即synsets(i)。i.预测结果提交使用ILSVRC2012_ID作为synset标签。
'WNID’是一个synset的WordNet ID。它是ImageNet或WordNet中synset的唯一标识。训练图像的tar文件使用WNID命名。此外,它还用于命名单个训练图像。
'num_children’是该synset的子类数量。对于所有低等级synsets,它都是零;对于高等级synsets,它是非零的。
'children’是该synset的子类的ILSVRC2012_IDs组成的向量。
'wordnet_height’是指在完整ImageNet/WordNet层次结构中的到其子节点(子类)的最长路径的长度(完整ImageNet层次结构中的叶子节点的wordnet_height为0)。
层次结构根的ILSVRC2012_ID为1001,即synset“实体”。
数据整理到如上所示的目录结构后,可以使用keras中的ImageDataGenerator
的flow_from_directory
方法或是pytorch中的torchvision.datasets.ImageFolder
来读取数据,便于下一步的处理。