PyTorch 2.2 中文官方教程(三)(1)

简介: PyTorch 2.2 中文官方教程(三)

使用 PyTorch 构建模型

原文:pytorch.org/tutorials/beginner/introyt/modelsyt_tutorial.html

译者:飞龙

协议:CC BY-NC-SA 4.0

注意

点击这里下载完整示例代码

介绍 || 张量 || 自动微分 || 构建模型 || TensorBoard 支持 || 训练模型 || 模型理解

跟随下面的视频或在youtube上观看。

www.youtube.com/embed/OSqIP-mOWOI

torch.nn.Moduletorch.nn.Parameter

在这个视频中,我们将讨论 PyTorch 为构建深度学习网络提供的一些工具。

除了Parameter,我们在这个视频中讨论的类都是torch.nn.Module的子类。这是 PyTorch 的基类,旨在封装特定于 PyTorch 模型及其组件的行为。

torch.nn.Module的一个重要行为是注册参数。如果特定的Module子类具有学习权重,这些权重被表示为torch.nn.Parameter的实例。Parameter类是torch.Tensor的子类,具有特殊行为,当它们被分配为Module的属性时,它们被添加到该模块的参数列表中。这些参数可以通过Module类上的parameters()方法访问。

作为一个简单的例子,这里是一个非常简单的模型,有两个线性层和一个激活函数。我们将创建一个实例,并要求它报告其参数:

import torch
class TinyModel(torch.nn.Module):
    def __init__(self):
        super(TinyModel, self).__init__()
        self.linear1 = torch.nn.Linear(100, 200)
        self.activation = torch.nn.ReLU()
        self.linear2 = torch.nn.Linear(200, 10)
        self.softmax = torch.nn.Softmax()
    def forward(self, x):
        x = self.linear1(x)
        x = self.activation(x)
        x = self.linear2(x)
        x = self.softmax(x)
        return x
tinymodel = TinyModel()
print('The model:')
print(tinymodel)
print('\n\nJust one layer:')
print(tinymodel.linear2)
print('\n\nModel params:')
for param in tinymodel.parameters():
    print(param)
print('\n\nLayer params:')
for param in tinymodel.linear2.parameters():
    print(param) 
The model:
TinyModel(
  (linear1): Linear(in_features=100, out_features=200, bias=True)
  (activation): ReLU()
  (linear2): Linear(in_features=200, out_features=10, bias=True)
  (softmax): Softmax(dim=None)
)
Just one layer:
Linear(in_features=200, out_features=10, bias=True)
Model params:
Parameter containing:
tensor([[ 0.0765,  0.0830, -0.0234,  ..., -0.0337, -0.0355, -0.0968],
        [-0.0573,  0.0250, -0.0132,  ..., -0.0060,  0.0240,  0.0280],
        [-0.0908, -0.0369,  0.0842,  ..., -0.0078, -0.0333, -0.0324],
        ...,
        [-0.0273, -0.0162, -0.0878,  ...,  0.0451,  0.0297, -0.0722],
        [ 0.0833, -0.0874, -0.0020,  ..., -0.0215,  0.0356,  0.0405],
        [-0.0637,  0.0190, -0.0571,  ..., -0.0874,  0.0176,  0.0712]],
       requires_grad=True)
