神经网络能够使用torch.nn包构建神经网络。

现在你已经对autogard有了初步的了解,nn基于autograd来定义模型并进行微分。一个nn.Module包含层,和一个forward(input)方法并返回output。

以如下分类数字图片的网络所示:

这是一个简单的前馈网络。它接受输入,经过一层接着一层的神经网络层,最终得到输出。

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

  • 定义拥有可学习的参数的神经网络
  • 迭代数据集作为输入
  • 经过网络处理输入
  • 计算损失(离正确输出的距离)
  • 反向传播梯度到网络参数
  • 更新网络的权重,比如简单的更新规则:weight=weight-learning_rate*gradient

定义网络

让我们定义这个网络:  

import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
# 一个输入图片通道,六个输出通道,5*5的卷积核
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)
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=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):
     #第一个尺寸是batch size
size=x.size()[1:]
print(size)
num_features=1
for s in size:
num_features*=s
return num_features net=Net()
print(net)
out:
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函数(计算梯度的地方)是自动定义的。你能够在forward中使用任意的tensor运算。

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

params=list(net.parameters())
print(len(params))
print(params[0].size())

out:
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)

out:
tensor([[ 0.0355, -0.0294, -0.0025, -0.0743, -0.0168, -0.0202, -0.0558,
0.0803, -0.0162, -0.1153]])

将所有参数的梯度缓冲变为0并使用随机梯度进行后向传播:

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

!注意:

torch.nn只支持最小批。整个torch.nn包只支持输入的样本是一个最小批,而不是一个单一样本.

举例来说,nn.Conv2d将会接收4维的Tensor,nSamples*nChannels*Heights*Width.

如果你有一个单一样本,可以使用input.unsqueeze(0)来增加一个虚假的批维度。

在进行进一步处理前,让我们简要重复目前为止出现的类。

扼要重述:

  • torch.Tensor- 一个支持自动求导操作比如backward()的多维数组。同时保留关于tensor的梯度.
  • nn.Module- 神经网络模型。简易的封装参数的方法,帮助将它们转移到GPU上,导出加载等等.
  • nn.Parameters - 一类Tensor,在作为Module属性指定时会自动注册为一个parameter.
  • autograd.Function- 自动求导操作前向与后向的实现。每个tensor操作,至少创建一个Functional节点,它连接到创建Tensor的函数并编码它的历史

在这一节,我们包含了:

  • 定义一个神经网络
  • 处理输入并调用后向传播

还剩下:

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

损失函数:

损失函数接收对(输出,目标)作为输入,计算一个值估计输出与目标之间的距离。

nn包下有一些不同的损失函数。一个简单的损失是nn.MSELoss,它计算的是输入与输出之间的均方误差。

比如:

output=net(input)
target=torch.randn(10)
target=target.view(1,-1)
criterion=nn.MSELoss() loss=criterion(output,target)
print(loss)
out:
tensor(1.1941)

现在,如果你如果按照loss的反向传播方向,使用.grad_fn属性,你将会看到一个计算图如下所示:

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

所以,当你调用loss.backward(),整个图关于损失求导,并且图中所有requires_grad=True的tensor将会有它们的.grad属性。Tensor的梯度是累加的。

为了说明这一点,我们跟踪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
out:
<MseLossBackward object at 0x0000020E2E1289B0>
<AddmmBackward object at 0x0000020E2BF48048>
<ExpandBackward object at 0x0000020E2BF48048>

Backprop

为了反向传播error,我们需要做的就是loss.backward()。你需要清除现有的梯度,否则梯度将会累计到现有梯度上。

现在我们会调用loss.backward(),观察调用backward前后conv1层偏差的梯度。

net.zero_grad()

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

out:
conv1.bias.grad before backward
None # 上一个版本将会是一个为0的向量
conv1.bias.grad after backward
tensor(1.00000e-03 *
[ 4.0788, 1.9541, 5.8585, -2.3754, 2.3815, 1.3351])

现在我们知道了如何使用loss函数

稍后阅读:

神经网络包包含各种模型和loss函数,它们组成了深度神经网络的构建区块。完整的文档在这里。http://pytorch.org/docs/nn

剩下来需要学习的是:

  • 更新网络的权重

更新权重

实际中使用的最简单更新规则是随机梯度下降(SGD):

weight=weight-learning_rate*gradient

我们能够使用简单的python代码实现:

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

然而,当我们使用神经网络,你想要使用各种不同的更新规则比如SGD,Nesterov-SGD,Adam,RMSProp等。为了做到这一点,我们建立了一个小的包torch.optim实现了这些方法。使用它非常简单。

import torch.optim as optim

#create your optimizer
optimizer =optim.SGD(net.parameters(),lr=0.01) # in your training loop
optimizer.zero_grad()
output=net(input)
loss=criterion(output,target)
loss.backward()
optimizer.step()

!注意:

 手动使用optimizer.zero_grad()来将梯度缓冲变为0。这在Backprop章节进行了解释,因为梯度是累加的。

