书面文章|每月
更新| Zhao Luyang
先前的“ AI Talk:Push BP”谈论了向后传播的数学原理。本文以Oneflow代码为例,以列出Autograph模块的实现详细信息。
1
首先查看下面的简单示例:
正向通行证可以对应于下面的计算图:
图1
那与以下公式相对应:
根据上一篇文章“ AI Talk:Push BP”,很容易手动计算X的梯度值,即:
X1,X2和X3的计算过程相似,我不会详细介绍。让我们看一下Oneflow的执行结果。打印的执行(X.Grad)可以获取以下输出:
可以看出,结果与先前公式(3)的计算结果一致。以下由特定代码实现实现,以分析OneFlow的亲笔签名模块。
2
上面示例中Python末端的向后接口称为Python/One/Framework/Tensor.py中的_backward接口:
可以看出,向后仅支持急切的模式。这是因为在图形静态图模式中,计算图已提前编译,并且不需要手动传递.backward()调用。Flow.autagraphy.backward()将调用oneflow/api/python/python/python/afteragraph.cpp.cpp方法:反向方法:
从pybind定义的角度来看,总共两个接口(Aptraph.backward and Actograph.grad)导出了总共两个接口。它们是对所有必需的true的所有必需属性的渐变。GRAD仅找到指定叶节点的梯度。该原理在同一文件中是相同的。背向函数:
getThreadLocalautography()可以将其视为thread_local的一个示例,位于oneflow/core/core/actopraph/actopraph/promograph_engine.cpp中,并返回签名引擎(签名)对象的指针:
Autopradengine是Oneflow签名的核心数据结构。它的继承关系如下:
图2
签名引擎的子类实现此处具有基于堆栈的基于图形的实现,默认情况下使用Graphic Grunsographengine。从以前的代码中可以看到AS,通过调用RephBackwardSaveGradS4LeaeFeftEnsor,可以从先前的代码中看到AS位于oneflow/core/tocraph/aptrophing_engine.cpp中:l315:l315:
这确实输入了亲笔签名模块的内部处理过程,并以后继续进行分析。
3
执行向后通过时,执行了反向图。反图中的节点是在正向通行期间建立的。每个节点称为函数表。主要数据结构如下:
图3
让我们来谈谈图3中的功能节点(oneflow/core/rotagraph/apuroph_engine.h:l42),包括三个数据的三个数据成员的三个数据成员的三个数据成员的三个数据成员的三个数据成员三个数据成员的三个数据成员的三个数据成员的成员。几个数据成员的主要数据成员:
我们使用的是GraphFunctionNod(oneflow/core/tocraph/apatograph_engine.cpp:l178)
可以看出,它主要初始化功能节目中的重要数据成员。其中,从相应的输入和输出张量获得了签名和output_data_data_data -_data_dameta信息。张量保留了一个张量对象指针,张量是一个自动载体对象。
.cpp:l86),将创建此反向函数:
可以看出,反向图表节点的名称由带有_backward后缀的OP的类型名称组成,用于使用addNode方法创建函数(oneflow/core/core/ucogram/utogram/program/program/programs/promograph_engine.cpp:l356)。
可以看出,函数节点悬挂在张量上。通过张量的set_grad_fn_node接口将其维护到张量的数据结构中。在“ Oneflow学习注释:一致观点的概念和实现”中,张量的继承关系图存储在Tensorif中,保存在Tensorif.middle中:
图4
在这一点上,函数节点中每个成员的作用和起源已经清楚。如果将图1中的图1用作绘制相应反向图的示例,如下图所示:
图5
计算出的梯度值将放置在output_meta_data_data中的Autographmeta中。
4
第3节中列出的最后一个代码,两个最重要的词是:
这是Graph_task是GraphTask类型。这是一个非常重要的数据结构,用于安排反向图表中所有函数节点的执行。以下列表由其主要成员列出:
首先查看本节开头的graph_task.computemptipementencies。它主要是初始化的依赖项_此地图。该地图维护每个函数演奏的输入信息,然后查看graph_task.apply.euph函数名称,并在当前函数节点(oneflow/core/core/actopraph/atopraph/atapraph_engine.cpp:l287)上执行各种操作。
这里最重要的是以下两个句子:
让我们一一分析它。首先,查看Node-> Apply(oneflow/core/contraph/autogram_engine.cpp:l143)。首先,output_meta_data_初始化为反向函数的输入,并调用反向函数以找到梯度值。,它们在input_grads中暂时存在的梯度值,然后更新为input_meta_data_::
查看node-> accgrad4LeaftEnsor。此功能最终将调用copyoaccgrad。当多个迷你批次时,它主要用于在多个微型批次之间累积梯度值。当前梯度值的处理:
(特别感谢同事在本文中提出的各种问题和混乱。本文主要提到代码:https://github.com/oneflow-icow/oneflow/commit/a414444444444f9ecb7e85ad07359bfebbeb05e1)
欢迎体验Oneflow v0.7.0的最新版本:https://github.com/oneflow-ic/oneflow/
原始:https://juejin.cn/post/7097062696083783716