一文搞懂飞桨静态图与动态图(从API分清描述式编程与命令式编程的区别)
写在前面
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下
拿一个最简单的全连接层为例:

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下:
为了跟静态图对比,这里也举全连接层的例子:

在早期的动态图中,用的是动态图的全连接层用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:目前飞桨官方在主推动态图,即命令式编程。如果您是新手,建议从动态图开始学习;如果您有一定的基础,可以尝试静态图。因为最后训练出来的模型肯定是需要部署的,目前使用用命令式编程(动态图)得到的模型文件不能很方便的部署,因此对部署有需求的话,建议使用静态图。
更多推荐


所有评论(0)