赞
踩
Reference:
ILSVRC2012数据集(分类部分)简要介绍和初步处理
Imagenet 完整数据集下载
imagenet2012数据集下载
本文仅做学习记录使用,若侵权,留言秒删
ILSVRC2012数据集(分类部分)的简要介绍和初步处理
即大名鼎鼎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 完整数据集下载通过种子下载。
针对以上tar压缩包采用tarfiel库进行解压缩,代码如下:
""" 文件格式如下: your/path/to/ILSVRC2012 ILSVRC2012_img_train.tar ILSVRC2012_img_val.tar ILSVRC2012_img_test.tar ILSVRC2012_devkit_t12.gz ilsvrc_dir = your/path/to/ILSVRC2012 """ root, _, files = next(os.walk(ilsvrc_dir)) for file in files: # 获取当前处理的 tar 文件的路径 tar_file_path = os.path.join(root, file) # 打开 tar 文件 with tarfile.open(tar_file_path) as tar: # 获取 tar 文件中所有文件和文件夹的名称 file_names = tar.getnames() # 获取 tar 文件的目录路径 root_dir = os.path.dirname(tar_file_path) # 获取 tar 文件的基本名称 base_name = os.path.basename(tar_file_path) # 创建用于提取内容的路径,使用 tar 文件的基本名称 extract_dir = os.path.join(root_dir, base_name.split(".")[0]) # 如果输出文件夹不存在,则创建 os.makedirs(extract_dir, exist_ok=True) # 将 tar 文件中的每个文件/文件夹提取到输出文件夹中 for file_name in file_names: tar.extract(file_name, extract_dir)
ILSVRC2012_img_train.tar中有1000个tar压缩包,分别对应1000个类别。每个tar解压后得到对应类别的图片。可以使用一个简单的python程序或shell脚本将数据分别压缩至对应名称的文件夹中。将1000个tar解压至ILSVRC2012_img_train文件夹中,创建ILSVRC2012_img_train文件夹,将对应图片解压至相应的文件夹中。python脚本如下:
def unTrainTar(file_names,extract_dir): """ 将 tar 文件解压缩到指定文件夹。 Args: tar_file_path (str): 要解压缩的 tar 文件的路径。 Returns: None """ # 获取分类名称 for file_name in file_names: category_name = file_name.split(".")[0] # 构建分类 tar 文件路径和解压路径 category_tar_path = os.path.join(extract_dir, file_name) category_extract_path = os.path.join(extract_dir, category_name) # 如果分类文件夹不存在,则创建 os.makedirs(category_extract_path, exist_ok=True) # 打开分类的 tar 文件 with tarfile.open(category_tar_path) as category_tar: img_names = category_tar.getnames() # 将分类的每个图片提取到分类文件夹中 for img_name in img_names: category_tar.extract(img_name, category_extract_path) os.remove(category_tar_path)
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 moveValImg(val_dir, devkit_dir): """ 将验证图片移动到相应的文件夹中。 Args: val_dir (str): 验证图片所在的文件夹路径。 devkit_dir (str): ILSVRC2012_devkit_t12 目录的路径。 Returns: None """ # 加载 synset,val 图片的 ground truth 和 val 图片列表 synset = scipy.io.loadmat(os.path.join(devkit_dir, 'data', 'meta.mat')) with open(os.path.join(devkit_dir, 'data', 'ILSVRC2012_validation_ground_truth.txt')) as ground_truth: # 读取 val 图片的 ground truth,每一行是一个数字,表示对应图片的类别标签 labels = [int(line.strip()) for line in ground_truth.readlines()] # 获取 val 图片所在文件夹的路径以及该文件夹下所有文件的名称 root, _, filenames = next(os.walk(val_dir)) for filename in filenames: # 获取当前处理的 val 图片的编号,例如'ILSVRC2012_val_00000001.JPEG'中的 '00000001' val_id = int(filename.split('.')[0].split('_')[-1]) # 获取对应 val 图片的类别标签,ILSVRC ID 从 1 开始,而 val_id 从 1 开始,因此需要减 1 ILSVRC_ID = labels[val_id - 1] # 获取该 val 图片的类别名称 WIND(即 ImageNet 类别名称),通过 synset 加载的数据获取 WIND = synset['synsets'][ILSVRC_ID - 1][0][1][0] # 输出当前处理的 val 图片的编号、类别标签和类别名称 print("val_id:%d, ILSVRC_ID:%d, WIND:%s" % (val_id, ILSVRC_ID, WIND)) # 构建该 val 图片应该移动到的目标文件夹路径 output_dir = os.path.join(root, WIND) # 如果目标文件夹不存在,则创建 if not os.path.isdir(output_dir): os.mkdir(output_dir) # 移动当前处理的 val 图片到目标文件夹中 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
每个synset有100个测试图像,不公布测试图像的groud_truth。
开发工具集
除了说明性文件,比较有用的数据主要有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“实体”。
代码汇总如下:
import os import tarfile import scipy import shutil def unTrainTar(file_names,extract_dir): """ 将 tar 文件解压缩到指定文件夹。 Args: tar_file_path (str): 要解压缩的 tar 文件的路径。 Returns: None """ # 获取分类名称 for file_name in file_names: category_name = file_name.split(".")[0] # 构建分类 tar 文件路径和解压路径 category_tar_path = os.path.join(extract_dir, file_name) category_extract_path = os.path.join(extract_dir, category_name) # 如果分类文件夹不存在,则创建 os.makedirs(category_extract_path, exist_ok=True) # 打开分类的 tar 文件 with tarfile.open(category_tar_path) as category_tar: img_names = category_tar.getnames() # 将分类的每个图片提取到分类文件夹中 for img_name in img_names: category_tar.extract(img_name, category_extract_path) os.remove(category_tar_path) def moveValImg(val_dir, devkit_dir): """ 将验证图片移动到相应的文件夹中。 Args: val_dir (str): 验证图片所在的文件夹路径。 devkit_dir (str): ILSVRC2012_devkit_t12 目录的路径。 Returns: None """ # 加载 synset,val 图片的 ground truth 和 val 图片列表 synset = scipy.io.loadmat(os.path.join(devkit_dir, 'data', 'meta.mat')) with open(os.path.join(devkit_dir, 'data', 'ILSVRC2012_validation_ground_truth.txt')) as ground_truth: # 读取 val 图片的 ground truth,每一行是一个数字,表示对应图片的类别标签 labels = [int(line.strip()) for line in ground_truth.readlines()] # 获取 val 图片所在文件夹的路径以及该文件夹下所有文件的名称 root, _, filenames = next(os.walk(val_dir)) for filename in filenames: # 获取当前处理的 val 图片的编号,例如'ILSVRC2012_val_00000001.JPEG'中的 '00000001' val_id = int(filename.split('.')[0].split('_')[-1]) # 获取对应 val 图片的类别标签,ILSVRC ID 从 1 开始,而 val_id 从 1 开始,因此需要减 1 ILSVRC_ID = labels[val_id - 1] # 获取该 val 图片的类别名称 WIND(即 ImageNet 类别名称),通过 synset 加载的数据获取 WIND = synset['synsets'][ILSVRC_ID - 1][0][1][0] # 输出当前处理的 val 图片的编号、类别标签和类别名称 print("val_id:%d, ILSVRC_ID:%d, WIND:%s" % (val_id, ILSVRC_ID, WIND)) # 构建该 val 图片应该移动到的目标文件夹路径 output_dir = os.path.join(root, WIND) # 如果目标文件夹不存在,则创建 if not os.path.isdir(output_dir): os.mkdir(output_dir) # 移动当前处理的 val 图片到目标文件夹中 shutil.move(os.path.join(root, filename), os.path.join(output_dir, filename)) def untar_ilsvrc(ilsvrc_dir, traintar='./traintar'): """ 从 traintar 中解压图像并保存到相应的文件夹中。 Args: ilsvrc_dir (str): ILSVRC 数据集的目录路径。 traintar (str): 存储训练图像的 tar 文件夹路径,默认为 './traintar'。 Returns: None """ # 遍历 ILSVRC 数据集目录中的所有文件 root, _, files = next(os.walk(ilsvrc_dir)) for file in files: # 获取当前处理的 tar 文件的路径 tar_file_path = os.path.join(root, file) # 打开 tar 文件 with tarfile.open(tar_file_path) as tar: # 获取 tar 文件中所有文件和文件夹的名称 file_names = tar.getnames() # 获取 tar 文件的目录路径 root_dir = os.path.dirname(tar_file_path) # 获取 tar 文件的基本名称 base_name = os.path.basename(tar_file_path) # 创建用于提取内容的路径,使用 tar 文件的基本名称 extract_dir = os.path.join(root_dir, base_name.split(".")[0]) # 如果输出文件夹不存在,则创建 os.makedirs(extract_dir, exist_ok=True) # 将 tar 文件中的每个文件/文件夹提取到输出文件夹中 for file_name in file_names: tar.extract(file_name, extract_dir) # 根据当前处理的文件类型调用相应的函数进行进一步处理 if "img_train" in file: # 对训练图片的 tar 文件进行解压缩,并保存到对应的文件夹中 unTrainTar(file_names,extract_dir) if "img_val" in file: # 对验证图片进行处理,包括移动到相应文件夹中等操作 val_dir = os.path.join(root, "ILSVRC2012_img_val") devkit_dir = os.path.join(root, "ILSVRC2012_devkit_t12/ILSVRC2012_devkit_t12") moveValImg(val_dir, devkit_dir) if "img_test" in file: # 对测试图片进行处理,目前未实现 pass if __name__ == "__main__": ilsvrc_dir = r"your/path/to/ILSVRC2012" untar_ilsvrc(ilsvrc_dir)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。