Parameter containing:
tensor([ 0.0304, -0.0758, -0.0549, -0.0893, -0.0809, -0.0804, -0.0079, -0.0413,
        -0.0968,  0.0888,  0.0239, -0.0659, -0.0560, -0.0060,  0.0660, -0.0319,
        -0.0370,  0.0633, -0.0143, -0.0360,  0.0670, -0.0804,  0.0265, -0.0870,
         0.0039, -0.0174, -0.0680, -0.0531,  0.0643,  0.0794,  0.0209,  0.0419,
         0.0562, -0.0173, -0.0055,  0.0813,  0.0613, -0.0379,  0.0228,  0.0304,
        -0.0354,  0.0609, -0.0398,  0.0410,  0.0564, -0.0101, -0.0790, -0.0824,
        -0.0126,  0.0557,  0.0900,  0.0597,  0.0062, -0.0108,  0.0112, -0.0358,
        -0.0203,  0.0566, -0.0816, -0.0633, -0.0266, -0.0624, -0.0746,  0.0492,
         0.0450,  0.0530, -0.0706,  0.0308,  0.0533,  0.0202, -0.0469, -0.0448,
         0.0548,  0.0331,  0.0257, -0.0764, -0.0892,  0.0783,  0.0062,  0.0844,
        -0.0959, -0.0468, -0.0926,  0.0925,  0.0147,  0.0391,  0.0765,  0.0059,
         0.0216, -0.0724,  0.0108,  0.0701, -0.0147, -0.0693, -0.0517,  0.0029,
         0.0661,  0.0086, -0.0574,  0.0084, -0.0324,  0.0056,  0.0626, -0.0833,
        -0.0271, -0.0526,  0.0842, -0.0840, -0.0234, -0.0898, -0.0710, -0.0399,
         0.0183, -0.0883, -0.0102, -0.0545,  0.0706, -0.0646, -0.0841, -0.0095,
        -0.0823, -0.0385,  0.0327, -0.0810, -0.0404,  0.0570,  0.0740,  0.0829,
         0.0845,  0.0817, -0.0239, -0.0444, -0.0221,  0.0216,  0.0103, -0.0631,
         0.0831, -0.0273,  0.0756,  0.0022,  0.0407,  0.0072,  0.0374, -0.0608,
         0.0424, -0.0585,  0.0505, -0.0455,  0.0268, -0.0950, -0.0642,  0.0843,
         0.0760, -0.0889, -0.0617, -0.0916,  0.0102, -0.0269, -0.0011,  0.0318,
         0.0278, -0.0160,  0.0159, -0.0817,  0.0768, -0.0876, -0.0524, -0.0332,
        -0.0583,  0.0053,  0.0503, -0.0342, -0.0319, -0.0562,  0.0376, -0.0696,
         0.0735,  0.0222, -0.0775, -0.0072,  0.0294,  0.0994, -0.0355, -0.0809,
        -0.0539,  0.0245,  0.0670,  0.0032,  0.0891, -0.0694, -0.0994,  0.0126,
         0.0629,  0.0936,  0.0058, -0.0073,  0.0498,  0.0616, -0.0912, -0.0490],
       requires_grad=True)
Parameter containing:
tensor([[ 0.0504, -0.0203, -0.0573,  ...,  0.0253,  0.0642, -0.0088],
        [-0.0078, -0.0608, -0.0626,  ..., -0.0350, -0.0028, -0.0634],
        [-0.0317, -0.0202, -0.0593,  ..., -0.0280,  0.0571, -0.0114],
        ...,
        [ 0.0582, -0.0471, -0.0236,  ...,  0.0273,  0.0673,  0.0555],
        [ 0.0258, -0.0706,  0.0315,  ..., -0.0663, -0.0133,  0.0078],
        [-0.0062,  0.0544, -0.0280,  ..., -0.0303, -0.0326, -0.0462]],
       requires_grad=True)
Parameter containing:
tensor([ 0.0385, -0.0116,  0.0703,  0.0407, -0.0346, -0.0178,  0.0308, -0.0502,
         0.0616,  0.0114], requires_grad=True)
Layer params:
Parameter containing:
tensor([[ 0.0504, -0.0203, -0.0573,  ...,  0.0253,  0.0642, -0.0088],
        [-0.0078, -0.0608, -0.0626,  ..., -0.0350, -0.0028, -0.0634],
        [-0.0317, -0.0202, -0.0593,  ..., -0.0280,  0.0571, -0.0114],
        ...,
        [ 0.0582, -0.0471, -0.0236,  ...,  0.0273,  0.0673,  0.0555],
        [ 0.0258, -0.0706,  0.0315,  ..., -0.0663, -0.0133,  0.0078],
        [-0.0062,  0.0544, -0.0280,  ..., -0.0303, -0.0326, -0.0462]],
       requires_grad=True)
Parameter containing:
tensor([ 0.0385, -0.0116,  0.0703,  0.0407, -0.0346, -0.0178,  0.0308, -0.0502,
         0.0616,  0.0114], requires_grad=True) 

这显示了 PyTorch 模型的基本结构:有一个__init__()方法定义了模型的层和其他组件,还有一个forward()方法用于执行计算。注意我们可以打印模型或其子模块来了解其结构。

常见的层类型

线性层

最基本的神经网络层类型是线性全连接层。这是一个每个输入都影响层的每个输出的程度由层的权重指定的层。如果一个模型有m个输入和n个输出,权重将是一个m x n矩阵。例如:

lin = torch.nn.Linear(3, 2)
x = torch.rand(1, 3)
print('Input:')
print(x)
print('\n\nWeight and Bias parameters:')
for param in lin.parameters():
    print(param)
