zoukankan      html  css  js  c++  java
  • autograd手动仿真手记

    Preface

    查看损失函数的时候,突然想手工模拟梯度传递过程。

    Script

    损失函数是这个: (l(x)=-||x| - |x-1||)。程序脚本:

    import mxnet as mx;import numpy as np;import mxnet.autograd as ag
    x=mx.nd.zeros((1,))+2
    x.attach_grad()
    with ag.record():
        l=-mx.nd.abs( mx.nd.abs(x) - mx.nd.abs(x-1.)   )
        l.backward(mx.nd.ones_like(l))
    print x,l,'x.grad:',x.grad
    

    先回顾一下梯度传递的理论基础:如果(y=f(z(x))),其中(f,z)都可看作不同layer代表的映射,那么需要求得对(x)的梯度,易于推广的方法是链式法则:

    [y_x = f_z(z) imes z_x(x) ]

    得到普遍应用的原因是易于模块化,每个layer只需要把自己那部分设计好,就可以支持构建自定义系统。
    明白这点后,模拟过程最好就是列表:
    比如现在(x=2)

    Symbol Op Input Output Grad
    x | | 2 2 -1x1=-1
    x-1 + 2 1 1x1=1
    |x-1| | | 1 1 1x1/1=1
    |x|-|x-1| +,- 2, 1 1 -1x1=-1, -1x-1=1
    | |x| - |x-1| | | | 1 1 -1 x 1/1=-1
    -| |x| - |x-1| | - 1 -1 1 x -1 =-1
    l 1

    绝对值的导数:(f(x)=|x| Rightarrow f^,(x)=frac{x}{f(x)})
    填写Input/Output的过程类似于Forward过程;计算Grad类比于Backward,需要从表格底部算起。
    x的节点被复用一次:(grad_x=1+(-1)=0)

    Note

    (f(x)=|x|)(x=0)处,MXNet使用的应该是置零操作。参考(x=0Rightarrow 1, x=0.5Rightarrow 0, x=1Rightarrow -1)

  • 相关阅读:
    Circular vector
    【杂题】进制转换
    【POJ】3006
    【POJ】1503
    【POJ】2262
    【POJ】1083
    【POJ】2739
    对拍
    【POJ】2159
    【POJ】3299
  • 原文地址:https://www.cnblogs.com/chenyliang/p/8451547.html
Copyright © 2011-2022 走看看