PyTorch 2.2 中文官方教程(一)(1)https://developer.aliyun.com/article/1482476
张量的属性
张量属性描述了它们的形状、数据类型和存储它们的设备。
tensor = torch.rand(3,4) print(f"Shape of tensor: {tensor.shape}") print(f"Datatype of tensor: {tensor.dtype}") print(f"Device tensor is stored on: {tensor.device}")
Shape of tensor: torch.Size([3, 4]) Datatype of tensor: torch.float32 Device tensor is stored on: cpu
张量上的操作
包括算术、线性代数、矩阵操作(转置、索引、切片)、采样等在内的 100 多个张量操作在这里得到了全面描述。
这些操作中的每一个都可以在 GPU 上运行(通常比在 CPU 上速度更快)。如果您在使用 Colab,请转到运行时 > 更改运行时类型 > GPU 来分配 GPU。
默认情况下,张量在 CPU 上创建。我们需要使用.to
方法显式将张量移动到 GPU(在检查 GPU 可用性后)。请记住,在设备之间复制大型张量可能会在时间和内存方面昂贵!
# We move our tensor to the GPU if available if torch.cuda.is_available(): tensor = tensor.to("cuda")
尝试运行列表中的一些操作。如果您熟悉 NumPy API,您会发现 Tensor API 非常易于使用。
标准类似于 numpy 的索引和切片:
tensor = torch.ones(4, 4) print(f"First row: {tensor[0]}") print(f"First column: {tensor[:, 0]}") print(f"Last column: {tensor[..., -1]}") tensor[:,1] = 0 print(tensor)
First row: tensor([1., 1., 1., 1.]) First column: tensor([1., 1., 1., 1.]) Last column: tensor([1., 1., 1., 1.]) tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
连接张量 您可以使用torch.cat
沿着给定维度连接一系列张量。另请参阅torch.stack,另一个微妙不同于torch.cat
的张量连接运算符。
t1 = torch.cat([tensor, tensor, tensor], dim=1) print(t1)
tensor([[1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.], [1., 0., 1., 1., 1., 0., 1., 1., 1., 0., 1., 1.]])
算术操作
# This computes the matrix multiplication between two tensors. y1, y2, y3 will have the same value # ``tensor.T`` returns the transpose of a tensor y1 = tensor @ tensor.T y2 = tensor.matmul(tensor.T) y3 = torch.rand_like(y1) torch.matmul(tensor, tensor.T, out=y3) # This computes the element-wise product. z1, z2, z3 will have the same value z1 = tensor * tensor z2 = tensor.mul(tensor) z3 = torch.rand_like(tensor) torch.mul(tensor, tensor, out=z3)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]])
单元素张量 如果您有一个单元素张量,例如通过将张量的所有值聚合为一个值,您可以使用item()
将其转换为 Python 数值:
agg = tensor.sum() agg_item = agg.item() print(agg_item, type(agg_item))
12.0 <class 'float'>
原地操作 将结果存储到操作数中的操作称为原地操作。它们以_
后缀表示。例如:x.copy_(y)
,x.t_()
,将改变x
。
print(f"{tensor} \n") tensor.add_(5) print(tensor)
tensor([[1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.], [1., 0., 1., 1.]]) tensor([[6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.], [6., 5., 6., 6.]])
注意
原地操作可以节省一些内存,但在计算导数时可能会出现问题,因为会立即丢失历史记录。因此,不建议使用它们。
与 NumPy 的桥接
CPU 上的张量和 NumPy 数组可以共享它们的基础内存位置,改变一个将改变另一个。
张量转换为 NumPy 数组
t = torch.ones(5) print(f"t: {t}") n = t.numpy() print(f"n: {n}")
t: tensor([1., 1., 1., 1., 1.]) n: [1\. 1\. 1\. 1\. 1.]
张量中的更改会反映在 NumPy 数组中。
t.add_(1) print(f"t: {t}") print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.]) n: [2\. 2\. 2\. 2\. 2.]
NumPy 数组转换为张量
n = np.ones(5) t = torch.from_numpy(n)
NumPy 数组中的更改会反映在张量中。
np.add(n, 1, out=n) print(f"t: {t}") print(f"n: {n}")
t: tensor([2., 2., 2., 2., 2.], dtype=torch.float64) n: [2\. 2\. 2\. 2\. 2.]
脚本的总运行时间:(0 分钟 2.013 秒)
下载 Python 源代码:tensorqs_tutorial.py
下载 Jupyter 笔记本:tensorqs_tutorial.ipynb
数据集和 DataLoaders
原文:
pytorch.org/tutorials/beginner/basics/data_tutorial.html
译者:飞龙
注意
点击这里下载完整示例代码
学习基础知识 || 快速入门 || 张量 || 数据集和 DataLoaders || 转换 || 构建模型 || 自动求导 || 优化 || 保存和加载模型
处理数据样本的代码可能会变得混乱且难以维护;我们理想情况下希望我们的数据集代码与模型训练代码解耦,以提高可读性和模块化性。PyTorch 提供了两个数据原语:torch.utils.data.DataLoader
和torch.utils.data.Dataset
,允许您使用预加载数据集以及您自己的数据。Dataset
存储样本及其对应的标签,DataLoader
将可迭代对象包装在Dataset
周围,以便轻松访问样本。
PyTorch 领域库提供了许多预加载数据集(如 FashionMNIST),它们是torch.utils.data.Dataset
的子类,并实现了特定于特定数据的函数。它们可用于原型设计和模型基准测试。您可以在这里找到它们:图像数据集、文本数据集和音频数据集
加载数据集
这里是如何从 TorchVision 加载Fashion-MNIST数据集的示例。Fashion-MNIST 是 Zalando 文章图像数据集,包括 60,000 个训练示例和 10,000 个测试示例。每个示例包括一个 28×28 的灰度图像和来自 10 个类别之一的相关标签。
我们使用以下参数加载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 import matplotlib.pyplot as plt training_data = datasets.FashionMNIST( root="data", train=True, download=True, transform=ToTensor() ) test_data = datasets.FashionMNIST( root="data", train=False, download=True, transform=ToTensor() )
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to data/FashionMNIST/raw/train-images-idx3-ubyte.gz 0%| | 0/26421880 [00:00<?, ?it/s] 0%| | 65536/26421880 [00:00<01:12, 365057.28it/s] 1%| | 229376/26421880 [00:00<00:37, 693381.35it/s] 2%|2 | 655360/26421880 [00:00<00:14, 1837266.59it/s] 6%|5 | 1507328/26421880 [00:00<00:07, 3214435.37it/s] 17%|#6 | 4489216/26421880 [00:00<00:02, 10348304.36it/s] 31%|### | 8126464/26421880 [00:00<00:01, 14655512.28it/s] 50%|####9 | 13107200/26421880 [00:00<00:00, 23379028.97it/s] 65%|######5 | 17235968/26421880 [00:01<00:00, 23640128.44it/s] 85%|########4 | 22347776/26421880 [00:01<00:00, 30209848.84it/s] 100%|#########9| 26312704/26421880 [00:01<00:00, 27567395.90it/s] 100%|##########| 26421880/26421880 [00:01<00:00, 18266988.23it/s] Extracting data/FashionMNIST/raw/train-images-idx3-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw/train-labels-idx1-ubyte.gz 0%| | 0/29515 [00:00<?, ?it/s] 100%|##########| 29515/29515 [00:00<00:00, 327415.67it/s] Extracting data/FashionMNIST/raw/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz 0%| | 0/4422102 [00:00<?, ?it/s] 1%|1 | 65536/4422102 [00:00<00:11, 364864.90it/s] 5%|5 | 229376/4422102 [00:00<00:06, 685739.55it/s] 21%|##1 | 950272/4422102 [00:00<00:01, 2200229.85it/s] 87%|########6 | 3833856/4422102 [00:00<00:00, 7656139.70it/s] 100%|##########| 4422102/4422102 [00:00<00:00, 6118794.98it/s] Extracting data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz 0%| | 0/5148 [00:00<?, ?it/s] 100%|##########| 5148/5148 [00:00<00:00, 41443909.77it/s] Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw • 41
迭代和可视化数据集
我们可以像列表一样手动索引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()
为您的文件创建自定义数据集
自定义数据集类必须实现三个函数:__init__
、__len__
和__getitem__
。看一下这个实现;FashionMNIST 图像存储在一个名为img_dir
的目录中,它们的标签单独存储在一个名为annotations_file
的 CSV 文件中。
在接下来的部分中,我们将分解每个函数中发生的情况。
import os import pandas as pd from torchvision.io import read_image class CustomImageDataset(Dataset): def __init__(self, annotations_file, img_dir, transform=None, target_transform=None): self.img_labels = pd.read_csv(annotations_file) self.img_dir = img_dir self.transform = transform self.target_transform = target_transform def __len__(self): return len(self.img_labels) def __getitem__(self, idx): img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0]) image = read_image(img_path) label = self.img_labels.iloc[idx, 1] if self.transform: image = self.transform(image) if self.target_transform: label = self.target_transform(label) return image, label
__init__
__init__
函数在实例化数据集对象时运行一次。我们初始化包含图像的目录、注释文件和两个转换(在下一节中详细介绍)。
标签.csv 文件如下:
tshirt1.jpg, 0 tshirt2.jpg, 0 ...... ankleboot999.jpg, 9
def __init__(self, annotations_file, img_dir, transform=None, target_transform=None): self.img_labels = pd.read_csv(annotations_file) self.img_dir = img_dir self.transform = transform self.target_transform = target_transform
__len__
__len__
函数返回数据集中样本的数量。
示例:
def __len__(self): return len(self.img_labels)
__getitem__
__getitem__
函数加载并返回给定索引idx
处数据集中的样本。根据索引,它确定磁盘上图像的位置,使用read_image
将其转换为张量,从self.img_labels
中的 csv 数据中检索相应的标签,对它们调用转换函数(如果适用),并以元组形式返回张量图像和相应标签。
def __getitem__(self, idx): img_path = os.path.join(self.img_dir, self.img_labels.iloc[idx, 0]) image = read_image(img_path) label = self.img_labels.iloc[idx, 1] if self.transform: image = self.transform(image) if self.target_transform: label = self.target_transform(label) return image, label
为使用 DataLoaders 准备数据
Dataset
以一次一个样本的方式检索我们数据集的特征和标签。在训练模型时,我们通常希望以“小批量”方式传递样本,每个时代重新洗牌数据以减少模型过拟合,并使用 Python 的multiprocessing
加速数据检索。
DataLoader
是一个可迭代对象,它在易用的 API 中为我们抽象了这种复杂性。
from torch.utils.data import DataLoader train_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
,在遍历所有批次后,数据会被洗牌(为了更精细地控制数据加载顺序,请查看Samplers)。
# 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() print(f"Label: {label}")
Feature batch shape: torch.Size([64, 1, 28, 28]) Labels batch shape: torch.Size([64]) Label: 5
进一步阅读
脚本的总运行时间:(0 分钟 5.632 秒)
下载 Python 源代码:data_tutorial.py
下载 Jupyter 笔记本:data_tutorial.ipynb
转换
原文:
pytorch.org/tutorials/beginner/basics/transforms_tutorial.html
译者:飞龙
注意
点击这里下载完整示例代码
学习基础知识 || 快速入门 || 张量 || 数据集和数据加载器 || 转换 || 构建模型 || 自动求导 || 优化 || 保存和加载模型
数据并不总是以训练机器学习算法所需的最终处理形式出现。我们使用转换对数据进行一些处理,使其适合训练。
所有 TorchVision 数据集都有两个参数-transform
用于修改特征和target_transform
用于修改标签-接受包含转换逻辑的可调用对象。torchvision.transforms模块提供了几种常用的转换。
FashionMNIST 的特征以 PIL 图像格式呈现,标签为整数。对于训练,我们需要将特征作为标准化张量,将标签作为独热编码张量。为了进行这些转换,我们使用ToTensor
和Lambda
。
import torch from torchvision import datasets from torchvision.transforms import ToTensor, Lambda ds = 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)) )
Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to data/FashionMNIST/raw/train-images-idx3-ubyte.gz 0%| | 0/26421880 [00:00<?, ?it/s] 0%| | 65536/26421880 [00:00<01:12, 365341.60it/s] 1%| | 229376/26421880 [00:00<00:38, 686586.92it/s] 3%|3 | 884736/26421880 [00:00<00:12, 2035271.39it/s] 10%|# | 2686976/26421880 [00:00<00:03, 6286060.82it/s] 21%|##1 | 5603328/26421880 [00:00<00:01, 10565098.33it/s] 36%|###5 | 9404416/26421880 [00:00<00:00, 17370347.01it/s] 54%|#####4 | 14319616/26421880 [00:01<00:00, 21721945.28it/s] 70%|######9 | 18382848/26421880 [00:01<00:00, 26260208.56it/s] 90%|########9 | 23724032/26421880 [00:01<00:00, 28093598.52it/s] 100%|##########| 26421880/26421880 [00:01<00:00, 19334744.02it/s] Extracting data/FashionMNIST/raw/train-images-idx3-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw/train-labels-idx1-ubyte.gz 0%| | 0/29515 [00:00<?, ?it/s] 100%|##########| 29515/29515 [00:00<00:00, 329165.55it/s] Extracting data/FashionMNIST/raw/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz 0%| | 0/4422102 [00:00<?, ?it/s] 1%|1 | 65536/4422102 [00:00<00:12, 361576.31it/s] 5%|5 | 229376/4422102 [00:00<00:06, 680517.35it/s] 21%|##1 | 950272/4422102 [00:00<00:01, 2183882.82it/s] 77%|#######7 | 3407872/4422102 [00:00<00:00, 6666873.55it/s] 100%|##########| 4422102/4422102 [00:00<00:00, 6066091.89it/s] Extracting data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz 0%| | 0/5148 [00:00<?, ?it/s] 100%|##########| 5148/5148 [00:00<00:00, 41523609.60it/s] Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw
ToTensor()
ToTensor将 PIL 图像或 NumPy ndarray
转换为FloatTensor
。并将图像的像素强度值缩放到范围[0., 1.]内。
Lambda 转换
Lambda 转换应用任何用户定义的 lambda 函数。在这里,我们定义一个函数将整数转换为一个独热编码的张量。它首先创建一个大小为 10 的零张量(数据集中标签的数量),然后调用scatter_,该函数根据标签y
给定的索引分配value=1
。
target_transform = Lambda(lambda y: torch.zeros( 10, dtype=torch.float).scatter_(dim=0, index=torch.tensor(y), value=1))
进一步阅读
脚本的总运行时间:(0 分钟 4.410 秒)
下载 Python 源代码:transforms_tutorial.py
下载 Jupyter 笔记本:transforms_tutorial.ipynb
PyTorch 2.2 中文官方教程(一)(3)https://developer.aliyun.com/article/1482479