Neural Networks的更多相关文章

  1. 【转】Artificial Neurons and Single-Layer Neural Networks

    原文:written by Sebastian Raschka on March 14, 2015 中文版译文:伯乐在线 - atmanic 翻译,toolate 校稿 This article of ...

  2. tensorfolw配置过程中遇到的一些问题及其解决过程的记录(配置SqueezeDet: Unified, Small, Low Power Fully Convolutional Neural Networks for Real-Time Object Detection for Autonomous Driving)

    今天看到一篇关于检测的论文<SqueezeDet: Unified, Small, Low Power Fully Convolutional Neural Networks for Real- ...

  3. Deep Learning 23:dropout理解_之读论文“Improving neural networks by preventing co-adaptation of feature detectors”

    理论知识:Deep learning:四十一(Dropout简单理解).深度学习(二十二)Dropout浅层理解与实现.“Improving neural networks by preventing ...

  4. 一天一经典Reducing the Dimensionality of Data with Neural Networks [Science2006]

    别看本文没有几页纸,本着把经典的文多读几遍的想法,把它彩印出来看,没想到效果很好,比在屏幕上看着舒服.若用蓝色的笔圈出重点,这篇文章中几乎要全蓝.字字珠玑. Reducing the Dimensio ...

  5. Stanford机器学习笔记-5.神经网络Neural Networks (part two)

    5 Neural Networks (part two) content: 5 Neural Networks (part two) 5.1 cost function 5.2 Back Propag ...

  6. Stanford机器学习笔记-4. 神经网络Neural Networks (part one)

    4. Neural Networks (part one) Content: 4. Neural Networks (part one) 4.1 Non-linear Classification. ...

  7. Notes on Convolutional Neural Networks

    这是Jake Bouvrie在2006年写的关于CNN的训练原理,虽然文献老了点,不过对理解经典CNN的训练过程还是很有帮助的.该作者是剑桥的研究认知科学的.翻译如有不对之处,还望告知,我好及时改正, ...

  8. 《ImageNet Classification with Deep Convolutional Neural Networks》 剖析

    <ImageNet Classification with Deep Convolutional Neural Networks> 剖析 CNN 领域的经典之作, 作者训练了一个面向数量为 ...

  9. 卷积神经网络CNN(Convolutional Neural Networks)没有原理只有实现

    零.说明: 本文的所有代码均可在 DML 找到,欢迎点星星. 注.CNN的这份代码非常慢,基本上没有实际使用的可能,所以我只是发出来,代表我还是实践过而已 一.引入: CNN这个模型实在是有些年份了, ...

  10. Deep Learning 16:用自编码器对数据进行降维_读论文“Reducing the Dimensionality of Data with Neural Networks”的笔记

    前言 论文“Reducing the Dimensionality of Data with Neural Networks”是深度学习鼻祖hinton于2006年发表于<SCIENCE > ...

随机推荐

  1. Water 2.6.1 发布,一站式服务治理平台

    Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...

  2. [Vue]写一个简单的文件上传控件

    ​这篇将介绍如何写一个简单的基于Vue+Element的文件上传控件. 控件将具有 1. 上传队列的列表,显示文件名称,大小等信息,可以显示上传进度实时刷新 2. 取消上传 ​ 使用Element的u ...

  3. python学习-Day6

    目录 学习内容详述 上期 '猜年龄'练习详解: while循环补充 while + else 死循环与while的嵌套 while嵌套 for循环 range关键字 range用法 什么是爬虫??? ...

  4. 攻防世界-MISC:pure_color

    这是攻防世界高手进阶区的第六题,题目如下: 点击下载附件一,得到一张空白的png图片 用StegSolve打开,然后点击箭头(如下图所示) 多点击几次,即可得到flag 所以,这道题的flag如下: ...

  5. Bugku CTF练习题---MISC---贝斯手

    Bugku CTF练习题---MISC---贝斯手 flag:flag{this_is_md5_and_base58} 解题步骤: 1.观察题目,下载附件 2.下载后进行解压,得到了一张图片.一个压缩 ...

  6. VMware16搭建Ubuntu22.04,更新为国内下载源,安装open-vm-tools,用SecureCRT远程连接

    前期准备 1.VMware16(转载:下载安装流程:(https://www.bilibili.com/read/cv9694457)) 2.Ubuntu22.04----iso镜像文件(下载地址:( ...

  7. 通过Swagger接口导出模板文件时报错:URL.createObjectURL: Argument 1 is not valid for any of the 1-argument overloads.

    问题描述:通过Swagger接口导出Excel模板文件时,报错:URL.createObjectURL: Argument 1 is not valid for any of the 1-argume ...

  8. 使用pdfcrack & crunch暴力破解PDF密码

    crunch是密码字典生成器,可以根据指定的字符来生成组合密码字典. pdfcrack是Linux下一个PDF暴力破解密工具,可以使用crunch生成的密码字典来暴力破解PDF文件的密码. 注:没有强 ...

  9. 使用argparse进行调参

    argparse是深度学习项目调参时常用的python标准库,使用argparse后,我们在命令行输入的参数就可以以这种形式python filename.py --lr 1e-4 --batch_s ...

  10. 借助SpotBugs将程序错误扼杀在摇篮中

    背景 最近一年多在一家toB业务的公司,部门主要做的是建筑行业的招投标业务信息化,希望借助软件来达到"阳光.降本.提效"的目的,我刚入职时大概30多家客户,截止现在已经超过100家 ...