y = lin(x)
print('\n\nOutput:')
print(y) 
Input:
tensor([[0.8790, 0.9774, 0.2547]])
Weight and Bias parameters:
Parameter containing:
tensor([[ 0.1656,  0.4969, -0.4972],
        [-0.2035, -0.2579, -0.3780]], requires_grad=True)
Parameter containing:
tensor([0.3768, 0.3781], requires_grad=True)
Output:
tensor([[ 0.8814, -0.1492]], grad_fn=<AddmmBackward0>) 

如果对x进行矩阵乘法,乘以线性层的权重,并加上偏置,你会发现得到输出向量y

还有一个重要的特点需要注意:当我们用lin.weight检查层的权重时,它报告自己是一个Parameter(它是Tensor的子类),并告诉我们它正在使用 autograd 跟踪梯度。这是Parameter的默认行为,与Tensor不同。

线性层在深度学习模型中被广泛使用。你最常见到它们的地方之一是在分类器模型中,通常在末尾会有一个或多个线性层,最后一层将有n个输出,其中n是分类器处理的类的数量。

卷积层

卷积层被设计用于处理具有高度空间相关性的数据。它们在计算机视觉中非常常见,用于检测特征的紧密组合,然后将其组合成更高级的特征。它们也出现在其他上下文中 - 例如,在 NLP 应用中,一个词的即时上下文(即,序列中附近的其他词)可以影响句子的含义。

我们在早期的视频中看到了 LeNet5 中卷积层的作用:

