关闭

PyTorch学习系列(六)——自动求导

标签: 深度学习PyTorch自动求导
1827人阅读 评论(0) 收藏 举报
分类:

各种深度学习框架大大简化了研究人员的工作量,这主要归功于它们的自动求导功能。如果不借助于这些深度学习框架,我们不仅需要实现网络的前向过程,而且还要推导网络在各层的梯度表达式以实现反向过程。这是非常费时的,而且极易出错。

PyTorch提供了包torch.autograd用于自动求导。在前向过程中,PyTorch会构建计算图,每个节点用Variable表示,边表示由输入节点到输出节点的函数(torch.autograd.Function对象)。Function对象不仅负责执行前向计算,在反向过程中,每个Function对象会调用.backward()函数计算输出对输入的梯度,然后将梯度传递给下一个Function对象。

torch.autograd.Variable

见博客 PyTorch学习系列(三)——Tensor 和 Variable 中关于Variable的介绍。

torch.autograd.Function

Function和Variable一样,是autograd的重要组成部分,每个在Variable上执行的操作都会生成一个Function对象。

属性(成员变量)

  • saved_tensors: 传给forward()的参数,在backward()中会用到。
  • needs_input_grad:长度为 :attr:num_inputs的bool元组,表示输出是否需要梯度。可以用于优化反向过程的缓存。
  • num_inputs: 传给函数 :func:forward的参数的数量。
  • num_outputs: 函数 :func:forward返回的值的数目。
  • requires_grad: 布尔值,表示函数 :func:backward 是否永远不会被调用。

成员函数

forward()

forward()可以有任意多个输入、任意多个输出,但是输入和输出必须是Variable。

backward()

backward()的输入和输出的个数就是forward()函数的输出和输入的个数。其中,backward()输入表示关于forward()输出的梯度,backward()的输出表示关于forward()的输入的梯度。在输入不需要梯度时(通过查看needs_input_grad参数)或者不可导时,可以返回None。

定义新操作

一般情况下我们并不会接触到Function。但是在以下情况下,我们需要定义自己的Function子类:

  • 在关于Variable对象的操作生成的子图比较大时,需要保存的状态以及计算量会增加,这时我们会希望把这些操作封装在一个Function对象中;
  • 需要定义新的操作时。

定义新的操作,意味着定义Function的子类,并且这些子类必须重写以下函数:::forward()和::backward()。初始化函数::__init__()根据实际需求判断是否需要重写。

示例:

# Inherit from Function
class Linear(Function):

    # bias is an optional argument
    def forward(self, input, weight, bias=None):
        self.save_for_backward(input, weight, bias)
        output = input.mm(weight.t())
        if bias is not None:
            output += bias.unsqueeze(0).expand_as(output)
        return output

    # This function has only a single output, so it gets only one gradient
    def backward(self, grad_output):
        # This is a pattern that is very convenient - at the top of backward
        # unpack saved_tensors and initialize all gradients w.r.t. inputs to
        # None. Thanks to the fact that additional trailing Nones are
        # ignored, the return statement is simple even when the function has
        # optional inputs.
        input, weight, bias = self.saved_tensors
        grad_input = grad_weight = grad_bias = None

        # These needs_input_grad checks are optional and there only to
        # improve efficiency. If you want to make your code simpler, you can
        # skip them. Returning gradients for inputs that don't require it is
        # not an error.
        if self.needs_input_grad[0]:
            grad_input = grad_output.mm(weight)
        if self.needs_input_grad[1]:
            grad_weight = grad_output.t().mm(input)
        if bias is not None and self.needs_input_grad[2]:
            grad_bias = grad_output.sum(0).squeeze(0)

        return grad_input, grad_weight, grad_bias
#建议把新操作封装在一个函数中
def linear(input, weight, bias=None):
    # First braces create a Function object. Any arguments given here
    # will be passed to __init__. Second braces will invoke the __call__
    # operator, that will then use forward() to compute the result and
    # return it.
    return Linear()(input, weight, bias)#调用forward()

