MNIST数据集 [LeCun et al., 1998] 是图像分类中广泛使用的数据集之一,但作为基准数据集过于简单。 我们将使用类似但更复杂的Fashion-MNIST数据集。
%matplotlib inline
import torch
import torchvision
from torch.utils import data
from torchvision import transforms
from d2l import torch as d2l
d2l.use_svg_display()
通过框架中的内置函数将Fashion-MNIST数据集下载并读取到内存中
# 通过ToTensor 实例将图像数据从PIL类型变换成32位浮点数格式
# 并除以255使得所有像素的数值均在0~1之间
trans = transforms.ToTensor() # 把图片转成pytorch的tensor,做一个简单的预处理
# 从torchvision.datasets中把FashionMNIST拿到,下载到上一级目录的data下面
# train = True 表示的是:下载的是训练数据集
# transform=trans 表示数据集拿出来之后,要得到的是pytorch的tensor,而不是一堆图片
# download=True 默认从网上下载,如果不方便的话,可以事先下载好存在data文件夹下面
mnist_train = torchvision.datasets.FashionMNIST(root="./data",train = True,
transform=trans,
download=True)
# 测试数据集,用来验证模型好坏的数据集,不参与训练
mnist_test = torchvision.datasets.FashionMNIST(root="./data",train=False,
transform=trans,download=True)
len(mnist_train),len(mnist_test)
下载成功会显示:
读取第一张图片:
# mnist_train[i][0]表示第i个样本的图片信息,mnist_train[i][1]表示第i个样本的标签值
mnist_train[0][0].shape # 第一张图片的形状,是一个黑白图片
# rgb的channel数=1,单通道,长和宽都是28
Fashion-MNIST中包含的10个类别,分别为t-shirt(T恤)、trouser(裤子)、pullover(套衫)、dress(连衣裙)、coat(外套)、sandal(凉鞋)、shirt(衬衫)、sneaker(运动鞋)、bag(包)和ankle boot(短靴)。 以下函数用于在数字标签索引及其文本名称之间进行转换。
def get_fashion_mnist_labels(labels):
'''返回Fashion-MNIST数据集的文本标签'''
text_labels = [
't-shirt','trouser','pullover','dress','coat','sandal',
'shirt', 'sneaker', 'bag', 'ankle boot']
return [text_balels[int(i)] for i in labels]
创建一个函数来可视化这些样本:
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5): #@save
"""绘制图像列表"""
# 设置图片大小
figsize = (num_cols * scale, num_rows * scale) # tuple类型
# _表示忽略不使用的变量,即fig
_, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
axes = axes.flatten()
for i, (ax, img) in enumerate(zip(axes, imgs)):
if torch.is_tensor(img):
# 图片张量
ax.imshow(img.numpy())
else:
# PIL图片
ax.imshow(img)
# 取消横纵坐标上的刻度
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
if titles:
# 设置标题
ax.set_title(titles[i])
return axes
以下是训练数据集中前几个样本的图像及其相应的标签.
# 通过DataLoader函数从训练数据集中拿到第一个小批量,批量大小为18的数据
X,y = next(iter(data.DataLoader(mnist_train,batch_size=18)))
show_images(X.reshape(18,28,28),2,9,titles=get_fashion_mnist_labels(y))
batch_size = 256
# 每一次读取数据不容易,需要使用多个进程来进行数据的读取,操作以及预读取
def get_dataloader_workers():
'''使用4个进程来读取的数据'''
return 4
train_iter = data.DataLoader(mnist_train,batch_size,shuffle = True,
num_workers = get_dataloader_workers())
timer = d2l.Timer() # 定义Timer函数来测试速度
for X,y in train_iter:
continue
f'{timer.stop():.2f} sec'
运行结果如下,可以看到扫一遍数据要4.25秒:
有时候会碰到模型训练很快,但是数据读不过来,通常来说,会在训练之前,去看一下数据读取多快。读取数据的时间至少要比训练要快一些。
把所有的之前的函数放在一个函数里面,使得之后能够重用。
定义load_data_fashion_mnist函数,用于获取和读取Fashion-MNIST数据集。 这个函数返回训练集和验证集的数据迭代器。 此外,这个函数还接受一个可选参数resize,用来将图像大小调整为另一种形状。
def load_data_fashion_mnist(batch_size, resize=None): #@save
"""下载Fashion-MNIST数据集,然后将其加载到内存中"""
trans = [transforms.ToTensor()]
if resize:
trans.insert(0, transforms.Resize(resize))
trans = transforms.Compose(trans)
mnist_train = torchvision.datasets.FashionMNIST(
root="../data", train=True, transform=trans, download=True)
mnist_test = torchvision.datasets.FashionMNIST(
root="../data", train=False, transform=trans, download=True)
return (data.DataLoader(mnist_train, batch_size, shuffle=True,
num_workers=get_dataloader_workers()),
data.DataLoader(mnist_test, batch_size, shuffle=False,
num_workers=get_dataloader_workers()))
下面,我们通过指定resize参数来测试load_data_fashion_mnist函数的图像大小调整功能:
train_iter, test_iter = load_data_fashion_mnist(32, resize=64)
for X, y in train_iter:
print(X.shape, X.dtype, y.shape, y.dtype)
break
现在已经准备好使用Fashion-MNIST数据集,便于下面的章节调用来评估各种分类算法。