import torch.functional as F
class LeNet(torch.nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        # 1 input image channel (black & white), 6 output channels, 5x5 square convolution
        # kernel
        self.conv1 = torch.nn.Conv2d(1, 6, 5)
        self.conv2 = torch.nn.Conv2d(6, 16, 3)
        # an affine operation: y = Wx + b
        self.fc1 = torch.nn.Linear(16 * 6 * 6, 120)  # 6*6 from image dimension
        self.fc2 = torch.nn.Linear(120, 84)
        self.fc3 = torch.nn.Linear(84, 10)
    def forward(self, x):
        # Max pooling over a (2, 2) window
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # If the size is a square you can only specify a single number
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = x.view(-1, self.num_flat_features(x))
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
    def num_flat_features(self, x):
        size = x.size()[1:]  # all dimensions except the batch dimension
        num_features = 1
        for s in size:
            num_features *= s
        return num_features 

让我们分解一下这个模型的卷积层中发生的事情。从conv1开始:

  • LeNet5 旨在接收 1x32x32 的黑白图像。**卷积层构造函数的第一个参数是输入通道的数量。**这里是 1。如果我们构建这个模型来查看 3 色通道,那么它将是 3。
  • 卷积层就像一个窗口,扫描图像,寻找它认识的模式。这些模式称为特征,卷积层的一个参数是我们希望它学习的特征数量。**构造函数的第二个参数是输出特征的数量。**在这里,我们要求我们的层学习 6 个特征。
  • 在上面,我将卷积层比作一个窗口 - 但窗口有多大呢?**第三个参数是窗口或内核大小。**在这里,“5”表示我们选择了一个 5x5 的内核。(如果您想要高度与宽度不同的内核,可以为此参数指定一个元组 - 例如,(3, 5)以获得一个 3x5 的卷积内核。)

卷积层的输出是一个激活图 - 表示输入张量中特征存在的空间表示。conv1将给我们一个 6x28x28 的输出张量;6 是特征的数量,28 是我们地图的高度和宽度。(28 来自于在 32 像素行上扫描 5 像素窗口时,只有 28 个有效位置的事实。)

然后我们通过 ReLU 激活函数(稍后会详细介绍激活函数)将卷积的输出传递,然后通过一个最大池化层。最大池化层将激活图中相邻的特征组合在一起。它通过减少张量,将输出中的每个 2x2 组合的单元格合并为一个单元格,并将该单元格分配为其中输入的 4 个单元格的最大值。这给我们一个激活图的低分辨率版本,尺寸为 6x14x14。

我们的下一个卷积层conv2期望 6 个输入通道(对应于第一层寻找的 6 个特征),有 16 个输出通道和一个 3x3 的内核。它输出一个 16x12x12 的激活图,然后再通过最大池化层减少到 16x6x6。在将此输出传递给线性层之前,它被重新塑造为一个 16 * 6 * 6 = 576 元素的向量,以供下一层使用。

有用于处理 1D、2D 和 3D 张量的卷积层。卷积层构造函数还有许多可选参数,包括步长(例如,仅扫描每第二个或第三个位置)在输入中,填充(这样您可以扫描到输入的边缘)等。有关更多信息,请参阅文档

循环层

循环神经网络(或RNNs)用于顺序数据 - 从科学仪器的时间序列测量到自然语言句子到 DNA 核苷酸。RNN 通过保持作为其迄今为止在序列中看到的记忆的隐藏状态来实现这一点。

RNN 层的内部结构 - 或其变体,LSTM(长短期记忆)和 GRU(门控循环单元) - 是适度复杂的,超出了本视频的范围,但我们将通过一个基于 LSTM 的词性标注器来展示其工作原理(一种告诉你一个词是名词、动词等的分类器):

class LSTMTagger(torch.nn.Module):
    def __init__(self, embedding_dim, hidden_dim, vocab_size, tagset_size):
        super(LSTMTagger, self).__init__()
        self.hidden_dim = hidden_dim
        self.word_embeddings = torch.nn.Embedding(vocab_size, embedding_dim)
        # The LSTM takes word embeddings as inputs, and outputs hidden states
        # with dimensionality hidden_dim.
        self.lstm = torch.nn.LSTM(embedding_dim, hidden_dim)
        # The linear layer that maps from hidden state space to tag space
        self.hidden2tag = torch.nn.Linear(hidden_dim, tagset_size)
    def forward(self, sentence):
        embeds = self.word_embeddings(sentence)
        lstm_out, _ = self.lstm(embeds.view(len(sentence), 1, -1))
        tag_space = self.hidden2tag(lstm_out.view(len(sentence), -1))
        tag_scores = F.log_softmax(tag_space, dim=1)
        return tag_scores 

构造函数有四个参数:

  • vocab_size是输入词汇表中单词的数量。每个单词是一个在vocab_size维空间中的单热向量(或单位向量)。
  • tagset_size是输出集合中标签的数量。
  • embedding_dim是词汇表的嵌入空间的大小。嵌入将词汇表映射到一个低维空间,其中具有相似含义的单词在空间中靠在一起。
  • hidden_dim是 LSTM 的记忆大小。

输入将是一个句子,其中单词表示为单热向量的索引。嵌入层将把这些映射到一个embedding_dim维空间。LSTM 接受这些嵌入的序列并对其进行迭代,生成一个长度为hidden_dim的输出向量。最终的线性层充当分类器;将log_softmax()应用于最终层的输出将输出转换为给定单词映射到给定标签的估计概率的归一化集。

如果您想看到这个网络的运行情况,请查看 pytorch.org 上的序列模型和 LSTM 网络教程。

变压器

变压器是多功能网络,已经在 NLP 领域的最新技术中占据主导地位,如 BERT 模型。变压器架构的讨论超出了本视频的范围,但 PyTorch 有一个Transformer类,允许您定义变压器模型的整体参数 - 注意头的数量,编码器和解码器层数的数量,dropout 和激活函数等(您甚至可以根据正确的参数从这个单一类构建 BERT 模型!)。torch.nn.Transformer类还有类来封装各个组件(TransformerEncoderTransformerDecoder)和子组件(TransformerEncoderLayerTransformerDecoderLayer)。有关详细信息,请查看 pytorch.org 上有关变压器类的文档,以及有关 pytorch.org 上相关的教程

其他层和函数

数据操作层

还有其他层类型在模型中执行重要功能,但本身不参与学习过程。

最大池化(以及它的孪生,最小池化)通过组合单元格并将输入单元格的最大值分配给输出单元格来减少张量(我们看到了这一点)。例如:

my_tensor = torch.rand(1, 6, 6)
print(my_tensor)
maxpool_layer = torch.nn.MaxPool2d(3)
print(maxpool_layer(my_tensor)) 
tensor([[[0.5036, 0.6285, 0.3460, 0.7817, 0.9876, 0.0074],
         [0.3969, 0.7950, 0.1449, 0.4110, 0.8216, 0.6235],
         [0.2347, 0.3741, 0.4997, 0.9737, 0.1741, 0.4616],
         [0.3962, 0.9970, 0.8778, 0.4292, 0.2772, 0.9926],
         [0.4406, 0.3624, 0.8960, 0.6484, 0.5544, 0.9501],
         [0.2489, 0.8971, 0.7499, 0.1803, 0.9571, 0.6733]]])
tensor([[[0.7950, 0.9876],
         [0.9970, 0.9926]]]) 

如果您仔细查看上面的数值,您会发现 maxpooled 输出中的每个值都是 6x6 输入的每个象限的最大值。

归一化层在将一个层的输出重新居中和归一化之前将其馈送到另一个层。对中间张量进行居中和缩放具有许多有益的效果,例如让您在不爆炸/消失梯度的情况下使用更高的学习速率。

my_tensor = torch.rand(1, 4, 4) * 20 + 5
print(my_tensor)
print(my_tensor.mean())
norm_layer = torch.nn.BatchNorm1d(4)
normed_tensor = norm_layer(my_tensor)
print(normed_tensor)
print(normed_tensor.mean()) 
tensor([[[ 7.7375, 23.5649,  6.8452, 16.3517],
         [19.5792, 20.3254,  6.1930, 23.7576],
         [23.7554, 20.8565, 18.4241,  8.5742],
         [22.5100, 15.6154, 13.5698, 11.8411]]])
tensor(16.2188)
tensor([[[-0.8614,  1.4543, -0.9919,  0.3990],
         [ 0.3160,  0.4274, -1.6834,  0.9400],
         [ 1.0256,  0.5176,  0.0914, -1.6346],
         [ 1.6352, -0.0663, -0.5711, -0.9978]]],
       grad_fn=<NativeBatchNormBackward0>)
tensor(3.3528e-08, grad_fn=<MeanBackward0>) 

运行上面的单元格,我们向输入张量添加了一个大的缩放因子和偏移量;您应该看到输入张量的mean()大约在 15 的附近。通过归一化层后,您会看到值变小,并围绕零分组 - 实际上,均值应该非常小(> 1e-8)。

这是有益的,因为许多激活函数(下面讨论)在 0 附近具有最强的梯度,但有时会因为输入将它们远离零而出现消失或爆炸梯度。保持数据围绕梯度最陡峭的区域将倾向于意味着更快、更好的学习和更高的可行学习速度。

Dropout 层是鼓励模型中稀疏表示的工具 - 也就是说,推动它使用更少的数据进行推理。

Dropout 层通过在训练期间随机设置输入张量的部分来工作 - 推断时始终关闭 dropout 层。这迫使模型学习针对这个掩码或减少的数据集。例如:

my_tensor = torch.rand(1, 4, 4)
dropout = torch.nn.Dropout(p=0.4)
print(dropout(my_tensor))
print(dropout(my_tensor)) 
tensor([[[0.8869, 0.6595, 0.2098, 0.0000],
         [0.5379, 0.0000, 0.0000, 0.0000],
         [0.1950, 0.2424, 1.3319, 0.5738],
         [0.5676, 0.8335, 0.0000, 0.2928]]])
tensor([[[0.8869, 0.6595, 0.2098, 0.2878],
         [0.5379, 0.0000, 0.4029, 0.0000],
         [0.0000, 0.2424, 1.3319, 0.5738],
         [0.0000, 0.8335, 0.9647, 0.0000]]]) 

在上面,您可以看到对样本张量的 dropout 效果。您可以使用可选的p参数设置单个权重丢失的概率;如果不设置,默认为 0.5。

激活函数

激活函数使深度学习成为可能。神经网络实际上是一个程序 - 具有许多参数 - 模拟数学函数。如果我们只是重复地将张量乘以层权重,我们只能模拟线性函数;此外,拥有许多层也没有意义,因为整个网络可以简化为单个矩阵乘法。在层之间插入非线性激活函数是让深度学习模型能够模拟任何函数,而不仅仅是线性函数的关键。

torch.nn.Module 包含了封装所有主要激活函数的对象,包括 ReLU 及其许多变体,Tanh,Hardtanh,sigmoid 等。它还包括其他函数,如 Softmax,在模型的输出阶段最有用。

损失函数

损失函数告诉我们模型的预测与正确答案之间有多远。PyTorch 包含各种损失函数,包括常见的 MSE(均方误差 = L2 范数),交叉熵损失和负对数似然损失(对分类器有用),以及其他函数。

脚本的总运行时间:(0 分钟 0.029 秒)

下载 Python 源代码:modelsyt_tutorial.py

下载 Jupyter 笔记本:modelsyt_tutorial.ipynb

Sphinx-Gallery 生成的图库

PyTorch TensorBoard 支持

原文:pytorch.org/tutorials/beginner/introyt/tensorboardyt_tutorial.html

译者:飞龙

协议:CC BY-NC-SA 4.0

注意

点击这里下载完整示例代码

介绍 || 张量 || 自动微分 || 构建模型 || TensorBoard 支持 || 训练模型 || 模型理解

请跟随下面的视频或youtube

www.youtube.com/embed/6CEld3hZgqc

开始之前

要运行此教程,您需要安装 PyTorch、TorchVision、Matplotlib 和 TensorBoard。

使用conda

conda  install  pytorch  torchvision  -c  pytorch
conda  install  matplotlib  tensorboard 

使用pip

pip  install  torch  torchvision  matplotlib  tensorboard 

安装完依赖项后,在安装它们的 Python 环境中重新启动此笔记本。

介绍

在本笔记本中,我们将针对时尚-MNIST 数据集训练 LeNet-5 的变体。时尚-MNIST 是一组图像瓷砖,描绘了各种服装,有十个类标签表示所描绘的服装类型。

# PyTorch model and training necessities
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# Image datasets and image manipulation
import torchvision
import torchvision.transforms as transforms
# Image display
import matplotlib.pyplot as plt
import numpy as np
# PyTorch TensorBoard support
from torch.utils.tensorboard import SummaryWriter
# In case you are using an environment that has TensorFlow installed,
# such as Google Colab, uncomment the following code to avoid
# a bug with saving embeddings to your TensorBoard directory
# import tensorflow as tf
# import tensorboard as tb
# tf.io.gfile = tb.compat.tensorflow_stub.io.gfile 

在 TensorBoard 中显示图像

让我们从我们的数据集中向 TensorBoard 添加样本图像:

# Gather datasets and prepare them for consumption
transform = transforms.Compose(
    [transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))])
