PYTORCH: 60分钟 | 神经网络

神经网络可以使用 torch.nn包构建。

现在你已经对autograd有所了解, nn依赖 autograd 定义模型并对其求微分。 nn.Module 包括层,和一个返回 output 的方法 – forward(input)

例如,看看这个对数字图片进行分类的网络:

PYTORCH: 60分钟 | 神经网络

convnet

这是一个简单的前馈网络。它接受输入,通过一层接一层,最后输出。

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

  • 定义神经网络,并包括一些可学习的参数(或权重)
  • 通过输入数据集迭代
  • 通过网络处理输入
  • 计算损失(输出和真值的差距)
  • 将梯度反向传播至神经网络的参数
  • 更新神经网络权重,通常使用简单的更新规则: weight = weight - learning_rate * gradient

定义网络

让我们定义这个网络:

import torch
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        # 1个输入图片通道,6个输出通道,5x5平方卷积核
        self.conv1 = nn.Conv2d(1, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # 一个仿射变换操作:y = Wx + b
        self.fc1 = nn.Linear(16 * 5 * 5, 120) # 5*5是特征图维度
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        # 最大池化:(2,2)窗口
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        # 如果窗口大小是正方形,可以使用单个数字
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = torch.flatten(x, 1) # 将除了batch维度的所有维度展平
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
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(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

你仅仅需要定义 forward 函数, backward 函数(梯度计算)会自动使用 autograd 定义。你可以在 forward 函数上使用任何Tensor操作。

net.parameters() 返回模型的可学习参数

params = list(net.parameters())
print(len(params))
print(param[0].size()) # conv1的权重参数

输出:

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

让我们试试一个随机的32×32的输入。注意:该网络(LeNet)的输入大小是32×32。为在MNIST上使用该网络,请将图片缩放至32×32

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

输出:

tensor([[-0.1380, -0.0528,  0.0736,  0.1018,  0.0066, -0.1454,  0.0366, -0.0692,
          0.0182,  0.0003]], grad_fn=<addmmbackward0>)
</addmmbackward0>

使所有参数的梯度缓存归零,并反向传播 一个随机梯度:

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

注意: torch.nn仅支持mini-batches。整个 torch.nn包仅支持样本的mini-batch输入,而不是单个sample。例如, nn.Conv2d将接受一个4DTensor: nSamples x nChannels x Height x width。如果是单个样本,利用 input.unsqueeze(0) 添加一个假的batch维度即可。

在继续之前,让我们回顾一下所有你迄今为止看到的所有类。

Recap:

  • torch.Tensor – 一个 multi-dimensional array,支持autograd操作,如 backward()。还持有关于tensor的梯度。
  • nn.Module – 神经网络模型。封装参数的一个便捷的途径,并且可将它们移动到GPU,输出、加载等。
  • nn.Parameter – 当tensor作为属性赋给 Module时,自动注册为参数。
  • autograd.Function – autograd的前向和后向定义的具体实现。每一个 Tensor 操作创建最少一个 Function 节点,并连接到创建 Tensor 和对其历史进行编码的函数。

以上,我们介绍了:

  • Defining a neural network
  • Processing inputs and calling backward

还剩:

  • 计算损失
  • 更新网络权重

损失函数

损失函数接受input的(output,target)对,计算评估output距离target的值。

在nn包中有多种不同的loss function,一个简单的损失函数是: nn.MSELoss,它计算input和target的均方误差。

例如:

output = net(input)
target = torch.randn(10) # &#x4E00;&#x4E2A;&#x5047;&#x7684;target
target = target.view(1, -1) # &#x4F7F;&#x5176;&#x4E0E;output&#x4FDD;&#x6301;&#x5F62;&#x72B6;&#x4E00;&#x81F4;
criterion = nn.MSELoss()

loss = criterion(output, target)
print(loss)

输出:

tensor(1.3339, grad_fn=<mselossbackward0>)
</mselossbackward0>

现在,如果你在后向传播中跟踪 loss,使用它的 .grad_fn 属性,你将会看到类似下面的计算图:

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

因此,当我们调用 loss.backward(),整个图将被求有关神经网络参数的导数,并且图中所有 requires_grad=True的Tensors将持有梯度Tensor – .grad

为了说明,让我们查看几步backward:

print(loss.grad_fn) # MSELoss
print(loss.grad_fn.next_functions[0][0]) # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # Relu

输出:

<mselossbackward0 object at 0x7efad9c382b0>
<addmmbackward0 object at 0x7efad9c386d8>
<accumulategrad object at 0x7efad9c386d8>
</accumulategrad></addmmbackward0></mselossbackward0>

Backprop

为了使误差反向传播,我们需要做的仅仅是 loss.backward()。但是你需要清除现有的梯度,否则梯度将会累积到已有的梯度之中。

现在调用 loss.backward(),并查看conv1的偏置在反向传播前后的梯度。

net.zero_grad() # &#x5C06;&#x6240;&#x6709;&#x53C2;&#x6570;&#x7684;&#x68AF;&#x5EA6;&#x7F13;&#x5B58;&#x8BBE;&#x7F6E;&#x4E3A;0

print('conv1.bias.grad before backward')
print(net.conv1.bias.grad)

loss.backward()

print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)

输出:

conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([ 0.0061, -0.0024, -0.0051, -0.0073,  0.0014,  0.0074])

现在,我们已经知道了如何使用损失函数。

Read Later:

神经网络包中包含多种模型和损失函数,用以组成深度神经网络的构建块,完整的文档列表在

还剩最后一部分:

  • 更新网络的权重

更新权重

在实践中最简单的更新方法是随机梯度下降(SGD)

weight = weight - learning * gradient

我们可以使用简单的Python代码实现SGD:

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

但是,当你使用神经网络时,你想使用多种不同的更新规则,如SGD、Nesterov-SGD、Adam、RMSProp,etc。为了实现这个,我们构建了一个小型的包: torch.optim,可以实现以上所有方法。使用起来也非常简单。

import torch.optim as optim

create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)

