CIFAR-10 数据集介绍
数据来源
CIFAR-10 是由 Hinton 的学生 AlexKrizhevsky 和 IlyaSutskever 整理的一个用于识别普适物体的小型数据集2。
包含类别
一共包含 10 个类别的 RGB 彩色图片:飞机(airplane)、汽车(automobile)、鸟类(bird)、猫(cat)、鹿(deer)、狗(dog)、蛙类(frog)、马(horse)、船(ship)和卡车(truck)2。
图片尺寸与数量
- 图片的尺寸为 32×32。
- 数据集中一共有 50000 张训练图片和 10000 张测试图片2。
数据特点
- 相比于手写字符,CIFAR-10 含有的是现实世界中真实的物体,不仅噪声很大,而且物体的比例、特征都不尽相同,这为识别带来很大困难。直接的线性模型如 Softmax 在 CIFAR-10 上表现得很差2。
- 同已经成熟的人脸识别相比,普适物体识别挑战巨大,数据中含有大量特征、噪声,识别物体比例不一。因而,CIFAR-10 相对于传统图像识别数据集,是相当有挑战的1
接下来,我们都需要使用这个CIFAR-10数据集,首先我们得下载数据集
from torchvision import datasets
data_path = 'F:\\深度学习\\CIFAR—10' # 数据下载的位置
cifar10 = datasets.CIFAR10(data_path, train=True, download=True)
cifar10_val = datasets.CIFAR10(data_path, train=False, download=True)
download后面的参数如果指定路径找不到这个数据集的话,会自动在该路径下下载此数据集
可是事实上小编也是下载的比较慢
小编通过其他途径下载完毕,现在直接把网盘分享给大家
通过百度网盘分享的文件:cifar-10-python.tar.gz
链接:https://pan.baidu.com/s/1DmAYGmc5-HPaiiN3hWPDzQ
提取码:kafo
大家自行下载即可
获取CIFAR-10数据集的长度(即数据集中样本的数量)
from torchvision import datasets
data_path = "F:\\深度学习\\cifar-10-python.tar\\cifar-10-python"
cifar10 = datasets.CIFAR10(data_path, train=True, download=False)
cifar10_val = datasets.CIFAR10(data_path, train=False, download=False)
print(len(cifar10))
结果显示为50000,这个也符合CIFAR-10的训练集有5w张
那我们来查看数据集中的图片吧
from matplotlib import pyplot as plt
import numpy as np
import torch
# 自定义类别名称
class_names = ['airplane','automobile','bird','cat','deer',
'dog','frog','horse','ship','truck']
fig = plt.figure(figsize=(8,3))
num_classes = 10
for i in range(num_classes): # 遍历类别
# 添加子图
ax = fig.add_subplot(2, 5, 1 + i, xticks=[], yticks=[])
ax.set_title(class_names[i])
img = next(img for img, label in cifar10 if label == i)
plt.imshow(img)
plt.show()
当然我们也可以指定查看数据集中指定索引的图像,下面是示例代码
# 显示数据集中指定的图像
img, label = cifar10[618]
print(img, label, class_names[label])
plt.imshow(img)
plt.show()
我们选择了查看索引为618的图片
可以看到这张RGB PIL图像的大小为32 * 32,类别为cat
还有另一种方法效果和上述代码相同,这里就直接提供给大家
# 另一种方法
from torchvision import transforms
to_tensor = transforms.ToTensor()
img_t = to_tensor(img)
tensor_cifar10 = datasets.CIFAR10(data_path, train=True, download=False,
transform=transforms.ToTensor())
img_t, _ = tensor_cifar10[618]
plt.imshow(img_t.permute(1, 2, 0)) # <1>
plt.show()
数据归一化
归一化的过程可以概括为以下几个步骤:
-
计算均值和标准差:首先,需要计算数据集中所有图像的每个通道的均值和标准差。这通常是在整个训练集上进行的,以确保模型在训练期间和评估/测试期间看到的数据具有相同的分布。
-
减去均值:对于数据集中的每张图像,从其每个像素值中减去相应通道的均值。这一步的目的是将数据中心化到0,即确保每个通道的平均像素值为0。
-
除以标准差:然后,将上一步的结果除以相应通道的标准差。这一步的目的是将数据缩放到具有单位方差,即确保每个通道的像素值在其均值周围具有相同的波动范围。
-
可选:缩放范围:在某些情况下,可能希望将归一化后的像素值缩放到一个特定的范围(如[0, 1]),尽管
transforms.Normalize
本身并不直接提供这一功能。这可以通过简单的数学运算(如加0.5并乘以2)来实现,但请注意这样做会改变数据的分布,因此在大多数情况下,直接使用transforms.Normalize
输出的[-1, 1]范围可能更为合适。
归一化的好处包括:
- 加速收敛:通过将数据缩放到一个较小的范围,并使其具有零均值和单位方差,梯度下降等优化算法可以更快地收敛到最优解。
- 提高模型性能:归一化有助于减少模型对输入数据的尺度敏感性,从而提高模型的泛化能力。
- 数值稳定性:在某些情况下,如使用sigmoid或tanh激活函数时,归一化可以防止梯度消失或爆炸的问题。
imgs = torch.stack([img_t for img_t, _ in tensor_cifar10], dim=3)
print(imgs.view(3, -1).mean(dim=1)) # 计算出每个信道的平均值
print(imgs.view(3, -1).std(dim=1)) # 计算标准差
# 定义了一个transforms.Normalize对象,该对象用于对图像进行归一化处理
# 将图像中的每个像素值从其原始值减去均值,然后除以标准差
transforms.Normalize((0.4915, 0.4823, 0.4468), (0.2470, 0.2435, 0.2616))
transformed_cifar10 = datasets.CIFAR10(
data_path, train=True, download=False,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.4915, 0.4823, 0.4468),
(0.2470, 0.2435, 0.2616))
]))
img_t, _ = transformed_cifar10[99]
plt.imshow(img_t.permute(1, 2, 0))
plt.show()
这就是归一化后的图像