# Store separate training and validations splits in ./data
training_set = torchvision.datasets.FashionMNIST('./data',
    download=True,
    train=True,
    transform=transform)
validation_set = torchvision.datasets.FashionMNIST('./data',
    download=True,
    train=False,
    transform=transform)
training_loader = torch.utils.data.DataLoader(training_set,
                                              batch_size=4,
                                              shuffle=True,
                                              num_workers=2)
validation_loader = torch.utils.data.DataLoader(validation_set,
                                                batch_size=4,
                                                shuffle=False,
                                                num_workers=2)
# Class labels
classes = ('T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
        'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle Boot')
# Helper function for inline image display
def matplotlib_imshow(img, one_channel=False):
    if one_channel:
        img = img.mean(dim=0)
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    if one_channel:
        plt.imshow(npimg, cmap="Greys")
    else:
        plt.imshow(np.transpose(npimg, (1, 2, 0)))
# Extract a batch of 4 images
dataiter = iter(training_loader)
images, labels = next(dataiter)
# Create a grid from the images and show them
img_grid = torchvision.utils.make_grid(images)
matplotlib_imshow(img_grid, one_channel=True) 

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:09, 378414.86it/s]
  1%|          | 229376/26421880 [00:00<00:37, 693250.36it/s]
  4%|3         | 950272/26421880 [00:00<00:11, 2219214.26it/s]
 15%|#4        | 3833856/26421880 [00:00<00:02, 7688687.97it/s]
 35%|###5      | 9273344/26421880 [00:00<00:01, 15802443.73it/s]
 58%|#####7    | 15204352/26421880 [00:01<00:00, 21640902.59it/s]
 80%|#######9  | 21102592/26421880 [00:01<00:00, 25246743.30it/s]