&#x5728;&#x8BAD;&#x7EC3;&#x5FAA;&#x73AF;&#x4E2D;&#xFF1A;
optimizer.zero_grad() # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update

Original: https://www.cnblogs.com/DeepRS/p/15720200.html
Author: Deep_RS
Title: PYTORCH: 60分钟 | 神经网络

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621348/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • linux中实时监控目录中生成的文件,并钉钉告警

    inotify是一个API 需要通过开发应用程序进行调用,对于大多数用户来讲这有着许多不便,inotify-tools的出现弥补了这一不足。 inotify-tools是一套组件,…

    Linux 2023年6月6日
    0101
  • 每天一个 HTTP 状态码 201

    201 Created 表示请求成功,在服务器端创建了一个新资源… 201 Created 201 Created 表示客户端的请求已经成功完成,结果是创建了一个新资源…

    Linux 2023年6月7日
    0116
  • 位运算(一)

    位运算的一般应用 功能 例子 运算 去掉最后一位 1110101->111010 x>>1 在最后加0 1110101->11101010 x< 通过…

    Linux 2023年6月8日
    0126
  • Linux之Keepalived高可用

    一、高可用介绍 一般是指2台机器启动着完全相同的业务系统,当有一台机器down机了,另外一台服务器就能快速的接管,对于访问的用户是无感知的。 硬件通常使用:F5 软件通常使用:Ke…

    Linux 2023年6月14日
    0130
  • VMware ESXi 7.0 U2 SLIC 2.6 & Unlocker 集成 Intel NUC 网卡、USB 网卡和 NVMe 驱动

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    Linux 2023年5月27日
    085
  • [20220811]奇怪的隐式转换问题(12c补充测试).txt

    [20220811]奇怪的隐式转换问题(12c补充测试).txt –//生产系统遇到一个奇怪的隐式转换问题,问题在于没有发生隐式转换,前面已经做了一些分析增加12c下的…

    Linux 2023年6月13日
    074
  • 面向对象设计的23种设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是…

    Linux 2023年6月7日
    087
  • 数据库主从复制

    主从复制是MySQL中最重要的功能之一。主从复制是指一台服务器充当主数据库服务器,另一台或多台服务器充当从数据库服务器,主服务器中的数据自动复制到从服务器之中。对于多级复制,数据库…

    Linux 2023年6月6日
    057
  • 一文搞懂 Netty 发送数据全流程 | 你想知道的细节全在这里

    欢迎关注公众号:bin的技术小屋,如果大家在看文章的时候发现图片加载不了,可以到公众号查看原文 本系列Netty源码解析文章基于 4.1.56.Final版本 在《Netty如何高…

    Linux 2023年6月6日
    084
  • 阿里云函数-爱奇艺签到

    简介 是否支持多账号:是消息推送平台:PUSHPLUS 代码 -*- coding: utf8 -*- import requests,random,string,hashlib,…

    Linux 2023年6月7日
    075
  • Windows Server 新增磁盘处于脱机状态解决办法

    解决方案: Cmd命令行操作如下: 1,进入diskpart模式 2、列出磁盘情况 3、选择脱机的磁盘 4、联机磁盘 5、清除磁盘属性 6、进入磁盘管理,提示初始化 每天记录一点,…

    Linux 2023年6月8日
    099
  • sed命令

    对文件的操作无非就是”增删改查”,怎样用sed 命令实现对文件的”增删改查”,玩转sed 是写自动化脚本必须的基础之一 sed遵循简…

    Linux 2023年6月13日
    081
  • [CentOS7]redis设置开机启动,设置密码

    简介 上篇文章介绍了如何安装redis,但每次重启服务器之后redis不会自启,这里将介绍如何进行自启设置,以及如何设置redis的密码,进行密码验证登陆。 上篇文章: Cento…

    Linux 2023年5月28日
    094
  • 备用链接

    win10 stick note 地址 https://www.partitionwizard.com/partitionmanager/where-are-sticky-note…

    Linux 2023年6月7日
    079
  • [apue] linux 文件访问权限那些事儿

    说到 linux 上的文件权限,其实我们在说两个实体,一是文件,二是进程。一个进程能不能访问一个文件,其实由三部分内容决定: 下面先简单说明一下这些基本概念,最后再说明它们是如何相…

    Linux 2023年6月6日
    092
  • 博客园装饰——(二)滚动到页面顶部或底部

    功能描述: 1. 当页面向下滚动一定距离时,向下滚动到底部的按钮以淡入的效果出现,并以固定定位显示。且滚动到一定距离(快接近所设置的底部)时,该按钮又会以淡出效果消失。 2. 当页…

    Linux 2023年6月14日
    080
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球