基于python的 CIFAR-10 与 CIFAR-100可视化

这两天再做卷积神经网络的训练,数据集是CIFAR-10和CIFAR-100。虽然pytorch自带使用这两个数据集的类(datasets.CIFAR10()和datasets.CIFAR100()),使用的时候不用关心内部是如何对数据集进行处理的,但是心里还是想把这两个数据集可视化一下。顺便在这里做个笔记,为有心人提供参考,一起学习。

数据集简介:

CIFAR-10 与 CIFAR-100是计算机视觉中最基本的两个数据集,每个数据集都包含60k张图片,并且都是50k张训练,10k张测试。这两个数据集的压缩包解压后分别得到‘cifar-10-batches-py’和‘cifar-100-python’这两个文件夹,也就是datasets.CIFAR10()和datasets.CIFAR100()这两个类要用到的文件夹。
cifar-10-batches-py文件夹内容:
cifar-10-batches-py的内容
cifar-100-python文件夹内容:
cifar-100-python的内容
下面我们主要对这两个文件夹进行操作,将里面的图片提取出来。

说到基本数据集当然还有MNIST,EMNIST等,但是这些太过简单,在学术论文中,基本被抛弃使用。甚至从近些年的趋势来看,CIFAR-10的使用频率也在下降,因为随着视觉领域的算法越发的SOTA,尤其是随着Transformer和MLP(这里的MLP不是几十年前的那种简单MLP,大家可以参考这篇文章,https://arxiv.org/pdf/2105.01601.pdf)的加入,这些简单的数据集已经支撑不起检验一个算法性能的重任。相反一些大的数据集使用的频率在增加,比如 ImageNet,ImageNet21k,JFT-300M等。

提取CIFAR-10:

因为CIFAR-10和CIFAR-100原始数据集都是序列化后的数据,因此在查看和提取过程需要用到pickle包,进行反序列化,可以形象地看成是解压。
CIFAR-10的训练集存储在‘data_batch_i’(i=1,2,3,4,5)这五个文件内,因为训练集包含50k的样本,因此每个文件包含10k个样本。我们可以看一下他们中都有些什么:
1)类型

  import pickle
  for i in range(5):
    with open('.\cifar-10-batches-py\data_batch_' + str(i + 1), 'rb') as f:
        file = pickle.load(f, encoding='bytes')
        print(type(file))
        

结果:

<class 'dict'>
<class 'dict'>
<class 'dict'>
<class 'dict'>
<class 'dict'>

可以看出它们都是字典。
2)字典里的内容
因为它们包含的内容格式都是一样的,所以这里只打印一个。


for i in range(5):
    with open('.\cifar-10-batches-py\data_batch_' + str(i + 1), 'rb') as f:
        file = pickle.load(f, encoding='bytes')#反序列化
        for i in file:
           print(i,type(file[i]))
    break

结果:

b'batch_label' <class 'bytes'>
b'labels' <class 'list'>
b'data' <class 'numpy.ndarray'>
b'filenames' <class 'list'>

这里的‘b’表示的是bytes类型。可以看出这5个字典中每个字典都包含b’batch_label’,b’labels’ ,b’data’,b’filenames这4个键。
b’batch_label’:
b’batch_label’为 <class ‘bytes’>类型。5个文件每个文件的b’batch_label’如下:

b'training batch 1 of 5'
b'training batch 2 of 5'
b'training batch 3 of 5'
b'training batch 4 of 5'
b'training batch 5 of 5'
‘’‘其实就是每个文件的别名或标签。’‘’

b’labels’
b’labels’ 为<class ‘list’>类型。顾名思义,b’labels’就是每个文件中所有样本对应的标签。因为每个文件都包含10k个样本,所以b’labels’的长度自然为10k。这里只打印第一个文件的部分片段。
里面的每个标签都在区间[0,9]内。

[6, 9, 9, 4, 1, 1, 2, 7, 8, 3, 4, 7,... 5, 1, 2, 9, 2, 2, 1, 6, 3, 9, 1, 1, 5]

b’data’
b’data’为<class ‘numpy.ndarray’>类型。里面存储的就是样本(图片)的像素值了。二维数组,第一维长度是10k,第二维长度是3x32x32(样本通道x样本宽x样本高)。
[[ 59 43 50 ... 140 84 72] [154 126 105 ... 139 142 144] [255 253 253 ... 83 83 84] ... [ 71 60 74 ... 68 69 68] [250 254 211 ... 215 255 254] [ 62 61 60 ... 130 130 131]]
b’filenames’
b’filenames’ 也为<class ‘list’>类型,里面存放的是每个样本的名称(bytes类型),因此长度也为10k。这里就举第一个文件的部分片段。

