一文搞懂飞桨静态图与动态图(从API分清描述式编程与命令式编程的区别)

您所在的位置:网站首页 静态图 一文搞懂飞桨静态图与动态图(从API分清描述式编程与命令式编程的区别)

一文搞懂飞桨静态图与动态图(从API分清描述式编程与命令式编程的区别)

2024-01-24 20:48| 来源: 网络整理| 查看: 265

写在前面

PaddlePaddle即飞桨,我在学习这个框架的过程中,其实是很迷的,迷惑的地方就在它的静态图与动态图。于是,我打算好好整理整理,把两者的特点给大家解析一下,让新入门的开发者少走弯路。

关于飞桨的版本静态图动态图

在这里插入图片描述

1. 关于飞桨的版本

我查阅了飞桨的文档,PaddlePaddle1.3版本是没有动态图这个概念的,从PaddlePaddle1.4才开始出现动态图: 在这里插入图片描述 因此,要使用飞桨的动态图,或者说命令式编程时,飞桨的版本一定要在1.4以上

在开始之前,我再多提一句:

静态图: 描述(声明)式编程动态图: 命令式编程

从编程范式上说,飞桨兼容支持声明式编程和命令式编程,通俗地讲即静态图和动态图。其实飞桨本没有图的概念,在飞桨的设计中,把一个神经网络定义成一段类似程序的描述,也就是用户在写程序的过程中,就定义了模型表达及计算。

在静态图的控制流实现方面,飞桨借助自己实现的控制流OP而不是python原生的if else和for循环,这使得在飞桨中的定义的program即一个网络模型,可以有一个内部的表达,是可以全局优化编译执行的。

考虑到开发者更愿意使用python原生控制流,飞桨也做了支持,并通过解释方式执行,这就是命令式编程模式。

但整体上,这两种编程范式是相对兼容统一的。飞桨将持续发布更完善的命令式编程功能,同时保持更强劲的性能。

2. 静态图

代码示例:

import paddle.fluid as fluid import numpy as np x_np = np.random.rand(1).astype("float32") y_np = np.random.rand(1).astype("float32") x = fluid.data( shape=[1], name="x", dtype="float32") y = fluid.data( shape=[1], name="y", dtype="float32") z = fluid.layers.cond( x > y, \lambda: x + y, lambda: x -y) exe = fluid.Executor() out = exe.run(fluid.default_main_program(), feed={ "x" : x_np, "y" : y_np}, fetch_list=[z]) print( out )

在飞桨API文档里,可以这么理解,静态图在网络结构定义的方法在fluid.layers下

文档链接: https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/layers_cn.html

拿一个最简单的全连接层为例:

静态图全连接层API文档链接: https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/layers_cn/fc_cn.html

在这里插入图片描述 fluid.layers下的api不全是静态图的方法,但是,在模型结构定义时,全连接层fc、卷积层conv2d等等这些都是静态图的api

现在你可能还是比较懵,没关系,我们继续往下看

3. 动态图

代码示例:

import paddle.fluid as fluid import numpy as np fluid.enable_imperative() x_np = np.random.rand(1).astype("float32") y_np = np.random.rand(1).astype("float32") x = fluid.dygraph.to_variable( x_np ) y = fluid.dygraph.to_variable( y_np ) z = x + y if x > y else x -y print(z.numpy())

在飞桨的官方文档里,动态图的网络结构定义的方法都在fluid.dygraph下:

文档链接: https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/dygraph_cn.html

为了跟静态图对比,这里也举全连接层的例子: 在这里插入图片描述 在早期的动态图中,用的是动态图的全连接层用FC表示,但是目前最新的PaddlePaddle1.8已经不使用FC,而是改成Linear: https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/dygraph_cn/Linear_cn.html#cn-api-fluid-dygraph-linear 在这里插入图片描述 写到这里,我想说的是: 动态图和静态图乍一看好像是两种东西,但实际上,对于网络结构而言,都是全连接层的情况下,一个是fc,另一个是Linear,表面上换了一个名称,但实际上,你可以认为两者在实现的效果上是一样的,只不过写法不同罢了。

将静态图和动态图放在一起对比

在这里插入图片描述 飞桨的文档里,对于静态图和动态图的API没有一个整体的概括,这里我给总结一下:

如果你要使用静态图(描述式编程),请在fluid.layers里选择你需要的网络结构,如fc,conv2d,pool2d等如果你要使用动态图(命令是编程),请在fluid.dygraph里选择你需要的网络结构,如Linear,Conv2D,Pool2D等

如果你想更加深入地了解静态图与动态图的区别,您可以在AI Studio上查看该项目: https://aistudio.baidu.com/aistudio/projectdetail/671871

我用自建的手写数字数据集做了一个案例,其中,我对动态图和静态图的写法都做了尝试。

Q&A

Q:作为新手,我应该如何选择?使用静态图好还是动态图好? A:目前飞桨官方在主推动态图,即命令式编程。如果您是新手,建议从动态图开始学习;如果您有一定的基础,可以尝试静态图。因为最后训练出来的模型肯定是需要部署的,目前使用用命令式编程(动态图)得到的模型文件不能很方便的部署,因此对部署有需求的话,建议使用静态图。



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3