PyTorch入门(三):Neural Networks 神经网络

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

nn依赖于autograd定义模型并且区分。一个nn.Moudule包含层(layers),以及一个返回输出(output)的前向(forward(input))方法。


上图是一个数字图片分类网络。这是一个简单的前馈网络,包括输入,通过几个层,最后产生输出。

一个典型的神经网络包含如下步骤:

  • 定义一些具有可学习参数(或权重)的神经网络
  • 数据集迭代(iterare)输入
  • 通过网络处理输入
  • 计算损失(即输出与正确的预测有多远)
  • 将梯度传播回网络的参数中
  • 更新网络的权重,通常使用的规则为:weight=weight-learning_rate*grdient

定义一个网络

#-*-coding:utf-8-*-
import torch
import torch.nn as nn
import torch.nn.functional as f

class Net(nn.Module):

    def __init__(self):
        super(Net,self).__init__()
        self.conv1 = nn.Conv2d(1,6,5)
        self.conv2 = nn.Conv2d(6,16,5)

        self.fc1 = nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)

    def forward(self,x):
        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):
    	#源代码为size=x.size[1:]
    	#在随机产生一个输入时,此行源代码报错了,于是先得到它的尺寸,再取除去图片个数以外的所有尺寸
        size = x.size()
        size = size[1:]
        num_features = 1
        for s in size:
            num_features *= s
        return num_features

net = Net()
print(net)

得到如下输出
在这里插入图片描述
我们只需要定义forward函数,因为backward函数通过autograd自动定义。在forward函数中可以使用任何Tensor操作。

通过net.parameters()可以返回一个网络的可学习参数

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

输出为
在这里插入图片描述

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

得到输出
在这里插入图片描述
将梯度缓冲区归零,然后用随机梯度值进行反向传播

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

注意

  • torch.nn仅支持小批次样本,而不是一个单独样本
  • nn.Conv2d接收一个4维张量nSamples * nChannels * Height * Width
  • 如果只有一个单独样本,使用input.unsqueeze(0)添加虚拟的batch dimension

损失函数(Loss Function)
损失函数计算并估计输出与目标之间的距离(output和target)。

target = torch.randn(10) 
target = target.view(1, -1)  
criterion = nn.MSELoss()

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

输出为
在这里插入图片描述
当我们调用loss.backward()函数的时候,整张图都被一次计算误差,所有Variable的.grad属性会被累加

反向传播(Backprop)
要使用loss.backward()进行误差反向传播,需要清楚已经存在的梯度值,否则梯度会积累到现有梯度上。

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

在这里插入图片描述
更新权重(Update the weights)
最简单的更新规则是
weight=weight-learning_rate*grdient
通过以下代码实现

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

通过torch.optim包可以实现更新权重的不同更新规则,使用方法很简单。

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

optimizer.zero_grad()
output = net(a)
loss = criterion(output,target)
loss.backward()
optimizer.step()
展开阅读全文

没有更多推荐了,返回首页