PyTorch和 TensorFlow等框架通过TensorFlow Fold支持动态计算图,并受到数据科学家的关注。
然而,似乎缺乏资源来帮助理解动态计算图。
动态计算图的优势似乎包括适应输入数据中不同数量的能力。似乎可能会自动选择层数、每层中的神经元数量、激活函数和其他 NN 参数,具体取决于训练期间的每个输入集实例。这是一个准确的表征吗?
动态模型比静态模型有什么优势?这就是 DCG 受到广泛关注的原因吗?总而言之,什么是 DCG,它们的使用优缺点是什么?
PyTorch和 TensorFlow等框架通过TensorFlow Fold支持动态计算图,并受到数据科学家的关注。
然而,似乎缺乏资源来帮助理解动态计算图。
动态计算图的优势似乎包括适应输入数据中不同数量的能力。似乎可能会自动选择层数、每层中的神经元数量、激活函数和其他 NN 参数,具体取决于训练期间的每个输入集实例。这是一个准确的表征吗?
动态模型比静态模型有什么优势?这就是 DCG 受到广泛关注的原因吗?总而言之,什么是 DCG,它们的使用优缺点是什么?
两个简短的答案
从理论的角度来看,简短的回答是......
动态计算图是一个可变系统,表示为操作之间数据流的有向图。它可以被可视化为包含由箭头连接的文本的形状,其中顶点(形状)表示对沿边缘(箭头)流动的数据的操作。
请注意,这样的图定义了数据流中的依赖关系,但不一定定义操作应用程序的时间顺序,如果没有额外的机制来指定时间优先级,则在图中的顶点或循环中保留状态可能会变得模棱两可。
从应用程序开发的角度来看,简短的回答是......
动态计算图框架是一个由库、接口和组件组成的系统,提供灵活的、程序化的运行时接口,通过连接有限但可能可扩展的操作集来促进系统的构建和修改。
PyTorch 框架
PyTorch 是 Torch 框架与 Python 语言和数据结构的集成。Torch 与 Theano、TensorFlow 和其他动态计算系统构建框架竞争。
——— 其他理解方法 ———
任意离散张量的任意计算结构
可用于构建计算系统的组件之一是旨在互连以创建神经网络的元素。这些的可用性支持深度学习和反向传播神经网络的构建。还可以构建涉及在任意定义的计算结构中处理潜在多维数据的组件组装的各种其他系统。
数据可以是标量值,例如浮点数、整数或字符串,也可以是这些值的正交聚合,例如向量、矩阵、立方体或超立方体。这些数据形式的泛化操作是离散张量,而将张量操作组装到工作系统中创建的结构是数据流。
理解动态计算概念的参考点
动态计算图并不是一个特别新的概念,尽管这个术语相对较新。计算机科学家对 DCG 的兴趣并不像数据科学家这个词那么新。尽管如此,该问题正确地指出,几乎没有可用的编写良好的资源(除了代码示例),可以从中了解围绕它们的出现和使用的整体概念。
开始理解 DCG 的一个可能参考点是命令设计模式,它是面向对象设计的支持者所推广的众多设计模式之一。命令设计模式将操作视为计算单元,其细节对触发它们的命令对象是隐藏的。命令设计模式通常与解释器设计模式结合使用。
在 DCG 的情况下,还涉及复合和外观设计模式,以促进即插即用离散张量操作的定义,这些操作可以以模式组装在一起以形成系统。
这种形成系统的设计模式的特殊组合实际上是一种软件抽象,它在很大程度上类似于导致冯诺依曼架构出现的激进思想,该架构是当今大多数计算机的核心。冯诺依曼对计算机出现的贡献是允许包含布尔逻辑、算术和分支的任意算法被表示和存储为数据——一个程序。
DCG 的另一个先驱是表达引擎。表达式引擎可以像算术引擎一样简单,也可以像 Mathematica 等应用程序一样复杂。规则引擎有点像 DCG,除了规则引擎是声明性的并且规则引擎的元规则在这些声明上运行。
程序操作程序
这些与 DCG 的共同点是可以在运行时定义要应用的数据流和操作。与 DCG 一样,这些软件库和应用程序中的一些具有 API 或其他机制,以允许将操作应用于功能细节。它本质上是一个程序允许操纵另一个程序的想法。
在原始级别理解此原理的另一个参考点是某些计算机语言中可用的 switch-case 语句。它是一种源代码结构,程序员基本上表达了“我们不确定必须做什么,但这个变量的值将告诉实时执行模型从一组可能性中做什么。”
switch-case 语句是一种抽象,它扩展了将关于计算方向的决定推迟到运行时的想法。它是现代 CPU 的控制单元内所做工作的软件版本,是延迟某些算法细节的概念的扩展。C 中的函子(函数指针)表或 C++、Java 或 Python 中的多态是其他原始示例。
动态计算进一步进行了抽象。它们将大部分(如果不是全部)计算规范和它们之间的关系推迟到运行时。这种全面的概括拓宽了在运行时进行功能修改的可能性。
计算的有向图表示
这就是动态计算模型。现在是图表部分。
一旦决定将要执行的操作的选择推迟到运行时,就需要一个结构来保存操作、它们的依赖关系以及可能的映射参数。这样的表示不仅仅是一棵句法树(例如表示源代码层次结构的树)。与汇编语言程序或机器代码不同,它必须是容易且任意可变的。它必须包含比数据流图和内存映射更多的信息。指定计算结构的数据结构必须是什么样的?
幸运的是,任何任意的、有限的、有界算法都可以表示为指定操作之间依赖关系的有向图。在这样的图中,顶点(在显示时通常表示为各种形状的节点)表示对数据执行的操作,而边(通常在显示时表示为箭头)是源自某些操作(或系统输入)的信息的数字表示以及其他操作(或系统输出)所依赖的。
请记住,有向图既不是算法(指定了精确的操作序列)也不是声明(数据可以显式存储,循环、分支、函数和模块可以定义和嵌套)。
这些动态计算图框架和库中的大多数都允许组件对支持机器学习的组件输入进行计算。有向图中的顶点可以是用于构建神经网络或支持微积分的组件的神经元模拟。这些框架提供了可用于更广义意义上的深度学习的构造的可能性。
在计算机历史的背景下
同样,到目前为止,没有任何东西对计算机科学来说是新的。LISP 允许其他算法修改计算示意图。广义的输入维度和数量被内置到许多长期存在的即插即用接口和协议中。学习框架的想法也可以追溯到 20 世纪中叶。
新的和越来越受欢迎的是集成功能和相关术语集的特定组合,每个功能的现有术语的聚合,为那些已经在软件行业学习和工作的人提供了更广泛的理解基础.
其中许多框架支持对不断变化的输入维度(维度的数量和每个维度的范围)的适应性。
与编译器中的抽象符号树的相似性
操作的输入和输出的依赖图也出现在抽象符号树 (AST) 中,一些更先进的编译器在解释源代码结构期间构建它。然后,AST 用于在与库链接并形成可执行文件的过程中生成汇编指令或机器指令。AST 是一个有向图,表示数据结构、执行的操作和源代码指定的控制流。
数据流只是操作之间的一组依赖关系,它必须是 AST 所固有的,才能使用 AST 在汇编程序或机器代码中创建精确遵循源代码中指定算法的执行指令。
与编译器中的 switch-case 语句或 AST 模型不同,动态计算图框架可以实时操作、优化、调整(如塑料人工网络)、反转、张量转换、抽取、修改以添加或删除熵,根据一组规则变异,或以其他方式转换为派生形式。它们可以存储为文件或流,然后从中检索。
对于 LISP 程序员或那些了解 John von Neumann 将操作规范存储为数据的建议本质的人来说,这是一个微不足道的概念。在后一种意义上,程序是一种数据流,通过编译器和操作系统来指示在 VLSI 数字电路中实现的动态计算系统。
实现可适应的维度和数量
问题是没有人的评论,“需要有数据集——其中的所有实例都具有相同的、固定数量的输入。” 这种说法并不能促进准确的理解。有更清晰的方式来说明输入适应性的真实性。
必须定义 DCG 和整个系统的其他组件之间的接口,但这些接口可能具有内置的动态维度或数量性。这是一个抽象的问题。
例如,离散张量对象类型表示特定的软件接口,而张量是一个动态数学概念,可以围绕它使用通用接口。离散张量可以是标量、向量、矩阵、立方体或超立方体,并且每个维度的因变量的范围可能是可变的。
动态计算图中定义的系统层中的节点数量可能是特定类型输入数量的函数,也可能是延迟到运行时的计算。
可以对框架进行编程以选择层结构(再次扩展 switch-case 范例)或计算定义结构大小和深度或激活的参数。然而,这些复杂的特性并不能使该框架成为动态计算图框架。
什么使框架能够支持动态计算图?
要获得动态计算图框架的资格,该框架必须仅支持将算法的确定推迟到运行时,因此为运行时计算依赖和数据流上的大量操作打开了大门。延迟操作的基础必须包括表示操作系统的有向图的规范、操作、执行和存储。
如果算法的规范没有推迟到运行时,而是编译成为特定操作系统设计的可执行文件,只有低级语言提供的传统灵活性,如 if-then-else、switch-case、多态性、数组函子和可变长度字符串,它被认为是一种静态算法。
如果操作、它们之间的依赖关系、数据流、流中数据的维数以及系统对输入数量和维数的适应性在运行时都是可变的,以创建一个高度自适应的系统,那么算法在这些方面是动态的。
同样,在 LISP 程序上运行的 LISP 程序、具有元规则功能的规则引擎、表达式引擎、离散张量对象库,甚至是相对简单的命令设计模式在某种意义上都是动态的,将某些特性推迟到运行时。DCG 在支持任意计算结构的能力方面灵活而全面,从而为深度学习实验和系统实施创造了丰富的环境。
何时使用动态计算图
DCG 的优缺点完全是针对特定问题的。如果您研究上述各种动态规划概念以及相关文献中可能与它们密切相关的其他概念,您是否需要动态计算图将变得很明显。
一般来说,如果您需要表示任意且不断变化的计算模型以促进深度学习系统、数学操作系统、自适应系统或其他能够很好地映射到 DCG 范式的灵活复杂的软件结构的实施,那么证明使用动态计算图框架的概念是定义问题解决方案的软件架构的良好第一步。
并非所有的学习软件都使用 DCG,但当对任意计算结构的系统且可能连续的操作是运行时要求时,它们通常是一个不错的选择。
简而言之,动态计算图可以解决一些静态图不能解决的问题,或者由于不允许批量训练而效率低下。
更具体地说,现代神经网络训练通常是分批进行的,即一次处理多个数据实例。一些研究人员选择批量大小,如 32、128,而其他研究人员使用大于 10,000 的批量大小。单实例训练通常很慢,因为它无法从硬件并行中受益。
例如,在自然语言处理中,研究人员希望用不同长度的句子训练神经网络。使用静态计算图,他们通常必须首先进行填充,即在较短句子的开头或结尾添加无意义的符号以使所有句子的长度相同。此操作使训练变得非常复杂(例如,需要屏蔽、重新定义评估指标、在那些填充符号上浪费大量计算时间)。使用动态计算图,不再需要填充(或仅在每个批次中需要)。
一个更复杂的例子是(使用神经网络)根据其解析树处理句子。由于每个句子都有自己的解析树,因此它们每个都需要不同的计算图,这意味着使用静态计算图进行训练只能允许单实例训练。与此类似的一个例子是递归神经网络。
动态计算图是具有更高抽象级别的简单修改的 CG。“动态”一词解释了这一切:数据如何流经图形取决于输入结构,即 DCG 结构是可变的而不是静态的。它的重要应用之一是在 NLP 神经网络中。
许多深度神经网络都有一个静态数据流图,这大致意味着它的计算结构(它的计算图)在不同的输入上保持稳定。这很好,因为我们可以利用这个特性来提高性能,例如通过小批量(一次处理一堆输入)。
但是一些神经网络可能对每个输入有不同的计算图。这会导致一些问题(批处理困难,图构建计算成本高),因此这些网络有点难以使用。
您链接的论文通过提出一种可以将多个计算图批处理为一个的方法来克服这个问题。然后,我们可以使用我们通常的 NN 技术。
好处是加速,这激励研究人员探索不同的结构并更具创造性。
动态计算图的优势似乎包括适应输入数据中不同数量的能力。似乎可能会自动选择层数、每层中的神经元数量、激活函数和其他 NN 参数,具体取决于训练期间的每个输入集实例。这是一个准确的表征吗?
这是不正确的。