打造属于自己的TensorFlow(一)之SimpleFlow-计算图与前向传播

前段时间因为课题需要使用了一段时间TensorFlow,感觉这种框架很有意思,除了可以搭建复杂的神经网络,也可以优化其他自己需要的计算模型,所以一直想自己学习一下写一个类似的图计算框架。前几天组会开完决定着手实现一个模仿TensorFlow接口的简陋版本图计算框架以学习计算图程序的编写以及前向传播和反向传播的实现。目前实现了前向传播和反向传播以及梯度下降优化器,并写了个优化线性模型的例子。

代码放在了GitHub上,取名SimpleFlow, 仓库链接:
https://github.com/PytLab/simpleflow

虽然前向传播反向传播这些原理了解起来并不是很复杂,但是真正着手写起来才发现,里面还是有很多细节需要学习和处理才能对实际的模型进行优化(例如Loss函数对每个计算节点矩阵求导的处理)。其中SimpleFlow的代码并没有考虑太多的东西比如dtype和张量size的检查等,因为只是为了实现主要图计算功能并没有考虑任何的优化,
内部张量运算使用的Numpy的接口(毕竟是学习和练手的目的嘛)。好久时间没更新博客了,在接下来的几篇里面我将把实现的过程的细节总结一下,希望可以给后面学习的童鞋做个参考。

正文

本文主要介绍计算图以及前向传播的实现, 主要涉及图的构建以及通过对构建好的图进行后序遍历然后进行前向传播计算得到具体节点上的输出值。

先贴上一个简单的实现效果吧:
在这里插入图片描述

计算图(Computational Graph)

计算图是计算代数中的一个基础处理方法,我们可以通过一个有向图来表示一个给定的数学表达式,并可以根据图的特点快速方便对表达式中的变量进行求导。而神经网络的本质就是一个多层复合函数, 因此也可以通过一个图来表示其表达式。

本部分主要总结计算图的实现,在计算图这个有向图中,每个节点代表着一种特定的运算例如求和,乘积,向量乘积,平方等等… 例如求和表达式 f ( x , y ) = x + y f(x,y)=x+y f(x,y)=x+y使用有向图表示为:

表达式 f ( x , y , z ) = z ( x + y ) f(x,y,z)=z(x+y) f(x,y,z)=z(x+y)使用有向图表示为:

与TensorFlow的实现不同,为了简化,在SimpleFlow中我并没有定义Tensor类来表示计算图中节点之间的数据流动,而是直接定义节点的类型,其中主要定义了四种类型来表示图中的节点:

Operation: 操作节点主要接受一个或者两个输入节点然后进行简单的操作运算,例如上图中的加法操作和乘法操作等。
Variable: 没有输入节点的节点,此节点包含的数据在运算过程中是可以变化的。
Constant: 类似Variable节点,也没有输入节点,此节点中的数据在图的运算过程中不会发生变化
Placeholder: 同样没有输入节点,此节点的数据是通过图建立好以后通过用户传入的
其实图中的所有节点都可以看成是某种操作,其中Variable, Constant, Placeholder都是一种特殊的操作,只是相对于普通的Operation而言,他们没有输入,但是都会有输出(像上图中的xx, yy节点,他们本身输出自身的值到++节点中去),通常会输出到Operation节点,进行进一步的计算。

下面我们主要介绍如何实现计算图的基本组件: 节点和边。

Operation节点
节点表示操作,边代表节点接收和输出的数据,操作节点需要含有以下属性:

