3.5.1. 读取数据集
我们可以通过框架中的内置函数将Fashion-MNIST数据集下载并读取到内存中。
# 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式,
# 并除以255使得所有像素的数值均在0~1之间
trans = transforms.ToTensor()
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)
这段代码用于下载和加载Fashion-MNIST数据集,并进行数据预处理。
1. `trans = transforms.ToTensor()`:定义了一个数据预处理的操作,将数据转换为PyTorch中的张量(Tensor)格式。
2. `mnist_train = torchvision.datasets.FashionMNIST(root="../data", train=True, transform=trans, download=True)`:下载和加载Fashion-MNIST训练数据集。`root`表示数据集存储的根目录,`train=True`表示加载训练数据集,`transform=trans`表示对数据进行预处理,`download=True`表示如果数据集不存在,则自动下载。
3. `mnist_test = torchvision.datasets.FashionMNIST(root="../data", train=False, transform=trans, download=True)`:下载和加载Fashion-MNIST测试数据集。`train=False`表示加载测试数据集,其余参数同上。
综合起来,这段代码实现了下载和加载Fashion-MNIST数据集,并对数据进行了预处理,将其转换为PyTorch中的张量格式。其中,训练数据集和测试数据集分别通过`train=True`和`train=False`进行区分。
def get_fashion_mnist_labels(labels): #@save
"""返回Fashion-MNIST数据集的文本标签"""
text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
return [text_labels[int(i)] for i in labels]
定义了一个函数get_fashion_mnist_labels,它接受一个参数labels。该函数的作用是将Fashion-MNIST数据集的数值标签转换为对应的文本标签。
在函数内部,定义了一个名为text_labels的列表,其中包含了Fashion-MNIST数据集中的10个类别的文本标签,分别是:'t-shirt'、'trouser'、'pullover'、'dress'、'coat'、'sandal'、'shirt'、'sneaker'、'bag'和'ankle boot'。
接下来,使用列表推导式对labels进行遍历,将每个数值标签转换为对应的文本标签。具体地,通过int(i)将数值标签转换为整数类型,并使用该整数作为索引从text_labels列表中获取对应的文本标签。最后,将所有转换后的文本标签组成一个新的列表并返回。
总结起来,该函数的作用是将Fashion-MNIST数据集的数值标签转换为对应的文本标签,并返回转换后的文本标签列表。
def show_images(imgs, num_rows, num_cols, titles=None, scale=1.5): #@save
"""绘制图像列表"""
figsize = (num_cols * scale, num_rows * scale)
_, 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
定义了一个函数show_images,它接受一些参数:imgs表示图像列表,num_rows表示图像展示的行数,num_cols表示图像展示的列数,titles表示每个图像的标题(可选),scale表示图像的缩放比例(默认为1.5)。
在函数内部,首先根据num_rows和num_cols计算出图像展示区域的大小,并将其保存在变量figsize中。
接下来,使用d2l.plt.subplots(num_rows, num_cols, figsize=figsize)创建一个图像展示区域,返回的结果包括一个Figure对象和一个Axes对象的二维数组。将Axes对象的二维数组展平为一维,并将其保存在变量axes中。
然后,使用enumerate函数遍历axes和imgs,其中i表示索引,ax表示当前的Axes对象,img表示当前的图像。对于每个图像,首先判断它是否是一个torch张量,如果是,则将其转换为numpy数组并使用ax.imshow函数显示;如果不是,则直接使用ax.imshow函数显示。
接下来,使用ax.axes.get_xaxis().set_visible(False)和ax.axes.get_yaxis().set_visible(False)隐藏坐标轴。
最后,如果titles不为空,则使用ax.set_title函数设置当前图像的标题。
最后,返回保存图像展示区域的一维数组axes。
总结起来,该函数的作用是将给定的图像列表按照指定的行数和列数展示在图像展示区域中,并可选择性地添加图像的标题。
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));
首先,使用data.DataLoader(mnist_train, batch_size=18)创建一个数据加载器,每次从mnist_train中获取18个样本。
接下来,使用next(iter(...))从数据加载器中获取一个批次的数据,将其赋值给变量X和y。其中,X是一个形状为(18, 1, 28, 28)的张量,表示18张28x28的灰度图像;y是一个形状为(18,)的张量,表示18个图像的标签。
然后,调用show_images函数,将X.reshape(18, 28, 28)作为图像列表传入。这里使用reshape函数将X的形状从(18, 1, 28, 28)变为(18, 28, 28),以适应show_images函数的要求。
指定参数2表示图像展示的行数,9表示图像展示的列数。通过titles=get_fashion_mnist_labels(y)将图像的标签传入show_images函数,以显示每个图像的标签。
最后,通过分号表示该行代码的结束。
总结起来,这段代码的作用是从Fashion-MNIST训练集中获取一个批次的数据,然后将其中的18张图像按照2行9列的形式展示出来,并显示每个图像的标签。
batch_size = 256
def get_dataloader_workers(): #@save
"""使用4个进程来读取数据"""
return 4
train_iter = data.DataLoader(mnist_train, batch_size, shuffle=True,
num_workers=get_dataloader_workers())
首先,定义了一个变量batch_size,其值为256,表示每个批次的样本数量。
接下来,定义了一个函数get_dataloader_workers,该函数没有参数。函数的作用是返回一个整数值4,表示使用4个进程来读取数据。
然后,使用data.DataLoader函数创建一个数据加载器train_iter。该函数接受多个参数:mnist_train表示要加载的数据集,batch_size表示每个批次的样本数量,shuffle=True表示在每个epoch开始时对数据进行洗牌,num_workers=get_dataloader_workers()表示使用get_dataloader_workers函数返回的整数值作为读取数据的进程数。
总结起来,这段代码的作用是创建一个数据加载器train_iter,用于从Fashion-MNIST训练集中读取数据。每个批次的样本数量为256,并且在每个epoch开始时对数据进行洗牌。读取数据时使用4个进程。
timer = d2l.Timer()
for X, y in train_iter:
continue
f'{timer.stop():.2f} sec'
首先,创建了一个d2l.Timer对象,将其赋值给变量timer。这个Timer对象用于计时。
接下来,使用for循环遍历train_iter,每次迭代从train_iter中获取一个批次的数据,将其赋值给变量X和y。在这个例子中,由于循环体内没有执行任何操作,因此使用continue语句跳过当前迭代,直接进行下一次迭代。
然后,使用f-string格式化字符串的方式,将timer.stop()的结果保留两位小数,并添加单位"sec",将其赋值给字符串变量。timer.stop()用于停止计时,并返回经过的时间。
最后,通过分号表示该行代码的结束。
总结起来,这段代码的作用是使用一个for循环遍历train_iter,但在循环体内并没有执行任何操作,只是为了消耗掉整个数据集。然后,通过计时器timer计算整个循环所消耗的时间,并将结果格式化为字符串,保留两位小数,并添加单位"sec"。
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()))
首先,定义了一个函数load_data_fashion_mnist,该函数有两个参数:batch_size和resize(可选)。函数的作用是下载Fashion-MNIST数据集,并将其加载到内存中。
接下来,创建了一个列表trans,其中包含一个transforms.ToTensor()变换。transforms.ToTensor()用于将图像数据转换为张量形式。
然后,通过条件判断语句判断resize是否为真。如果resize为真,则在trans列表的第一个位置插入一个transforms.Resize(resize)变换。transforms.Resize(resize)用于将图像调整为指定的大小。
接着,使用transforms.Compose函数将trans列表中的所有变换组合成一个变换对象trans。transforms.Compose用于将多个变换组合在一起。
然后,使用torchvision.datasets.FashionMNIST函数创建了两个数据集对象:mnist_train和mnist_test。这两个数据集对象分别代表Fashion-MNIST的训练集和测试集。torchvision.datasets.FashionMNIST函数接受多个参数:root表示数据集的根目录,train=True表示加载训练集,train=False表示加载测试集,transform=trans表示应用之前定义的变换对象trans,download=True表示如果数据集不存在,则进行下载。
最后,使用data.DataLoader函数创建了两个数据加载器对象:一个用于训练集(mnist_train),一个用于测试集(mnist_test)。这两个数据加载器对象分别使用之前创建的数据集对象作为输入,batch_size表示每个批次的样本数量,shuffle=True表示在每个epoch开始时对数据进行洗牌,num_workers=get_dataloader_workers()表示使用之前定义的函数get_dataloader_workers返回的整数值作为读取数据的进程数。
最终,load_data_fashion_mnist函数返回了一个包含两个元素的元组,每个元素都是一个数据加载器对象。第一个元素是训练集的数据加载器,第二个元素是测试集的数据加载器。
总结起来,这段代码的作用是定义一个函数load_data_fashion_mnist,用于下载Fashion-MNIST数据集并加载到内存中。函数可以指定批次大小和图像大小的调整。返回一个包含训练集和测试集数据加载器的元组。