TensorFlow可微编程实践2---自动微分符号体系

自动微分采用一套与常规机器学习和深度学习不同的符号体系,我们只有熟悉了这个符号体系,才能比较轻松的看懂自动微分的文章。本篇博文将向大家介绍自动微分中使用的符号体系。
我们以下面这个函数为例,讲解一下自动微分的符号表示法:

y=f(x1,x2)=logx1+x1x2sinx2 y = f ( x 1 , x 2 ) = log ⁡ x 1 + x 1 x 2 − sin ⁡ x 2

对自动微分采用一种比较特别的符号表示法,与Bingio的《Deep Learning》书中MLP章节中的表示法类似,采用三段表示法。

  • 输入向量
    我们假设自变量维度为n,在这个例子中n=2,我们用 v v 来表示自变量:vin=xi,i=1,2,...,n,以本例为例,我们用 v1 v − 1 表示 x1 x 1 ,用 v0 v 0 表示 x2 x 2
  • 中间变量
    我们同样用 v v 表示中间变量,假设共有l个中间变量,表示为: vi,i=1,2,...,l v i , i = 1 , 2 , . . . , l
  • 输出向量
    我们用 y y 来表示输入向量,假设输出向量维度为k,表示为: yki=vli,i=k1,...,0 y k − i = v l − i , i = k − 1 , . . . , 0 ,还以本例为例,输出向量只有1维,则 k=1 k = 1 ,则 y1=vl y 1 = v l
    这里写图片描述
    我们先来讲前向模式,这种模式即可求出计算图的输出,同时也可以求出导数值。但是如果以深度学习的角度来看,前向模式就只需要完成计算出计算图中各节点的值就可以了。而求导数则由反向模式来实现。
    我们首先给输入节点赋值: v1=x1 v − 1 = x 1 v0=x2 v 0 = x 2
    接着我们计算 v1 v 1 节点: v1=logv1=logx1 v 1 = log ⁡ v − 1 = log ⁡ x 1
    我们再计算 v2 v 2 节点: v2=v1v0=x1x2 v 2 = v − 1 v 0 = x 1 x 2
    我们再来计算 v3 v 3 节点: v3=v1+v2=logx1+x1x2 v 3 = v 1 + v 2 = log ⁡ x 1 + x 1 x 2
    计算 v4 v 4 节点: v4=sinv0=sinx2 v 4 = − sin ⁡ v 0 = − sin ⁡ x 2
    计算输出节点 v5 v 5 y1=v5=v3+v4=logx1+x1x2sinx2 y 1 = v 5 = v 3 + v 4 = log ⁡ x 1 + x 1 x 2 − sin ⁡ x 2
    至此我们就计算出了计算图中所有节点的值。
    下面我们来介绍在正向模式下导数的计算。假设我们想求 yx1 ∂ y ∂ x 1 的值,我们也是由输入开始计算。
    v1 v − 1 节点: v1x1=1 ∂ v − 1 ∂ x 1 = 1 ,因为 v1=x1 v − 1 = x 1
    v0 v 0 节点: v0x1=0 ∂ v 0 ∂ x 1 = 0 ,因为 v0=x2 v 0 = x 2 其与 x1 x 1 无关。
    v1 v 1 节点: v1x1=x1logx1=1x1 ∂ v 1 ∂ x 1 = ∂ ∂ x 1 log ⁡ x 1 = 1 x 1
    v2 v 2 节点: v2x1=x1x1x2=x2 ∂ v 2 ∂ x 1 = ∂ ∂ x 1 x 1 x 2 = x 2
    v3 v 3 节点: v3x1=v1x1+v2x1=1x1+x2 ∂ v 3 ∂ x 1 = ∂ v 1 ∂ x 1 + ∂ v 2 ∂ x 1 = 1 x 1 + x 2
    v4 v 4 节点: v4x1=x1sinx2=0 ∂ v 4 ∂ x 1 = ∂ ∂ x 1 sin ⁡ x 2 = 0
    v5 v 5 节点: v5x1=v3x1v4x1=1x1+x2 ∂ v 5 ∂ x 1 = ∂ v 3 ∂ x 1 − ∂ v 4 ∂ x 1 = 1 x 1 + x 2
    由上面的计算可以看出,我们每次前向计算,只能计算输入向量一维的导数,如果输入向量有 n=2 n = 2 维,则需要计算两次,当 n n 很大时,这种方法的效率就会比较低了。
    对于深度学习问题,我们通常会研究Jacobian矩阵,假设输入向量xRn,而输出向量用 yRk y ∈ R k ,则Jacobian矩阵定义为:
    J=y1x1...ykx1y1x2...ykx2.........y1xn...ykxn J = [ ∂ y 1 ∂ x 1 ∂ y 1 ∂ x 2 . . . ∂ y 1 ∂ x n . . . . . . . . . . . . ∂ y k ∂ x 1 ∂ y k ∂ x 2 . . . ∂ y k ∂ x n ]

    我们可以看出,一次前向计算,可以求出Jacobian矩阵的一列数据。
    为了讨论方便,我们这里假设 x1=2 x 1 = 2 x2=5 x 2 = 5 ,我们首先按照前向模式计算出各节点的值,如下图所示:
    这里写图片描述
    我们再来看导数部分。
    v5 v 5 节点有 v5=v3v4 v 5 = v 3 − v 4 ,我们首先求 v5v3=(v3v4)v3=1 ∂ v 5 ∂ v 3 = ∂ ( v 3 − v 4 ) ∂ v 3 = 1 ,将结果写在 v3 v 3 指向 v5 v 5 的边上。
    我们再来求 v5v4=(v3v4)v4=1 ∂ v 5 ∂ v 4 = ∂ ( v 3 − v 4 ) ∂ v 4 = − 1 ,将结果写在 v4 v 4 指向 v5 v 5 的边上。
    我们再来求 v4v0=sinv0v0=cosv0=0.284 ∂ v 4 ∂ v 0 = ∂ sin ⁡ v 0 ∂ v 0 = cos ⁡ v 0 = 0.284 ,将结果写在 v0 v 0 指向 v4 v 4 的边上。
    我们再来求 v3v1=(v1+v2)v1=1 ∂ v 3 ∂ v 1 = ∂ ( v 1 + v 2 ) ∂ v 1 = 1 ,将结果写在 v1 v 1 指向 v3 v 3 的边上。
    我们再来求 v3v2=(v1+v2)v2=1 ∂ v 3 ∂ v 2 = ∂ ( v 1 + v 2 ) ∂ v 2 = 1 ,将结果写在 v2 v 2 指向 v3 v 3 的边上。
    我们再来求 v1v1=logv1v1=1x1=0.5 ∂ v 1 ∂ v − 1 = ∂ log ⁡ v − 1 ∂ v − 1 = 1 x 1 = 0.5 ,将结果写在 v1 v − 1 指向 v1 v 1 的边上。
    我们再来求 v2v1=(v1v0)v1=v0=5 ∂ v 2 ∂ v − 1 = ∂ ( v − 1 v 0 ) ∂ v − 1 = v 0 = 5 ,将结果写在 v1 v − 1 指向 v2 v 2 的边上。
    我们再来求 v2v0=(v1v0)v0=v1=2 ∂ v 2 ∂ v 0 = ∂ ( v − 1 v 0 ) ∂ v 0 = v − 1 = 2 ,将结果写在 v0 v 0 指向 v2 v 2 的边上。
    至此我们已经求出了所有步的偏导数的值,我们计算 y1x1 ∂ y 1 ∂ x 1 就是从 y1 y 1 开始,反向走回 x1 x 1 节点,可能有多条路径,对每一条路径,将每个边上的值连乘,最后将多条路径的值相加,即可求出 y1x1 ∂ y 1 ∂ x 1 的值。 y1x2 ∂ y 1 ∂ x 2 的值与此类似。
    如图所示,从 y1 y 1 走到 x1 x 1 共有两条路径,分别为:
    v5v3v1v1 v 5 → v 3 → v 1 → v − 1 110.5=0.5 1 ∗ 1 ∗ 0.5 = 0.5
    v5v3v2v1 v 5 → v 3 → v 2 → v − 1 115=5.0 1 ∗ 1 ∗ 5 = 5.0
    所以 y1x1=0.5+5.0=5.5 ∂ y 1 ∂ x 1 = 0.5 + 5.0 = 5.5
    用同样的方法我们可以计算 y1x2 ∂ y 1 ∂ x 2 的值。由 y1 y 1 y1x2 ∂ y 1 ∂ x 2 x2 x 2 的路径也有两条:
    v5v3v2v0 v 5 → v 3 → v 2 → v 0 112=2.0 1 ∗ 1 ∗ 2 = 2.0
    v5v4v0 v 5 → v 4 → v 0 (1)0.284=0.284 ( − 1 ) ∗ 0.284 = − 0.284
    所以 y1 y 1 y1x2=2.0+(0.284)=1.716 ∂ y 1 ∂ x 2 = 2.0 + ( − 0.284 ) = 1.716
    相对于正向模式而言,反向模式可以通过一次反向传输,就计算出所有偏导数,而这对于深度学习中的如多层感知器(MLP)模型来说,非常方便,而且中间的偏导数计算只需计算一次,减少了重复计算的工作量,当然这是以增加存储量需求为代价的。
    在本篇博文中,我们详细讲解了自动微分概念,自动微分概念是一个比较老的概念,但是将其引入深度学习领域,还是一个新鲜事务,这就是最近Yann Lecun提到的“深度学习已死,可微分编程永生”中的技术。在下一篇博文中,我们将向大家介绍自动微分在深度学习中的应用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值