100%|##########| 26421880/26421880 [00:01<00:00, 19515987.25it/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, 329627.44it/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, 363060.61it/s]
  5%|5         | 229376/4422102 [00:00<00:06, 683092.95it/s]
 19%|#8        | 819200/4422102 [00:00<00:01, 1861301.92it/s]
 64%|######4   | 2850816/4422102 [00:00<00:00, 5548383.23it/s]
100%|##########| 4422102/4422102 [00:00<00:00, 6080037.27it/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, 39618856.87it/s]
Extracting ./data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to ./data/FashionMNIST/raw 

以上,我们使用 TorchVision 和 Matplotlib 创建了一个输入数据小批量的可视网格。下面,我们使用SummaryWriter上的add_image()调用来记录图像以供 TensorBoard 使用,并调用flush()确保它立即写入磁盘。

# Default log_dir argument is "runs" - but it's good to be specific
# torch.utils.tensorboard.SummaryWriter is imported above
writer = SummaryWriter('runs/fashion_mnist_experiment_1')
# Write image data to TensorBoard log dir
writer.add_image('Four Fashion-MNIST Images', img_grid)
writer.flush()
# To view, start TensorBoard on the command line with:
#   tensorboard --logdir=runs
# ...and open a browser tab to http://localhost:6006/ 

