• PyTorch教程之Neural Networks


    我们可以通过torch.nn package构建神经网络。

    现在我们已经了解了autograd,nn基于autograd来定义模型并对他们有所区分。

    一个 nn.Module模块由如下部分构成:若干层,以及返回output的forward(input)方法。

    例如,这张图描述了进行数字图像分类的神经网络:

    这是一个简单的前馈( feed-forward)网络,读入input内容,每层接受前一级的输入,并输出到下一级,直到给出outpu结果。

    一个经典神经网络的训练程序如下: 

    1.定义具有可学习参数(或权重)的神经网络

    2.遍历input数据集

    3.通过神经网络对input进行处理得到output结果

    4.计算损失(ouput离正确值有多远)

    5.将梯度返回到神经网络的参数中

    6.更新神经网络的权重,通常使用一个简单的更新规则:

    weight = weight - learning_rate * gradient

     一、如何在pytorch中定义神经网络

    定义神经网络:

    import torch
    from torch.autograd import Variable
    import torch.nn as nn
    import torch.nn.functional as F
    
    class Net(nn.Module):
        # 定义Net的初始化函数,本函数定义了神经网络的基本结构
        def __init__(self):
            # 继承父类的初始化方法,即先运行nn.Module的初始化函数
            super(Net,self).__init__()
            # 定义卷积层:输入1通道(灰度图)的图片,输出6张特征图,卷积核5x5
            self.conv1 = nn.Conv2d(1,6,(5,5))
            # 定义卷积层:输入6张特征图,输出16张特征图,卷积核5x5
            self.conv2 = nn.Conv2d(6,16,5)
            # 定义全连接层:线性连接(y = Wx + b),16*5*5个节点连接到120个节点上
            self.fc1 = nn.Linear(16*5*5,120)
            # 定义全连接层:线性连接(y = Wx + b),120个节点连接到84个节点上
            self.fc2 = nn.Linear(120,84)
            # 定义全连接层:线性连接(y = Wx + b),84个节点连接到10个节点上
            self.fc3 = nn.Linear(84,10)
        # 定义向前传播函数,并自动生成向后传播函数(autograd)
        def forward(self,x):
            # 输入x->conv1->relu->2x2窗口的最大池化->更新到x
            x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
            # 如果大小是一个正方形,可以只指定一个数字
            x = F.max_pool2d(F.relu(self.conv2(x)),2)
            # view函数将张量x变形成一维向量形式,总特征数不变,为全连接层做准备
            x = x.view(-1,self.num_flat_features(x))
            # 输入x->fc1->relu,更新到x
            x = F.relu(self.fc1(x))
            # 输入x->fc2->relu,更新到x
            x = F.relu(self.fc2(x))
            # 输入x->fc3,更新到x
            x = self.fc3(x)
            return x
        # 计算张量x的总特征量
        def num_flat_features(selfself,x):
            # 由于默认批量输入,第零维度的batch剔除
            size = x.size()[1:]
            num_features = 1
            for s in size:
                num_features *= s
            return num_features
    
    net = Net()
    print(net)

     输出结果:

    Net (
      (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))
      (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
      (fc1): Linear (400 -> 120)
      (fc2): Linear (120 -> 84)
      (fc3): Linear (84 -> 10)
    )

     通过net.parameters()可以得到可学习的参数:

    params = list(net.parameters())
    print(len(params))
    print(params[0].size())  # conv1's .weight

    输出结果:

    10
    torch.Size([6, 1, 5, 5])

    我们模拟一下单向传播,其中input和output均为autograd.Variable:

    input = Variable(torch.randn(1, 1, 32, 32))
    out = net(input)
    print(out)

    输出结果:

    Variable containing:
    -0.0618 -0.0648 -0.0350  0.0443  0.0633 -0.0414  0.0317 -0.1100 -0.0569 -0.0636
    [torch.FloatTensor of size 1x10]

    对所有参数的梯度缓冲区归零并设置随机梯度反向传播:

    net.zero_grad()
    out.backward(torch.randn(1, 10))

    整个torch.nn包只接受那种小批量样本的数据,而无法接受单个样本。 例如,nn.Conv2d能够构建一个四维的Tensor:nSamples x nChannels x Height x Width。

    如果需要对单个样本进行操作,使用input.unsqueeze(0)来加一个假维度就可以了。

    我们回顾一下目前出现过的概念:

    torch.Tensor - 一个多维数组
    autograd.Variable - 改变Tensor并且记录下来历史操作过程。和Tensor拥有相同的API,以及backward()的一些API。同时包含着和Tensor 相关的梯度。
    nn.Module - 神经网络模块。便捷的数据封装,能够将运算移往GPU,还包括一些输入输出的东西。
    nn.Parameter - 一种变量(Variable),当将任何值赋予Module时自动注册为一个参数。
    autograd.Function - 实现了使用自动求导方法的前馈和后馈的定义。每个Variable的操作都会生成至少一个独立的Function节点,与生成了Variable的函数相连之后记录下历史操作过程。

    二、Loss Function

    Loss function根据(output, target) 输入对计算一个值,该值估计输出离目标有多远。

     nn包下有几种不同的损失函数。一个简单的损失是:nn.MSELoss,它计算输入和目标之间的均方误差。

     

    output = net(input)
    target = Variable(torch.arange(1, 11))  # a dummy target, for example
    criterion = nn.MSELoss()
    
    loss = criterion(output, target)
    print(loss)

    输出结果:

    Variable containing:
     38.4929
    [torch.FloatTensor of size 1]

    现在如果你沿着loss函数反方向走,用.grad_fn属性,你会看到一个像这样的计算图:

    input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d
          -> view -> linear -> relu -> linear -> relu -> linear
          -> MSELoss
          -> loss

    三、Backprop

    我们只需要进行loss.backward()即可向前传播误差。

    你先对现有的梯度进行清零,否则其他梯度将被累积到现有的梯度上。

    我们可以看一看 conv1’s bias在loss.backward()前后的梯度:

    net.zero_grad()     # zeroes the gradient buffers of all parameters
    
    print('conv1.bias.grad before backward')
    print(net.conv1.bias.grad)
    
    loss.backward()
    
    print('conv1.bias.grad after backward')
    print(net.conv1.bias.grad)

    输出结果:

    Variable containing:
     0
     0
     0
     0
     0
     0
    [torch.FloatTensor of size 6]
    Variable containing:
    -0.0929
     0.0419
    -0.0218
     0.0941
     0.2251
     0.1809
    [torch.FloatTensor of size 6]

    四、Update the weights

    在实践中使用的最简单的更新规则是随机梯度下降法(SGD):weight weight learning_rate gradient。

    learning_rate = 0.01
    for f in net.parameters():
        f.data.sub_(f.grad.data * learning_rate)

    然而,在使用神经网络时,用户希望使用各种不同的更新规则,如SGD、nesterov - SGD、Adam、RMSProp等,为了实现这一点,pytorch构建了一个小的包:torch.optim实现了所有这些方法。

    SGD使用方法如下:

    import torch.optim as optim
    
    # create your optimizer lr为learning_rate
    optimizer = optim.SGD(net.parameters(), lr=0.01)
    
    # in your training loop:
    optimizer.zero_grad()   # zero the gradient buffers
    output = net(input)     #
    loss = criterion(output, target)
    loss.backward()     #得到梯度,i.e. 给Variable.grad赋值
    optimizer.step() # Does the update

      

  • 相关阅读:
    tensorflow2.0 GPU和CPU 时间对比
    第一次使用FileZilla Server
    PremiumSoft Navicat 15 for Oracle中文破解版安装教程
    Unmapped Spring configuration files found. Please configure Spring facet or use 'Create Default Context' to add one including all unmapped files.
    ng : 无法加载文件 D: odejs ode_global g.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
    angular
    Github上优秀的go项目
    win10---file explore 中remove quick access folder
    react--useEffect使用
    linux---cat 和 grep 的妙用
  • 原文地址:https://www.cnblogs.com/xueqiuqiu/p/7514674.html
Copyright © 2020-2023  润新知