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
PyTorch教程之Neural Networks的更多相关文章
- PyTorch教程之Training a classifier
我们已经了解了如何定义神经网络,计算损失并对网络的权重进行更新. 接下来的问题就是: 一.What about data? 通常处理图像.文本.音频或视频数据时,可以使用标准的python包将数据加载 ...
- PyTorch Tutorials 3 Neural Networks
%matplotlib inline Neural Networks 使用torch.nn包来构建神经网络. 上一讲已经讲过了autograd,nn包依赖autograd包来定义模型并求导. 一个nn ...
- PyTorch教程之Autograd
在PyTorch中,autograd是所有神经网络的核心内容,为Tensor所有操作提供自动求导方法. 它是一个按运行方式定义的框架,这意味着backprop是由代码的运行方式定义的. 一.Varia ...
- PyTorch教程之Tensors
Tensors类似于numpy的ndarrays,但是可以在GPU上使用来加速计算. 一.Tensors的构建 from __future__ import print_function import ...
- 新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs)
新手教程之:循环网络和LSTM指南 (A Beginner’s Guide to Recurrent Networks and LSTMs) 本文翻译自:http://deeplearning4j.o ...
- pytorch -- CNN 文本分类 -- 《 Convolutional Neural Networks for Sentence Classification》
论文 < Convolutional Neural Networks for Sentence Classification>通过CNN实现了文本分类. 论文地址: 666666 模型图 ...
- Machine Learning - 第4周(Neural Networks: Representation)
Neural networks is a model inspired by how the brain works. It is widely used today in many applicat ...
- 3D Graph Neural Networks for RGBD Semantic Segmentation
3D Graph Neural Networks for RGBD Semantic Segmentation 原文章:https://www.yuque.com/lart/papers/wmu47a ...
- 课程二(Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization),第三周(Hyperparameter tuning, Batch Normalization and Programming Frameworks) —— 2.Programming assignments
Tensorflow Welcome to the Tensorflow Tutorial! In this notebook you will learn all the basics of Ten ...
随机推荐
- PyQt:昨天今天明天表示方法
PyQt中今天的表示方法如下: QtCore.QDate.currentDate() 那么,明天怎么表示呢? today=QtCore.QDate.currentDate().toJulianDay( ...
- javascript一些比较难理解的知识点
原文出处:https://segmentfault.com/a/1190000010371988 看了一下这篇文章,自己也手敲了一遍 //1. 立即执行函数 作用:将var变量的作用域限制于函数内,这 ...
- mysql排序
MySQL里desc和asc的意思 desc是descend 降序意思 asc 是ascend 升序意思 sql = "select 表内容名 from 数据库 ...
- 面试技巧,如何通过索引说数据库优化能力,内容来自Java web轻量级开发面试教程
上星期写了一个篇文章,数据库方面的面试技巧,如何从建表方面展示自己能力,承蒙管理员抬举,放入首页,也承蒙各位厚爱,两天内收获了将近770个点击,也一度进入48小时热榜. 为了感谢管理员和大家的支持,再 ...
- JavaScript基本语法2
javaScript中要显示> .<必须使用> .<,如果是不显示但是要作为条件可以直接使用>.<. 接下来是JavaScirpt函数: 要使用func ...
- Electron 实战桌面计算器应用
前言 Electron 是一个搭建跨平台桌面应用的框架,仅仅使用 JavaScript.HTML 以及 CSS,即可快速而容易地搭建一个原生应用.这对于想要涉及其他领域的开发者来说是一个非常大的福利. ...
- macaca 环境搭建篇,(web 和安卓)
appium研究一段时间,感觉appium太不稳定了, 后来听说了阿里开源了macaca,那么我就想尝尝鲜,啥都不说,我感觉还是赶紧上手搭建环境吧. macaca介绍: Macaca是一套完整的自动化 ...
- postman 第5节 Runner的使用(转)
1.首先在postman新建要批量运行的接口文件夹,新建一个接口,并设置好全局变量. 2.然后在Test里面设置好要断言的方法 如: tests["Status code is 200&qu ...
- C# 单例模式(Singleton Pattern)(转SuagrMatl)
单例模式的定义: 确保一个类只有一个实例,并提供一个全局访问点. 首先实例大家应该都明白就是类生成对象的过程简单的就是String s=new String(),则s就是个实例. Q:如何只生成一个实 ...
- httpd2.4常用配置
author:JevonWei 版权声明:原创作品 httpd 2.4配置 切换使用的MPM Centos7:/etc/httpd/conf.modules.d/00-mpm.conf 启用要启用的M ...