Pytorch笔记02-torch.nn以及torch.optim

0.本章内容

Pytorch中集成了许多现成的模块,如包torch.nn中,集成了一些常见的网络层,如卷积等;包torch.optim中集成了许多常用的优化算法,如SGD,Adam等。本章将就torch.nn以及torch.optim做简要介绍。

1.torch.nn

直观理解

  • 在keras、TFLearn等高级的深度学习集成库中,将许多计算进行更加高级的封装
  • torch.nn包内就是类似这种高级封装,里面包括了卷积,池化,RNN等计算,以及其他如Loss计算,可以把torch.nn包内的各个类想象成神经网络的一层
  • 创建一个torch.nn中的层后,对其输入Variable,将得到对应输出的Variable,具体例子见下示例

作用

  • 它的作用包括,能够接受一个输入,并得到一个输出(forward操作)。同时,他保存了该层学习的参数,以及其他的一些状态变量
  • 这种方式将网络高度模块化,使得网络的每个运算都像积木一样一层又一层叠加。

实现机制

  • torch.nn包里面的大部分类都是继承了父类torch.nn.Modules,即本质上所有torch.nn中的层(如卷积、池化)都是torch.nn.Modules
  • torch.nn.Modules可以简单认为是网络一层,包括该层的参数,以及一些操作,如forward,调用参数等
  • 同样地,它的作用包括,能够接受一个输入,并得到一个输出(forward操作)。同时,他保存了该层学习的参数,以及其他的一些状态变量。并实现各类功能的方法,如返回Modules的参数等
  • 因此可以把torch.nn以及torch.nn.Modules看做是一个定义好的小网络(包括其参数),给该网络一个输入,其将得到一个输出。输入输出都是Variable
  • 更多Modules具体机制以及如何重写将在后面章节介绍

torch.nn示例

import torch.nn as nn
import torch
from torch.autograd import Variable

# nn.Sequential是一个Module的容器,里面包含多个Module。里面的Module在forward时将按顺序进行操作,如下即Conv->BN->ReLU->Pool
# nn.Conv2d是2维卷积,其第一个参数为输入通道数,第二个参数为输出通道数
# 注意Conv2d只接收batch输入,不接受单个数据输入,即输入必须是(N,C,H,W)
# BN层的参数是通道数
# 各层的参数已经自动初始化

model = nn.Sequential(
        nn.Conv2d(1, 16, kernel_size=5, padding=2),
        nn.BatchNorm2d(16),
        nn.ReLU(),
        nn.MaxPool2d(2)
        )
# 输出模型
print '模型: ', model

# 输出模型参数
print '模型参数: ', model.parameters

# 输出卷积层参数个数
print '卷积层参数个数: ', list(model.parameters())[0].size()
# print list(model.parameters())[0] # 输出卷积层参数

# 得到model的某一层
conv = model[0]


# model forward得到输出,model的输入输出都是Variable
# 由于forward使用了__call__函数,因此可以直接利用Modules的对象来调用forward

input_var = Variable(torch.randn(1, 1, 10, 10))
output_var = model(input_var)  # 这里使用output_var = model.forward(input_var)也是可行
print output_var.size()


# model backward, output_var是一个Variable,网络在forward过程中已经建立计算图,因此使用backward可计算该model的所有可学习参数的梯度
output_var.backward(torch.ones(output_var.size()))

# 对卷积层进行重新初始化
print '旧的参数值: ', model[0].weight.data[0]
new_weight = torch.zeros(conv.weight.size())
conv.weight.data = new_weight
print '新的参数值: ', model[0].weight.data[0]

# torch.nn中也包含Loss计算,先定义好loss_fn后,可以像调用函数一样在后面进行调用
loss_fn = torch.nn.MSELoss(size_average=False)
print(loss_fn)

# 如下调用loss_fn,y_pred与y是输入的Variable,输出是计算结果的Variable
# loss = loss_fn(y_pred, y)

2 torch.optim示例

torch.optim中有许多常用的优化算法,其实用方法十分简单,详见以下示例:

# 创建一个optim,并指定对应的参数
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

# 将对应参数梯度置0,注意如果没有置0,则将会与上一次梯度进行叠加
optimizer.zero_grad()

# forward 然后 backward 得到梯度
y = model(x)
# 得到对应loss
loss = loss_fn(y_pred, y)
# backward后,计算出loss对制定Variable(requires_grad=True)的梯度
loss.backward()

# 更新参数
optimizer.step()

3. 例子

在学习了,torch.nn以及torch.optim,终于可以不用自己手写网络层以及优化函数了,下面将使用torch.nn及torch.optim来完成前几个章节建立的简单神经网络

import torch
from torch.autograd import Variable

# N为batch size; D_in为输入维度;
# H为隐藏层单元数; D_out为输出层维度.
N, D_in, H, D_out = 64, 1000, 100, 10

# 随机生成输入数据x,label y
x = Variable(torch.randn(N, D_in))
y = Variable(torch.randn(N, D_out), requires_grad=False)

# 使用torch.nn建立网络
model = torch.nn.Sequential(
          torch.nn.Linear(D_in, H),
          torch.nn.ReLU(),
          torch.nn.Linear(H, D_out),
        )

# 使用torch.nn中MSELoss定义损失函数
loss_fn = torch.nn.MSELoss(size_average=False)

# 定义优化器
learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
for t in range(20000):
    # Forward 前向传播
    y_pred = model(x).mean()

    # 计算loss
    loss = loss_fn(y_pred, y)
    print(t, loss.data[0])

    optimizer.zero_grad()

    # 后向传播 
    loss.backward()

    if t % 100 == 0:
        print(y_pred.data[0])

    # 更新梯度
    optimizer.step()
    原文作者:林梅林
    原文地址: https://zhuanlan.zhihu.com/p/27443165
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