ILSVRC2012数据集-图像分类

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)

train数据集

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)

Val数据集

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))

test数据

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)
  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值