1. ImagNet与ILSVRC简介
ImageNet是一种数据集,而不是神经网络模型。斯坦福大学教授李飞飞为了解决机器学习中过拟合和泛化的问题而牵头构建的数据集。该数据集从2007年开始手机建立,直到2009年作为论文的形式在CVPR 2009上面发布。直到目前,该数据集仍然是深度学习领域中图像分类、检测、定位的最常用数据集之一。
基于ImageNet有一个比赛,从2010年开始举行,到2017年最后一届结束。该比赛称为ILSVRC,全称是ImageNet Large-Scale Visual Recognition Challenge,每年举办一次,每次从ImageNet数据集中抽取部分样本作为比赛的数据集。ILSVRC比赛包括:图像分类、目标定位、目标检测、视频目标检测、场景分类。在该比赛的历年优胜者中,诞生了AlexNet(2012)、VGG(2014)、GoogLeNet(2014)、ResNet(2015)等耳熟能详的深度学习网络模型。“ILSVRC”一词有时候也用来特指该比赛使用的数据集,即ImageNet的一个子集,其中最常用的是2012年的数据集,记为ILSVRC2012。因此有时候提到ImageNet,很可能是指ImageNet中用于ILSVRC2012的这个子集。ILSVRC2012数据集拥有1000个分类(这意味着面向ImageNet图片识别的神经网络的输出是1000个),每个分类约有1000张图片。这些用于训练的图片总数约为120万张,此外还有一些图片作为验证集和测试集。ILSVRC2012含有5万张图片作为验证集,10万张图片作为测试集(测试集没有标签,验证集的标签在另外的文档给出)。
ILSVRC2012训练集1000个分类约120万张图片
ILSVRC2012验证集
1000个分类
5万张图片
ILSVRC2012测试集
1000个分类
10万张图片
下面是ImageNet官网上显示的各数据集的大小。
ILSVRC2012是ImageNet的子集,而ImageNet本身有超过1400多万张图片,超过2万多的分类。其中有超过100万张图片有明确类别标注和物体位置标注。
对于如基于ImageNet的图像识别的结果评估,往往用到两个准确率的指标,一个是top-1准确率,一个是top-5准确率。Top-1准确率指的是输出概率中最大的那一个对应的是正确类别的概率;top-5准确率指的是输出概率中最大的5个对应的5个类别中包含了正确类别的概率。
2. 数据集的下载与处理
前面提到过ImageNet的比赛包含多个项目,如果只考虑图像识别的话,训练集只需要上图中Task1&2部分那个(大小138G)。下面是两个下载方法:
1). 官网下载:
可以点上面的链接也可以百度直接搜索。如图需要点Download,但是没有登录的话就算点了也无法进入下载页面,需要先注册登录。右上角sign up和log in。注册的邮箱必须是学校邮箱,即edu的邮箱。
注册登录成功后就可以点积Download进入下载页面,进入了选择2012.
然后就能看到前面1里面出现的那个图了,可以自己下载训练集、验证集和测试集。
2). 官网可能会经常卡住,我自己下的时候就老是失败,因此在网上找了个种子链接,用迅雷(我专门给迅雷冲了个会员,速度有2M/s-5M/s,没有会员会被限速)啥的下起来挺快的。该链接是在参考文献【6】里面看到的:
需要注意的是测试集没有相应的标注,因为比赛的时候会用这些测试数据来检测参赛者的神经网络精度,因此不会公开。所以我们常用验证集来进行自己的网络自测。然而上面所示的验证集解压后也是没有标注的,全是.JPEG图片,因此需要额外下载对应的标注。无论是从官网还是方法2的网站,都可以下载到ILSVRC2012对应的文件:Development kit (Task 1 & 2)。该文件里面含有验证集的标注。打开该压缩文件如下,可以在路径ILSVRC2012_devkit_t12.tar.gz\ILSVRC2012_devkit_t12\data下找到如下两个文件:
ILSVRC2012_validation_ground_truth.txt存放了验证集50000张图片对应的标注(label)。meta.mat则是一些额外的信息,这里不用深究,但是等会还是会用到。将这两个文件解压到自己需要的地方。
回头再来看看验证集的构成。解压后的验证集如下,包含5万张后缀为.JPEG的图片。这些图片的命名如图,名字的最后一串是递增的数字。这些数字与ILSVRC2012_validation_ground_truth.txt中的label意义对应(5000张图片对应5000个数字)。
打开ILSVRC2012_validation_ground_truth.txt可以看到如下所示。例如,第一张图片ILSVRC2012_val_00000001.JPEG对应的是label 490,第二张对应的是361。值得注意的是,这里的label是从1到1000(不是从0开始)。
我们再来看看meta.mat里面是什么内容。用MATLAB打开可以看到如下图。其实第一例的ID和验证集图片的.JEP文件的名称不是对应的,他对应的是验证集图片的label。例如我们打开图片ILSVRC2012_val_00002881.JPEG,是一只狐狸的照片。查看ILSVRC2012_validation_ground_truth.txt中第2881行,发现对应的label是1,再看meta.mat里面的数据,第一列ID为1时,解释是kit fox,这就全对上了。
3. 验证集label的重映射
用前面所描述的对应关系,其实是没有问题的,但是,在我使用Pytorch调用预训练的神经网络模型的过程中发现,Pytorch预训练的模型用的label对应关系和上面的还有些不同。例如,上面所举例的kit fox的标签是1,但是将一系列的kit fox的图片输入某个预训练的神经网络,例如AlexNet,神经网络输出的label是278。这意味着我们上述的label不是主流的label(至少和Pytorch上面的预训练模型不一致,我试过例如MobileNet和ResNet等,采用的是同一套label,但和我们上面讲的不一样)。
前面一节讲的图片的分类是没有问题的,只是label的数字需要重新映射一下,例如需要将现在的1映射到278。我在网上找了一下相关的数据,以用于验证集label的重新映射,发现了参考文献【7】中的数据比较简单好用:
我们来看看这个label的对应关系。将上述txt文件的数据复制到本地,也可以自己重新取个名字,我自己重新取名为transform_for_matlab.txt。依然来看看kit fox的label。在meta.mat里面第2列,kit fox的WNID是n02119789,在transform_for_matlab.txt中搜索n02119789,发现对应的数字是278.这与Pytorch上预训练模型所用label一致。因此,我们需要用这个transform_for_matlab.txt的数据建立验证集图片与label之间的映射关系。
4. 操作流程与相关脚本
因为将ImageNet的图片下载到了本地(或者服务器里面),所以读取数据的时候需要用到ImageFolder。ImageFolder的详细解释参考官网或者百度:
通俗一点讲,就是在某个目录(文件夹)下,同一类图片放在一个子目录下,然后调用ImageFolder去读取这个目录的全部图片。例如我创建一个名为“ILSVRC2012_img_val_Pytorch”的文件夹,下面有1000个子文件夹,每个子文件夹对应的是同一类(同一个label)图片。ImageFolder就用于读取这个名为“ILSVRC2012_img_val_Pytorch”的文件夹
整理一下目前的思路。目前需要的文件:验证集的5万张图片、ILSVRC2012_validation_ground_truth.txt、meta.mat和transform_for_matlab.txt。
我们先用ILSVRC2012_validation_ground_truth.txt、meta.mat和transform_for_matlab.txt将映射关系变得和Pytorch上的默认一致。用下列MATLAB脚本,得到新的与验证集图片一一对应的label的txt文件,命名为trans_idx.txt。
打开trans_idx.txt,如下,可以发现,现在映射关系与ILSVRC2012_validation_ground_truth.txt中完全不同,第一张图片对应65,第二张对应970,第三张对应230…。
至此,我们的目录下应该有这些文件。其中ILSVRC2012_img_val目录下有着5万张.JPEG图片,ILSVRC2012_img_val_Pytorch是我们想要构造的用于ImageFolder读取的重新排好序的文件夹,repath.sh是shell脚本。
执行repath.sh(linux命令行./repath.sh),先创建ILSVRC2012_img_val_Pytorch文件夹,然后在他下面创建名为"000"、“001”、…"999"的1000个子文件夹,然后将ILSVRC2012_img_val下的5万张图片按照trans_idx.txt的映射关系复制到这些子文件夹下面。至此,每个子文件夹的名字就是它下面的图片的label。注意,这里给子文件夹命名采用补零是为了ImageFolder读取的时候,能按照字母升序的顺序,这一点很重要。复制脚本后,其中的文件路径可能需要根据自己的情况做调整。
#!/bin/bash
mkdir ILSVRC2012_img_val_Pytorch
for x in {0..999}
do
if 【 $x -lt 10 】
then
mkdir ILSVRC2012_img_val_Pytorch/00${x}
elif 【 $x -lt 100 】
then
mkdir ILSVRC2012_img_val_Pytorch/0${x}
else
mkdir ILSVRC2012_img_val_Pytorch/${x}
fi
done
cnt=1;
var=1;
while read x
do
echo ${cnt}
if 【 $cnt -lt 10 】
then
if 【 ${x} -lt 10 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_0000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/00${x}/
elif 【 ${x} -lt 100 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_0000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/0${x}/
else
cp ILSVRC2012_img_val/ILSVRC2012_val_0000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/${x}/
fi
elif 【 $cnt -lt 100 】
then
if 【 ${x} -lt 10 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/00${x}/
elif 【 ${x} -lt 100 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/0${x}/
else
cp ILSVRC2012_img_val/ILSVRC2012_val_000000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/${x}/
fi
elif 【 $cnt -lt 1000 】
then
if 【 ${x} -lt 10 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_00000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/00${x}/
elif 【 ${x} -lt 100 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_00000${cnt}.JPEG ILSVRC2012img//代码效果参考:http://www.jhylw.com.cn/011934735.html
val_Pytorch/0${x}/else
cp ILSVRC2012_img_val/ILSVRC2012_val_00000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/${x}/
fi
elif 【 $cnt -lt 10000 】
then
if 【 ${x} -lt 10 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_0000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/00${x}/
elif 【 ${x} -lt 100 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_0000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/0${x}/
else
cp ILSVRC2012_img_val/ILSVRC2012_val_0000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/${x}/
fi
else
if 【 ${x} -lt 10 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/00${x}/
elif 【 ${x} -lt 100 】
then
cp ILSVRC2012_img_val/ILSVRC2012_val_000${cnt}.JPEG ILSVRC2012_img_val_Pytorch/0${x}/
else
cp ILSVRC2012_img_val/ILSVRC2012_val_000${cnt}.//代码效果参考:http://www.jhylw.com.cn/431633585.html
JPEG ILSVRC2012_img_val_Pytorch/${x}/fi
fi
let cnt=${cnt}+1
done < trans_idx.txt
转载:
5. 参考文献
【1】 badchild0912,Note:学习使用ImageNet,2018-05-03。
【2】 zephyr_wang,ILSVRC-ImageNet历年竞赛冠军,2020-08-09。
【3】 种花家的奋斗兔,Imagenet与ILSVRC数据集介绍,2020-01-22。
【4】 CrazyVertigo,【数据集介绍】ImageNet介绍,2017-06-14。
【5】 深度睡眠–,top1错误率、top5正确率,2018-06-20。
【6】 薰风初入弦,薰风写代码|手把手带你下载、处理、加载ImageNet数据集,2021-06-08。
【7】 fh295,semanticCNN/imagenet_labels/ILSVRC2012_mapping.txt。
【8】 ChrisZZ,下载imagenet2012数据集,以及label说明,2018-12-07。
【9】 朴素.无恙,pytorch之ImageFolder,2018-12-19。