#检查实现的backward()是否正确
from torch.autograd import gradcheck
# gradchek takes a tuple of tensor as input, check if your gradient
# evaluated with these tensors are close enough to numerical
# approximations and returns True if they all verify this condition.
input = (Variable(torch.randn(20,20).double(), requires_grad=True),)
test = gradcheck(Linear(), input, eps=1e-6, atol=1e-4)
print(test)
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

pytorch学习笔记(三):自动求导

auto gradient本片博文主要是对http://pytorch.org/docs/notes/autograd.html的部分翻译以及自己的理解,如有错误,欢迎指正!Backward过程中排除...
  • u012436149
  • u012436149
  • 2017-03-27 15:04
  • 4804

pytorch自动微分的几个例子

昨天微信‘机器之心’发布了开源软件pytorch出场的重磅消息。看内容感觉动态计算图的思路比较新颖。在初步体验其自动微分操作之后,发觉这个算法包确实是将计算图的符号占位变量和实体变量的绑定操作合二为一...
  • AMDS123
  • AMDS123
  • 2017-03-16 15:07
  • 7756

Pytorch入门学习(五)---- 示例讲解Tensor, Autograd, nn.module

Pytorch学习,直接看例子快速入门。
  • Hungryof
  • Hungryof
  • 2017-05-09 12:35
  • 3127

PyTorch学习系列(九)——参数_初始化

上篇文章介绍了神经网络的参数定义,并简单提到了其默认初始化。这里详细聊聊怎么根据用户的需求对参数进行初始化。PyTorch提供了多种参数初始化函数: torch.nn.init.constant(te...
  • VictoriaW
  • VictoriaW
  • 2017-06-05 22:16
  • 4825

PyTorch之示例——MNIST

from __future__ import print_function import argparse import torch import torch.nn as nn import torc...
  • VictoriaW
  • VictoriaW
  • 2017-05-16 23:09
  • 5123

PyTorch学习系列(六)——自动求导

各种深度学习框架大大简化了研究人员的工作量,这主要归功于它们的自动求导功能。如果不借助于这些深度学习框架,我们不仅需要写大量构建网络的代码,而且还要推导网络在各层的梯度并实现导数计算,这是非常费时的,...
  • VictoriaW
  • VictoriaW
  • 2017-05-19 21:39
  • 1827

pytorch学习笔记(三):自动求导

auto gradient本片博文主要是对http://pytorch.org/docs/notes/autograd.html的部分翻译以及自己的理解,如有错误,欢迎指正!Backward过程中排除...
  • u012436149
  • u012436149
  • 2017-03-27 15:04
  • 4804

pytorch 学习笔记(一)

pytorch 学习笔记(一) pytorch是一个动态的建图的工具。不像Tensorflow那样,先建图,然后通过feed和run重复执行建好的图。相对来说,pytorch具有更好的灵活性。 ...
  • shuyun123456789
  • shuyun123456789
  • 2017-02-05 13:26
  • 8317

PyTorch学习总结(七)——自动求导机制

自动求导机制从后向中排除子图每个变量都有两个标志:requires_grad和volatile。它们都允许从梯度计算中精细地排除子图,并可以提高效率。requires_grad如果有一个单一的输入操作...
  • manong_wxd
  • manong_wxd
  • 2017-12-06 19:46
  • 86

pytorch学习笔记(三):自动求导

auto gradient 本片博文主要是对http://pytorch.org/docs/notes/autograd.html的部分翻译以及自己的理解,如有错误,欢迎指正! Backw...
  • qq_27245709
  • qq_27245709
  • 2017-06-15 13:20
  • 456
    个人资料
    • 访问:320424次
    • 积分:6315
    • 等级:
    • 排名:第4496名
    • 原创:334篇
    • 转载:6篇
    • 译文:15篇
    • 评论:76条