[b'leptodactylus_pentadactylus_s_000004.png', b'camion_s_000148.png',..., b'truck_s_000036.png', b'car_s_002296.png', b'estate_car_s_001433.png', b'cur_s_000170.png']

很直接,就是每个图片的名称。
提取图片完整代码如下:

import numpy as np
import pickle
import os
from PIL import Image

if __name__ == '__main__':
    channels = 3
    img_width, img_height = 32, 32
    ima_dir = r'***'
    if not os.path.exists(ima_dir):
        os.mkdir(ima_dir)
        # os.makedirs()
    data = []
    label = []
    data_name = []
    for i in range(5):
        with open('***\cifar-10-batches-py\data_batch_' + str(i + 1), 'rb') as f:
            file = pickle.load(f, encoding='bytes')
            data.extend(file[b'data'])
            label.extend(file[b'labels'])
            data_name.extend(file[b'filenames'])
    with open(r'***\cifar-10-labels.txt', 'w') as f:
            for i in label:
                f.write(str(i)  + '\n')
    images = np.reshape(data, [-1, channels, img_width, img_height])
    for ind in range(len(images)):
        r = images[ind][0]
        g = images[ind][1]
        b = images[ind][2]

        ir = Image.fromarray(r)
        ig = Image.fromarray(g)
        ib = Image.fromarray(b)

        rgb = Image.merge('RGB', (ir, ig, ib))
        img_path = os.path.join(ima_dir, data_name[ind].decode())
        rgb.save(img_path, 'PNG')

提取结果
提取结果
提取训练集类似。

提取CIFAR-100:

与CIFAR-10不同的是CIFAR-100的训练数据全部放在了文件夹train里面。

import pickle
with open(r'.\cifar-100-python\train', 'rb') as f:
        file = pickle.load(f, encoding='bytes')#反序列化
        for i in file:
           print(i,type(file[i]))

结果:

b'filenames' <class 'list'>
b'batch_label' <class 'bytes'>
b'fine_labels' <class 'list'>
b'coarse_labels' <class 'list'>
b'data' <class 'numpy.ndarray'>

b’filenames’
这里的b’filenames’同CIFAR-10一样,只不过长度变为了50k。
b’batch_label’

b'training batch 1 of 1'

其实就是这个文件的一个别名或标签。
b’fine_labels’
精标签。CIFAR-100有两种标签,一类是粗标签,20个类,在此基础上又将每个样本细分类为了100个类,即精标签。
b’coarse_labels’
粗标签。
b’data’
同CIFAR-10一样,原始数据的像素。
提取图片完整代码如下:

import pickle
import numpy as np
import os
from PIL import Image

if __name__ == '__main__':
    img_dir = r'***'
    channels = 3
    width = 32
    height = 32
    if not os.path.exists(os.path.join(img_dir, 'cifar100_real_images')):
        os.mkdir(
            os.path.join(img_dir, 'cifar100_real_images')
        )
    filenames = []
    fine_labels = []
    coarse_labels = []
    data = []
    with open(r'***\cifar-100-python\train', 'rb') as f:
        file = pickle.load(f, encoding='bytes')

        for i in file:
            if i == b'filenames':
                filenames = [name.decode() for name in file[i]]
            if i == b'fine_labels':
                fine_labels = file[i]
            if i == b'coarse_labels':
                coarse_labels = file[i]
            if i == b'data':
                data = file[i]
        data = np.reshape(data, [-1, channels, width, height])
 
        for ind in range(len(data)):
            r = data[ind][0]
            g = data[ind][1]
            b = data[ind][2]

            ir = Image.fromarray(r)
            ig = Image.fromarray(g)
            ib = Image.fromarray(b)

            rgb = Image.merge('RGB', (ir, ig, ib))

            rgb.save(os.path.join(img_dir, 'cifar100_real_images', str(ind)+'.png'),'PNG')
            
    with open(r'***\cifar-100-labels.txt','w') as f:
        for i,j in list(zip(fine_labels,coarse_labels)):
            f.write(str(i)+' '*5+str(j)+'\n')
 

这里需要注意一下,因为在b’filenames’中有两个样本名称一样,这样的话要是根据这些名称生成样本,会被覆盖掉一个,结果是49999个样本。所以不能像CIFAR-10那样根据名称生成样本。

提取结果如下:
提取结果
提取训练集类似。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葉相惜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值