Pytorch:Neural Networks
Posted CollectTime
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytorch:Neural Networks相关的知识,希望对你有一定的参考价值。
让我们使用Pytorch建立一个神经网络模型,使用的模块是:torch.nn。基于之前以及学习的autograd,nn模块依据此模块定义了不同的模型。通过nn.Model定义网络模型,然后通过forward(input)计算出output值。
这里我们以定义一个下图的神经卷积网络为例:
具体网络模型可参考之前讲解的关于CNN的文章。
训练一个神经网络模型基本的步骤如下:
确定网络的科学系参数
遍历一个数据集作为输入
将数据输入网络
计算损失函数
计算梯度
更新参数
1 定义网络:
import torchfrom torch.autograd import Variableimport torch.nn as nnimport torch.nn.functional as Fclass Net(nn.Module): def __init__(self): super(Net, self).__init__() # 1 input image channel, 6 output channels, 5x5 square convolution # kernel self.conv1 = nn.Conv2d(1, 6, 5) self.conv2 = nn.Conv2d(6, 16, 5) # an affine operation: 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): # Max pooling over a (2, 2) window x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) # If the size is a square you can only specify a single number 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): size = x.size()[1:] # all dimensions except the batch dimension num_features = 1 for s in size: num_features *= s return num_featuresnet = Net()print(net)
思路非常清晰和简单,首先定义一个类Net,该类继承与nn.Model,这样就可以调用nn.Model的方法生成模型,和使用model中的各种网络模块。
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) (fc2): Linear(in_features=120, out_features=84) (fc3): Linear(in_features=84, out_features=10))
可以看出来,我们只需要定义前向网络,输入一个Variable,通过输出调用backward即可自动计算出每个变量相对于输出的梯度。非常的简单。
通过一下方式可以看到网络的所有参数:
params = list(net.parameters())
print(len(params))
print(params[0].size()) # conv1's .weight
out:
10
torch.Size([6, 1, 5, 5])
同时为了使初始的梯度都为0,可以调用:
net.zero_grad()
out.backward(torch.randn(1, 10))
需要注意的是:
torch.nn中支支持mini-batch,而不是单个的样本。所以对于图片来说,输入的参数是一个4维iede数据:nSamples x nChannels x Height x Width
如果是想要输入单个样本的话,使用input.unsqueeze(0)营造一个假的batch。
2.定义loss函数
loss函数输入的参数为output和target,通过计算算出目标值和检测出的值之间的差距。
nn包下有好几种不同的loss函数包,一个简单的loss函数平方差误差损失函数。
如下:
output = net(input)
target = Variable(torch.arange(1, 11)) # a dummy target, for example
criterion = nn.MSELoss()
loss = criterion(output, target)
print(loss)
out:
Variable containing: 38.3962
[torch.FloatTensor of size 1]
现在来看loss函数如何通过其grad.fn属性计算出参数的梯度的。
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d -> view -> linear -> relu -> linear -> relu -> linear -> MSELoss -> loss
通过loss变量的grad_fn属性,可以看到各层网络的函数。
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 0x7f95e0a148d0>
<AddmmBackward object at 0x7f95e0a14c18>
<ExpandBackward object at 0x7f95e0a14c18>
3 反向传播:
以上发现可以使用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)
这里看的仅仅是参数的梯度,如果调用data属性即可根据grad进行修改。
out:
conv1.bias.grad before backwardVariable containing: 0 0 0 0 0 0[torch.FloatTensor of size 6]
conv1.bias.grad after backward
Variable containing:
1.00000e-02 * -6.1643 -2.5201 -4.5238 6.8188 -0.2024 3.4750[torch.FloatTensor of size 6]
同pytorch中还包含了各种各样的网络模型,可以参考链接:
http://pytorch.org/docs/master/nn.html
4.更新参数
最后剩下的就是更新参数了,随机梯度下降法更新参数的公式为:
weight = weight - learning_rate * gradient
如下:
learning_rate = 0.01
for f in net.parameters(): f.data.sub_(f.grad.data * learning_rate)
不仅仅有随机梯度下降法跟新参数,还有其他的优化方法,包含在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() # zero the gradient buffers
output = net(input)loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update
以上是关于Pytorch:Neural Networks的主要内容,如果未能解决你的问题,请参考以下文章
PyTorch - Dropout: A Simple Way to Prevent Neural Networks from Overfitting
训练技巧详解含有部分代码Bag of Tricks for Image Classification with Convolutional Neural Networks
用 Recursive Neural Networks 得到分析树
Graph Neural Networks for Link Prediction with Subgraph Sketching