如果您在命令行启动 TensorBoard 并在新的浏览器选项卡中打开它(通常在 localhost:6006),您应该在 IMAGES 选项卡下看到图像网格。

绘制标量以可视化训练

TensorBoard 对于跟踪训练的进展和有效性非常有用。在下面,我们将运行一个训练循环,跟踪一些指标,并保存数据供 TensorBoard 使用。

让我们定义一个模型来对我们的图像瓷砖进行分类,以及用于训练的优化器和损失函数:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 4 * 4, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)
    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 4 * 4)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
net = Net()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) 

现在让我们训练一个 epoch,并在每 1000 批次时评估训练与验证集的损失:

print(len(validation_loader))
for epoch in range(1):  # loop over the dataset multiple times
    running_loss = 0.0
    for i, data in enumerate(training_loader, 0):
        # basic training loop
        inputs, labels = data
        optimizer.zero_grad()
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        if i % 1000 == 999:    # Every 1000 mini-batches...
            print('Batch {}'.format(i + 1))
            # Check against the validation set
            running_vloss = 0.0
            # In evaluation mode some model specific operations can be omitted eg. dropout layer
            net.train(False) # Switching to evaluation mode, eg. turning off regularisation
            for j, vdata in enumerate(validation_loader, 0):
                vinputs, vlabels = vdata
                voutputs = net(vinputs)
                vloss = criterion(voutputs, vlabels)
                running_vloss += vloss.item()
            net.train(True) # Switching back to training mode, eg. turning on regularisation
            avg_loss = running_loss / 1000
            avg_vloss = running_vloss / len(validation_loader)
            # Log the running loss averaged per batch
            writer.add_scalars('Training vs. Validation Loss',
                            { 'Training' : avg_loss, 'Validation' : avg_vloss },
                            epoch * len(training_loader) + i)
            running_loss = 0.0
print('Finished Training')
writer.flush() 
2500
Batch 1000
Batch 2000
Batch 3000
Batch 4000
Batch 5000
Batch 6000
Batch 7000
Batch 8000
Batch 9000
Batch 10000
Batch 11000
Batch 12000
Batch 13000
Batch 14000
Batch 15000
Finished Training 

切换到您打开的 TensorBoard,并查看 SCALARS 选项卡。

可视化您的模型

TensorBoard 还可以用于检查模型内部的数据流。为此,请使用模型和样本输入调用add_graph()方法。当您打开

# Again, grab a single mini-batch of images
dataiter = iter(training_loader)
images, labels = next(dataiter)
# add_graph() will trace the sample input through your model,
# and render it as a graph.
writer.add_graph(net, images)
writer.flush() 

当您切换到 TensorBoard 时,您应该看到一个 GRAPHS 选项卡。双击“NET”节点以查看模型内部的层和数据流。

使用嵌入可视化您的数据集

我们使用的 28x28 图像瓷砖可以建模为 784 维向量(28 * 28 = 784)。将其投影到较低维度表示可能很有启发性。add_embedding()方法将一组数据投影到具有最高方差的三个维度,并将它们显示为交互式 3D 图表。add_embedding()方法通过自动投影到具有最高方差的三个维度来实现这一点。

接下来,我们将取一部分数据,并生成这样一个嵌入:

# Select a random subset of data and corresponding labels
def select_n_random(data, labels, n=100):
    assert len(data) == len(labels)
    perm = torch.randperm(len(data))
    return data[perm][:n], labels[perm][:n]
# Extract a random subset of data
images, labels = select_n_random(training_set.data, training_set.targets)
# get the class labels for each image
class_labels = [classes[label] for label in labels]
# log embeddings
features = images.view(-1, 28 * 28)
writer.add_embedding(features,
                    metadata=class_labels,
                    label_img=images.unsqueeze(1))
writer.flush()
writer.close() 

现在,如果您切换到 TensorBoard 并选择 PROJECTOR 选项卡,您应该看到投影的 3D 表示。您可以旋转和缩放模型。在大尺度和小尺度上检查它,并查看是否可以在投影数据和标签的聚类中发现模式。

为了更好地可见,建议:

  • 从左侧的“按颜色分类”下拉菜单中选择“标签”。
  • 在顶部切换到夜间模式图标,将浅色图像放在黑色背景上。

其他资源

有关更多信息,请查看:

脚本的总运行时间:(2 分钟 34.092 秒)

下载 Python 源代码:tensorboardyt_tutorial.py

下载 Jupyter 笔记本:tensorboardyt_tutorial.ipynb

