我们可以通过torch.nn package构建神经网络。
现在我们已经了解了autograd,nn基于autograd来定义模型并对他们有所区分。
一个 nn.Module模块由如下部分构成:若干层,以及返回output的
forward(input)方法。
例如,这张图描述了进行数字图像分类的神经网络:
这是一个简单的前馈( feed-forward)网络,读入input内容,每层接受前一级的输入,并输出到下一级,直到给出outpu结果。
一个经典神经网络的训练程序如下:
1.定义具有可学习参数(或权重)的神经网络
2.遍历iinput数据集
3.通过神经网络对input进行处理得到output结果
4.计算损失(ouput离正确值有多远)
5.将梯度返回到神经网络的参数中
6.更新神经网络的权重,通常使用一个简单的更新规则:
weight = weight - learning_rate * gradient
一、如何在pytorch中定义神经网络
定义神经网络:
import torchfrom torch.autograd import Variableimport torch.nn as nnimport torch.nn.functional as Fclass 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_featuresnet = 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
输出结果:
10torch.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
PyTorch教程之Neural Networks
原文地址:http://www.cnblogs.com/xueqiuqiu/p/7514674.html