input_nodes: 输入节点,里面存放与当前节点相连接的输入节点的引用
output_nodes: 输出节点, 存放以当前节点作为输入的节点,也就是当前节点的去向
output_value: 存储当前节点的数值, 如果是Add节点,此变量就存储两个输入节点output_value的和
name: 当前节点的名称
graph: 此节点所属的图
下面我们定义了Operation基类用于表示图中的操作节点(详见https://github.com/PytLab/simpleflow/blob/master/simpleflow/operations.py):
在这里插入图片描述
在初始化方法中除了定义上面提到的属性外,还需要进行两个操作:

将当前节点的引用添加到他输入节点的output_nodes这样可以在输入节点中找到当前节点。
将当前节点的引用添加到图中,方便后面对图中的资源进行回收等操作
另外,每个操作节点还有两个必须的方法: comput_output和compute_gradient. 他们分别负责根据输入节点的值计算当前节点的输出值和根据操作属性和当前节点的值计算梯度。关于梯度的计算将在后续的文章中详细介绍,本文只对节点输出值的计算进行介绍。

下面我以求和操作为例来说明具体操作节点的实现:

在这里插入图片描述

可见,计算当前节点output_value的值的前提条件就是他的输入节点的值在此之前已经计算得到了。

Variable节点
与Operation节点类似,Variable节点也需要output_value, output_nodes等属性,但是它没有输入节点,也就没有input_nodes属性了,而是需要在创建的时候确定一个初始值initial_value:

在这里插入图片描述

Constant节点和Placeholder节点
Constant和Placeholder节点与Variable节点类似,具体实现详见: https://github.com/PytLab/simpleflow/blob/master/simpleflow/operations.py

计算图对象
在定义了图中的节点后我们需要将定义好的节点放入到一个图中统一保管,因此就需要定义一个Graph类来存放创建的节点,方便统一操作图中节点的资源。
在这里插入图片描述

为了提供一个默认的图,在导入simpleflow模块的时候创建一个全局变量来引用默认的图:
在这里插入图片描述

为了模仿TensorFlow的接口,我们给Graph添加上下文管理器协议方法使其成为一个上下文管理器, 同时也添加一个as_default方法:
在这里插入图片描述

这样在进入with代码块之前先保存旧的默认图对象然后将当前图赋值给全局图对象,这样with代码块中的节点默认会添加到当前的图中。最后退出with代码块时再对图进行恢复即可。这样我们可以按照TensorFlow的方式来在某个图中创建节点.

Ok,根据上面的实现我们已经可以创建一个计算图了:
在这里插入图片描述

前向传播(Feedforward)
实现了计算图和图中的节点,我们需要对计算图进行计算, 本部分对计算图的前向传播的实现进行总结。

会话
首先,我们需要实现一个Session来对一个已经创建好的计算图进行计算,因为当我们创建我们之前定义的节点的时候其实只是创建了一个空节点,节点中并没有数值可以用来计算,也就是output_value是空的。为了模仿TensorFlow的接口,我们在这里也把session定义成一个上下文管理器:
在这里插入图片描述

计算某个节点的输出值
上面我们已经可以构建出一个计算图了,计算图中的每个节点与其相邻的节点有方向的联系起来,现在我们需要根据图中节点的关系来推算出某个节点的值。那么如何计算呢? 还是以我们刚才¥f(x,y,z)=z(x+y)$的计算图为例,

若我们需要计算橙色××运算节点的输出值,我们需要计算与它相连的两个输入节点的输出值,进而需要计算绿色++的输入节点的输出值。我们可以通过后序遍历来获取计算一个节点所需的所有节点的输出值。为了方便实现,后序遍历我直接使用了递归的方式来实现:
在这里插入图片描述

通过此函数我们可以获取计算一个节点值所需要所有节点列表,再依次计算列表中节点的输出值,最后便可以轻易的计算出当前节点的输出值了。
在这里插入图片描述

例子

上面我们实现了计算图以及前向传播,我们就可以创建计算图计算表达式的值了, 如下:厦门二手叉车租赁

WX20180125-201021@2x

在这里插入图片描述

输出值:
在这里插入图片描述

总结

本文使用Python实现了计算图以及计算图的前向传播,并模仿TensorFlow的接口创建了Session以及Graph对象。下篇中将继续总结计算图节点计算梯度的方法以及反向传播和梯度下降优化器的实现。

以上转载自:
https://www.cnblogs.com/xyou/p/8359222.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最新版本,请从Simpleflow官方站点下载 http://www.simpleflow.com.cn 此版本已不是最新版本,请注意查看最新版本 ×××××××××××××××××××××××× 如果SimpleFlow并不能满足你对工作流的需求,请留言,你所需要的工作流的功能,谢谢 如果你想了解如何使用Simpleflow进行工作流开发,请随时与我交流 希望您在免费下载的同时,留下你的MSN,或加Simpleflow@163.com ×××××××××××××××××××××××× Simpleflow 工作流开发套件 CS版 如果你有一定的BS开发功底,可以很简单的改造成BS,因为所有流程驱动都是用后台类驱动。 Simpleflow的最终目的是开发成CS、BS并行的工作流套件。目正在努力中。。。 同一个流程实例,按用户喜好,既可以在CS审批,也可以在BS审批。 如果这个套件对您有帮助,请多关注并支持Simpleflow,同时,希望能够加Simpleflow为MSN好友 如果您有更好的点子或功能需求,请随时与Simpleflowf交流 QQ:935139121 MSN Simpleflow@163.com 关于Simpleflow的信息,请关注 Simpleflow的Blog http://blog.csdn.net/simpleflow/ Simpleflow的发布空间 http://download.csdn.net/user/simpleflow 此数据包中的内容 1.Application.nsf 工作流应用库(工作流运行库,三个流程定义中,外出申请可以实际运行,其它为示意流程,不能实际运行) 2.Process.nsf 流程定义库(附加三个经过测试的简单流程定义) 3.Organization.nsf 组织库(附加一个模拟企业的人员及组织信息,您可以在个人信息档中更改NotesID,进行测试) 4.FlowArchive/Archive_Out.nsf 外出流程的归档库 --------------------------------------------------------------------------- 配置 数据库签名 请用管理员[SysAdmin]角色登陆,并配置每个库的 系统设置档,并更新相关路径信息。 (原来没有参数的栏位,目不需配置,因为目还没用到) regist users文档用于在你的测试服务器上注册符合Organization.nsf的Notes 用户 用户需要注册在根Cert /World下 ------------------------------------------------------------------------------ ================================================================================== 版权声明 Simpleflow是一个免费套件,且没有收费的计划 如果您想将Simpleflow应用于生产环境,请邮件告知Simpleflow@163.com,开发团队只想了解Simpleflow的应用情况 并请及时反馈测试与使用过程中发生的问题。 Simpleflow开发团队保留所有权利 =====================================================================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值