Sphinx-Gallery 生成的画廊

使用 PyTorch 进行训练

原文:pytorch.org/tutorials/beginner/introyt/trainingyt.html

译者:飞龙

协议:CC BY-NC-SA 4.0

注意

点击这里下载完整示例代码

介绍 || 张量 || 自动微分 || 构建模型 || TensorBoard 支持 || 训练模型 || 模型理解

跟随下面的视频或者在youtube上进行操作。

www.youtube.com/embed/jF43_wj_DCQ

介绍

在过去的视频中,我们已经讨论并演示了:

  • 使用 torch.nn 模块的神经网络层和函数构建模型
  • 自动梯度计算的机制是基于梯度的模型训练的核心
  • 使用 TensorBoard 来可视化训练进度和其他活动

在这个视频中,我们将为您的工具库添加一些新工具:

  • 我们将熟悉数据集和数据加载器的抽象,以及它们如何简化在训练循环中向模型提供数据的过程
  • 我们将讨论具体的损失函数以及何时使用它们
  • 我们将研究 PyTorch 优化器,它们实现了根据损失函数的结果调整模型权重的算法。

最后,我们将把所有这些内容整合在一起,看到完整的 PyTorch 训练循环的运行。


PyTorch 2.2 中文官方教程(三)(2)https://developer.aliyun.com/article/1482488

相关文章
|
2月前
|
存储 物联网 PyTorch
基于PyTorch的大语言模型微调指南:Torchtune完整教程与代码示例
**Torchtune**是由PyTorch团队开发的一个专门用于LLM微调的库。它旨在简化LLM的微调流程,提供了一系列高级API和预置的最佳实践
194 59
基于PyTorch的大语言模型微调指南:Torchtune完整教程与代码示例
|
2月前
|
并行计算 监控 搜索推荐
使用 PyTorch-BigGraph 构建和部署大规模图嵌入的完整教程
当处理大规模图数据时,复杂性难以避免。PyTorch-BigGraph (PBG) 是一款专为此设计的工具,能够高效处理数十亿节点和边的图数据。PBG通过多GPU或节点无缝扩展,利用高效的分区技术,生成准确的嵌入表示,适用于社交网络、推荐系统和知识图谱等领域。本文详细介绍PBG的设置、训练和优化方法,涵盖环境配置、数据准备、模型训练、性能优化和实际应用案例,帮助读者高效处理大规模图数据。
61 5
|
5月前
|
并行计算 Ubuntu PyTorch
Ubuntu下CUDA、Conda、Pytorch联合教程
本文是一份Ubuntu系统下安装和配置CUDA、Conda和Pytorch的教程,涵盖了查看显卡驱动、下载安装CUDA、添加环境变量、卸载CUDA、Anaconda的下载安装、环境管理以及Pytorch的安装和验证等步骤。
892 1
Ubuntu下CUDA、Conda、Pytorch联合教程
|
8月前
|
PyTorch 算法框架/工具 异构计算
PyTorch 2.2 中文官方教程(十九)(1)
PyTorch 2.2 中文官方教程(十九)
150 1
PyTorch 2.2 中文官方教程(十九)(1)
|
8月前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch 2.2 中文官方教程(十八)(4)
PyTorch 2.2 中文官方教程(十八)
125 1
|
8月前
|
PyTorch 算法框架/工具 异构计算
PyTorch 2.2 中文官方教程(二十)(4)
PyTorch 2.2 中文官方教程(二十)
147 0
PyTorch 2.2 中文官方教程(二十)(4)
|
8月前
|
Android开发 PyTorch 算法框架/工具
PyTorch 2.2 中文官方教程(二十)(2)
PyTorch 2.2 中文官方教程(二十)
123 0
PyTorch 2.2 中文官方教程(二十)(2)
|
8月前
|
iOS开发 PyTorch 算法框架/工具
PyTorch 2.2 中文官方教程(二十)(1)
PyTorch 2.2 中文官方教程(二十)
119 0
PyTorch 2.2 中文官方教程(二十)(1)
|
8月前
|
PyTorch 算法框架/工具 异构计算
PyTorch 2.2 中文官方教程(十九)(3)
PyTorch 2.2 中文官方教程(十九)
81 0
PyTorch 2.2 中文官方教程(十九)(3)
|
8月前
|
异构计算 PyTorch 算法框架/工具
PyTorch 2.2 中文官方教程(十九)(2)
PyTorch 2.2 中文官方教程(十九)
110 0
PyTorch 2.2 中文官方教程(十九)(2)