0
点赞
收藏
分享

微信扫一扫

从零实现深度学习框架——自动求导神器计算图


引言

本着“凡我不能创造的,我就不能理解”的思想,​​本系列​​文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。

要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽量不适用外部完备的框架前提下,实现我们想要的模型。​​本系列​​​文章的宗旨就是通过这样的过程,让大家切实掌握深度学习底层实现,而不是仅做一个调包侠。
本系列文章首发于微信公众号:JavaNLP

本文介绍自动求导的基础知识——计算图。

计算图

我们知道,反向传播是模型训练的途径。而反向传播是基于求导的,有没有想过像Keras和PyTorch这种工具是如何做到自动求导的。答案就是计算图,只要掌握了计算图的知识,我们就能自己开发一个自动求导工具。

计算图是一种描述函数的工具,可以可视化为有向图结构。其中节点为Tensor(向量/张量),有向边为操作。

在深度学习中比较常见的例子是类似

从零实现深度学习框架——自动求导神器计算图_反向传播

从零实现深度学习框架——自动求导神器计算图_反向传播_02

​x​​​可以看成是输入,​​y​​可以看成是输出,中间经过了3次变换。

有时我们的函数有多个参数(比如乘法就有两个参数),假设我们要计算从零实现深度学习框架——自动求导神器计算图_反向传播_03​,它的计算图如下:

从零实现深度学习框架——自动求导神器计算图_深度学习_04

这里令从零实现深度学习框架——自动求导神器计算图_计算图_05,为了完整性,也画出了常量从零实现深度学习框架——自动求导神器计算图_损失函数_06

有了这个计算图,我们就就可以很容易的计算出从零实现深度学习框架——自动求导神器计算图_反向传播_07的值。比如令从零实现深度学习框架——自动求导神器计算图_损失函数_08

从零实现深度学习框架——自动求导神器计算图_计算图_09

当然,我们这么辛苦的画出这个图,主要不是为了沿着箭头方向进行计算的。而是为了求导,也就是计算梯度。

计算图上的梯度

回顾一下链式法则

从零实现深度学习框架——自动求导神器计算图_反向传播_10

从零实现深度学习框架——自动求导神器计算图_计算图_11

我们重点来看下多路径的链式法则,即上面说的全导数。

我们要计算从零实现深度学习框架——自动求导神器计算图_反向传播_03从零实现深度学习框架——自动求导神器计算图_损失函数_13

从零实现深度学习框架——自动求导神器计算图_计算图_05

类似上图中的从零实现深度学习框架——自动求导神器计算图_深度学习_15从零实现深度学习框架——自动求导神器计算图_反向传播_16也影响了两个因子。因此有
从零实现深度学习框架——自动求导神器计算图_计算图_17
要计算偏导数,我们先把每个箭头的偏导数计算出来。

从零实现深度学习框架——自动求导神器计算图_反向传播_18

我们先填入计算出来的式子:

从零实现深度学习框架——自动求导神器计算图_神经网络_19

根据从零实现深度学习框架——自动求导神器计算图_损失函数_20以及求导公式不难得到上面的结果。

此时,要计算从零实现深度学习框架——自动求导神器计算图_损失函数_13,只需要找出所有从从零实现深度学习框架——自动求导神器计算图_反向传播_16从零实现深度学习框架——自动求导神器计算图_反向传播_07到路径,然后把相同路径上的值相乘,不同路径上的值相加(连线相乘,分线相加)。

就可以得到:从零实现深度学习框架——自动求导神器计算图_深度学习_24

此时,代入从零实现深度学习框架——自动求导神器计算图_损失函数_08

先计算出从零实现深度学习框架——自动求导神器计算图_计算图_26,再计算从零实现深度学习框架——自动求导神器计算图_神经网络_27,所以从零实现深度学习框架——自动求导神器计算图_深度学习_28

反向模式

如果要同时计算从零实现深度学习框架——自动求导神器计算图_反向传播_07从零实现深度学习框架——自动求导神器计算图_计算图_30从零实现深度学习框架——自动求导神器计算图_反向传播_16的偏导数,我们需要反向模式(Reverse mode)来同时计算它们。

从零实现深度学习框架——自动求导神器计算图_深度学习_32

反向就是从顶点开始,这里从从零实现深度学习框架——自动求导神器计算图_反向传播_07开始,也从梯度等于从零实现深度学习框架——自动求导神器计算图_损失函数_06开始。

从顶点到从零实现深度学习框架——自动求导神器计算图_反向传播_16,通过有两条路径,如山古同橙色箭头所示。达到从零实现深度学习框架——自动求导神器计算图_计算图_36时的梯度为从零实现深度学习框架——自动求导神器计算图_深度学习_37;到达从零实现深度学习框架——自动求导神器计算图_损失函数_38时的梯度为从零实现深度学习框架——自动求导神器计算图_计算图_39

从零实现深度学习框架——自动求导神器计算图_计算图_36从零实现深度学习框架——自动求导神器计算图_损失函数_38从零实现深度学习框架——自动求导神器计算图_反向传播_16的梯度都是从零实现深度学习框架——自动求导神器计算图_损失函数_06。根据相同路径相乘,不同路径相加。到从零实现深度学习框架——自动求导神器计算图_反向传播_16到梯度为从零实现深度学习框架——自动求导神器计算图_神经网络_45

从零实现深度学习框架——自动求导神器计算图_神经网络_46

此时,计算从零实现深度学习框架——自动求导神器计算图_反向传播_07从零实现深度学习框架——自动求导神器计算图_计算图_30的就简单了,我们已经知道了从零实现深度学习框架——自动求导神器计算图_反向传播_07从零实现深度学习框架——自动求导神器计算图_计算图_36到梯度为从零实现深度学习框架——自动求导神器计算图_反向传播_51,由于从零实现深度学习框架——自动求导神器计算图_反向传播_07从零实现深度学习框架——自动求导神器计算图_计算图_30只有一条路径,因此直接相乘得从零实现深度学习框架——自动求导神器计算图_神经网络_54

如果你的函数只有一个输出,由需要同时计算大量的不同值的偏导数时,用反向模式就比较快。

而这恰恰非常适合于我们计算损失函数的梯度,因为损失函数的输出就是一个标量。

总结

我们已经了解了计算图的基础知识,下篇文章就来看一下常见操作的计算图。


举报

相关推荐

0 条评论