专题链接:https://blog.csdn.net/qq_33345365/category_12591348.html
本教程翻译自微软教程:https://learn.microsoft.com/en-us/training/paths/pytorch-fundamentals/
初次编辑:2024/3/2;最后编辑:2024/3/2
本教程第一篇介绍pytorch基础和张量操作
这是本教程的第二篇,介绍以下内容:
- 数据集与数据加载器
- 归一化
另外本人还有pytorch CV相关的教程,见专题:
https://blog.csdn.net/qq_33345365/category_12578430.html
数据集与数据加载器 Datasets and Dataloaders
处理数据样本的代码可能会变得复杂且难以维护。通常希望数据集代码与模型训练代码解耦,以获得更好的可读性和模块化性。PyTorch提供了两个数据原语:torch.utils.data.DataLoader
和torch.utils.data.Dataset
,它们使您能够使用预加载的数据集以及您自己的数据。Dataset存储样本及其对应的标签,而DataLoader则在Dataset周围包装了一个可迭代对象,以便轻松访问样本。
PyTorch库提供了许多预加载的样本数据集(例如FashionMNIST),它们是torch.utils.data.Dataset
的子类,并实现了特定于特殊数据的功能。用于模型原型设计(prototyping)和基准测试(benchmark)的样本包括:
- 图像数据集
- 文本数据集
- 音频数据集
加载数据集
此处使用TorchVision来加载Fashion-MNIST数据集。Fashion-MNIST是Zalando的服装图像数据集,包含60,000个训练样本和10,000个测试样本。每个样本包括一个28×28的灰度图像和一个来自10个类别中的关联标签。
- 每个图像高度为28个像素,宽度为28个像素,总共有784个像素。
- 这10个类别告诉图像是什么类型,例如:T恤/上衣、裤子、套头衫、连衣裙、包、短靴等。
- 灰度像素的值介于0到255之间,用于衡量黑白图像的强度。强度值从白色到黑色递增。例如:白色的颜色值为0,而黑色的颜色值为255。
我们使用以下参数加载FashionMNIST数据集:
- root 是存储训练/测试数据的路径。
- train 指定训练或测试数据集。
- download=True 如果数据在
root
中不可用,则从互联网下载数据。 - transform 和
target_transform
指定特征和标签的转换。
加载训练和测试数据集的代码如下所示:
import torch
from torch.utils.data import Dataset
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda
import matplotlib.pyplot as plttraining_data = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor()
)test_data = datasets.FashionMNIST(root="data",train=False,download=True,transform=ToTensor()
)
数据集的迭代与可视化
可以像列表一样手动索引Datasets
: training_data[index]
。此处使用matplotlib对训练数据中的一些样本进行可视化。代码如下所示:
labels_map = {0: "T-Shirt",1: "Trouser",2: "Pullover",3: "Dress",4: "Coat",5: "Sandal",6: "Shirt",7: "Sneaker",8: "Bag",9: "Ankle Boot",
}
figure = plt.figure(figsize=(8, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):sample_idx = torch.randint(len(training_data), size=(1,)).item()img, label = training_data[sample_idx]figure.add_subplot(rows, cols, i)plt.title(labels_map[label])plt.axis("off")plt.imshow(img.squeeze(), cmap="gray")
plt.show()
得到如下图片:
使用数据加载器(DataLoaders)准备自定义数据
Dataset
逐个样本检索数据集的特征和标签。在训练模型时,通常希望以“minibatch”的形式传递样本,在每个周期重混洗(reshuffle)数据以减少模型过拟合,并使用Python的多进程加速数据检索。
在机器学习中,需要指定数据集中的特征和标签。**特征(Feature)**是输入,**标签(label)**是输出。我们训练特征,然后训练模型以预测标签。
- 特征是图像像素中的模式。
- 标签是10个类别类型:T恤,凉鞋,连衣裙等。
DataLoader
是一个可迭代对象,用简单的API抽象了这种复杂性。为了使用DataLoader,我们需要设置以下参数:
- data 用于训练模型的训练数据,以及用于评估模型的测试数据。
- batch size 每个批次要处理的记录数。
- shuffle 按索引随机抽取数据样本。
使用DataLoader
处理两个数据集的代码如下所示:
from torch.utils.data import DataLoadertrain_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)
使用DataLoader进行迭代
我们已将数据集加载到 DataLoader
中,现在可以根据需要迭代数据集。 下面的每次迭代都会返回一个批次的 train_features
和 train_labels
(分别包含 batch_size=64
个特征和标签)。由于我们指定了 shuffle=True
,在遍历完所有批次后,数据将被混洗(shuffle),以更精细地控制数据加载顺序。
展示图片和标签的代码如下所示:
# Display image and label.
train_features, train_labels = next(iter(train_dataloader))
print(f"Feature batch shape: {train_features.size()}")
print(f"Labels batch shape: {train_labels.size()}")
img = train_features[0].squeeze()
label = train_labels[0]
plt.imshow(img, cmap="gray")
plt.show()
label_name = list(labels_map.values())[label]
print(f"Label: {label_name}")
得到图片:
归一化
标准化是一种常见的数据预处理技术,用于对数据进行缩放或转换,以确保每个特征都有相等的学习贡献。例如,灰度图像中的每个像素的值都介于0和255之间,这些是特征。如果一个像素值为17,另一个像素为197,则像素重要性的分布将不均匀,因为较高的像素值会偏离学习。标准化改变了数据的范围,而不会扭曲其特征之间的区别。这种预处理是为了避免:
- 减少预测精度
- 模型学习困难
- 特征数据范围的不利分布
Transforms
数据并不总是以最终处理过的形式呈现,这种形式适合训练机器学习算法。可以使用transforms来操作数据,使其适合训练。
所有 TorchVision 数据集都有两个参数(transform
用于修改特征,target_transform
用于修改标签),这些参数接受包含转换逻辑的可调用对象。torchvision.transforms
模块提供了几种常用的转换。
FashionMNIST 的特征是 PIL 图像格式,标签是整数。 对于训练,需要将特征转换为归一化的张量,将标签转换为 one-hot 编码的张量。 为了进行这些转换,将使用 ToTensor
和 Lambda
。
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambdads = datasets.FashionMNIST(root="data",train=True,download=True,transform=ToTensor(),target_transform=Lambda(lambda y: torch.zeros(10, dtype=torch.float).scatter_(0, torch.tensor(y), value=1))
)
解释上述代码:
ToTensor()
ToTensor 将PIL图像或NumPy ndarray
转换为FloatTensor,并将图像的像素强度值缩放到范围 [0., 1.]内。
Lambda transforms
Lambda transforms 应用任何用户定义的lambda函数。在这里,我们定义了一个函数来将整数转换为一个one-hot编码的张量。它首先创建一个大小为10的零张量(数据集中标签的数量),然后调用scatter,根据标签y的索引为其分配值为1。也可以使用torch.nn.functional.one_hot
的方式来实现这一点。