zoukankan      html  css  js  c++  java
  • 自动求梯度

    本博文来自于 《动手学深度学习》 本博文只是记录学习笔记,方便日后查缺补漏,如有侵权,联系删除

    自动求梯度

    在深度学习中,经常需要对函数求梯度(gradient)。本节将介绍如何使用MXNet提供的autograd模块来自动求梯度。

    from mxnet import autograd, nd
    

    简单例子

    我们先看一个简单例子:对函数 (y = 2oldsymbol{x}^{ op}oldsymbol{x}) 求关于列向量 (oldsymbol{x}) 的梯度。我们先创建变量x,并赋初值。

    x = nd.arange(4).reshape((4, 1))
    x
    
    [[0.]
     [1.]
     [2.]
     [3.]]
    <NDArray 4x1 @cpu(0)>
    

    为了求有关变量x的梯度,我们需要先调用attach_grad函数来申请存储梯度所需要的内存。

    x.attach_grad()
    

    下面定义有关变量x的函数。为了减少计算和内存开销,默认条件下MXNet不会记录用于求梯度的计算。我们需要调用record函数来要求MXNet记录与求梯度有关的计算。

    with autograd.record():
        y = 2 * nd.dot(x.T, x)
    

    由于x的形状为(4, 1),y是一个标量。接下来我们可以通过调用backward函数自动求梯度。需要注意的是,如果y不是一个标量,MXNet将默认先对y中元素求和得到新的变量,再求该变量有关x的梯度。

    y.backward()
    

    函数 (y = 2oldsymbol{x}^{ op}oldsymbol{x}) 关于(oldsymbol{x}) 的梯度应为(4oldsymbol{x})。现在我们来验证一下求出来的梯度是正确的。

    assert (x.grad - 4 * x).norm().asscalar() == 0
    x.grad
    
    [[ 0.]
     [ 4.]
     [ 8.]
     [12.]]
    <NDArray 4x1 @cpu(0)>
    

    训练模式和预测模式

    从上面可以看出,在调用record函数后,MXNet会记录并计算梯度。此外,默认情况下autograd还会将运行模式从预测模式转为训练模式。这可以通过调用is_training函数来查看。

    print(autograd.is_training())
    with autograd.record():
        print(autograd.is_training())
    
    False
    True
    

    在有些情况下,同一个模型在训练模式和预测模式下的行为并不相同。

    对Python控制流求梯度

    使用MXNet的一个便利之处是,即使函数的计算图包含了Python的控制流(如条件和循环控制),我们也有可能对变量求梯度。

    考虑下面程序,其中包含Python的条件和循环控制。需要强调的是,这里循环(while循环)迭代的次数和条件判断(if语句)的执行都取决于输入a的值。

    def f(a):
        b = a * 2
        while b.norm().asscalar() < 1000:
            b = b * 2
        if b.sum().asscalar() > 0:
            c = b
        else:
            c = 100 * b
        return c
    

    我们像之前一样使用record函数记录计算,并调用backward函数求梯度。

    a = nd.random.normal(shape=1)
    a.attach_grad()
    with autograd.record():
        c = f(a)
    c.backward()
    

    我们来分析一下上面定义的f函数。事实上,给定任意输入a,其输出必然是 f(a) = x * a的形式,其中标量系数x的值取决于输入a。由于c = f(a)有关a的梯度为x,且值为c / a,我们可以像下面这样验证对本例中控制流求梯度的结果的正确性。

    a.grad == c / a
    
    [1.]
    <NDArray 1 @cpu(0)>
    

    小结

    • MXNet提供autograd模块来自动化求导过程。
    • MXNet的autograd模块可以对一般的命令式程序进行求导。
    • MXNet的运行模式包括训练模式和预测模式。我们可以通过autograd.is_training()来判断运行模式。

    练习

    • 在本节对控制流求梯度的例子中,把变量a改成一个随机向量或矩阵。此时计算结果c不再是标量,运行结果将有何变化?该如何分析该结果?
    • 重新设计一个对控制流求梯度的例子。运行并分析结果。
    不一定每天 code well 但要每天 live well
  • 相关阅读:
    给自己新申请的阿里云服务器ECS免费搭建WDCP环境
    maven run 配置jre VM arguments配置 (转)
    JSON.stringify 语法实例讲解(转)
    Vue-cli proxyTable 解决开发环境的跨域问题(转)
    JS几种数组遍历方式以及性能分析对比(转 未经测试,先mark)
    调用web接口跨域问题
    Jquery获取浏览器窗口和Body长宽
    idea tab页签颜色不明显,自定义颜色解决。
    疯狂Java学习笔记(009)
    疯狂Java学习笔记(001)
  • 原文地址:https://www.cnblogs.com/geekfx/p/13875432.html
Copyright © 2011-2022 走看看