什么是命令式编程?什么是符号式编程
ztj100 2024-11-11 15:14 19 浏览 0 评论
导读
在深度学习中,我们经常会学习和使用到各种框架,如Facebook的pytorch、Google的TensorFlow、亚马逊的MXNet等。这些框架编程分格主要可以分为三大类,命令式编程、符号式编程、混合式编程。这篇文章,我们就来介绍一下它们不同编程分格之间的特点。
命令式编程
Python的编程分格就是典型的命令式(imperative program)编程,在深度学习框架中pytorch就是用的命令式编程,下面我们使用命令式编程来写一段代码
def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = add(c, d) g = add(e, f) return g fancy_func(1, 2, 3, 4)
在调用fancy_func函数运行e=add(a,b)代码时,Python需要调用add方法做加法运算然后将运算结果保存到变量e中,然后再依次运行f=add(c,d)和g=add(e,f)代码。
通过上面的代码可以发现在调用fancy_func方法的时候,add函数被重复调用了3次,同时在调用add函数的时候,还需要开辟空间来存储e、f变量,即使后面没有使用到这些变量。因为我们不知道下面究竟会不会使用到这些变量,所以只有当fancy_func函数执行结束的时候,才会释放变量所占用的空间。
命令式编程的特点:
- 代码简洁明了,容易理解
- 执行效率低,不方便优化代码
- 可以获取中间结果,方便调试代码
符号式编程
符号式编程(symbolic program)框架的代表就是TensorFlow,除此之外还有Theano、Caffe。符号式编程需要在计算过程完全被定义好之后才被执行,通常符号式编程会根据下面这三个步骤进行:
- 定义计算流程
- 将计算流程编译成可执行的程序
- 给定输入,调用编译好的程序执行
下面我们来看一段符号式编程分格的代码
A = Variable('A') B = Variable('B') C = B * A D = C + Constant(1) # 编译函数 f = compile(D) d = f(A=np.ones(10), B=np.ones(10)*2)
在执行上面代码中的C=B?A时,并不会触发真正的数值计算,它会生成一个计算图
大部分的符号式编程都会有一个隐性或显性的编译步骤,只有编译之后的函数才能够调用,所以在上面的代码中只有最后一行才会触发数值计算。在编译的过程中,系统会自动对计算和内存做一些优化,而且符号式编程不会保存中间变量的结果,所以相对于命令式编程来说,符号式编程的计算效率和内存利用更高。除此之外,符号式编程可以将程序编译成一个与Python无关的函数,从而可以使程序在非Python环境下运行,避免Python解释器的性能问题。
符号式编程的特点:
- 执行效率高,代码不易看懂
- 无法保存中间变量,不方便调试
- 方便移植,可以跨平台和语言使用编译好的函数
- 符号式编程不支持循环和选择结构
混合编程
大部分的深度学习框架都是在命令式编程和符号式编程二选一,要么选择便于调试和开发的命令式编程要么选择执行高效的符号式编程。混合编程的目的就是命令式编程和符号式编程的长处,让开发者能够享受到命令式编程简洁特性同时能够享受到符号式编程的效率。
MXNet的gluon正是基于混合式编程的思想,用户可以使用纯命令式编程进行开发和调试,当用户需在部署时需要产品级的性能时可以将大部分命令式编程程序转换为符号式编程运行。
计算性能比较
最后,我们通过MXNet框架来实现一段代码体验一下命令式编程和符号式编程之间的性能差距。
from mxnet import nd,sym from mxnet.gluon import nn import time #创建一个容器用来定义网络结构 net = nn.HybridSequential() #定义一个三层全连接的网络结构 net.add(nn.Dense(256,activation="relu"), nn.Dense(128,activation="relu"), nn.Dense(2)) #初始化网络参数 net.initialize() #创建一个网络的输出值 x = nd.random.normal(shape=(1,512)) def eval_fun(net,x): start_time = time.time() for i in range(1000): _ = net(x) #等待所有计算完成 nd.waitall() #统计程序运行时间 return time.time() - start_time print("imperative programe consume time:{:.4f}".format(eval_fun(net,x))) #将程序转变为符号式编程 net.hybridize() print("symbolic programe consume time:{:.4f}".format(eval_fun(net,x))) """ imperative programe consume time:0.2620 symbolic programe consume time:0.1610 """
通过上面程序可以发现,上面程序仅仅只是测试了前向传播,符号式编程的运行速度要比命令式编程快0.1s左右,而且上面只是一个三层的网络也仅仅只是迭代了1000次,实际应用的网络结构会比这个复杂的多,当数据比较多时迭代次数也会远远大于1000,实际运行能节省的时间远不止这么一点。
相关推荐
- 这个 JavaScript Api 已被废弃!请慎用!
-
在开发过程中,我们可能会不自觉地使用一些已经被标记为废弃的JavaScriptAPI。这些...
- JavaScript中10个“过时”的API,你的代码里还在用吗?
-
JavaScript作为一门不断发展的语言,其API也在持续进化。新的、更安全、更高效的API不断涌现,而一些旧的API则因为各种原因(如安全问题、性能瓶颈、设计缺陷或有了更好的替代品)被标记为“废...
- 几大开源免费的 JavaScript 富文本编辑器测评
-
MarkDown编辑器用的时间长了,发现发现富文本编辑器用起来是真的舒服。...
- 比较好的网页里面的 html 编辑器 推荐
-
如果您正在寻找嵌入到网页中的HTML编辑器,以便用户可以直接在网页上编辑HTML内容,以下是几个备受推荐的:CKEditor:CKEditor是一个功能强大的、开源的富文本编辑器,可以嵌入到...
- Luckysheet 实现excel多人在线协同编辑
-
前言前些天看到Luckysheet支持协同编辑Excel,正符合我们协同项目的一部分,故而想进一步完善协同文章,但是遇到了一下困难,特此做声明哈,若侵权,请联系我删除文章!若侵犯版权、个人隐私,请联系...
- 从 Element UI 源码的构建流程来看前端 UI 库设计
-
作者:前端森林转发链接:https://mp.weixin.qq.com/s/ziDMLDJcvx07aM6xoEyWHQ引言...
- 手把手教你如何用 Decorator 装饰你的 Typescript?「实践」
-
作者:Nealyang转发连接:https://mp.weixin.qq.com/s/PFgc8xD7gT40-9qXNTpk7A...
- 推荐五个优秀的富文本编辑器
-
富文本编辑器是一种可嵌入浏览器网页中,所见即所得的文本编辑器。对于许多从事前端开发的小伙伴来说并不算陌生,它的应用场景非常广泛,平时发个评论、写篇博客文章等都能见到它的身影。...
- 基于vue + element的后台管理系统解决方案
-
作者:林鑫转发链接:https://github.com/lin-xin前言该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(WebManagementSystem)开发。基于v...
- 开源富文本编辑器Quill 2.0重磅发布
-
开源富文本编辑器Quill正式发布2.0版本。官方TypeScript声明...
- Python之Web开发框架学习 Django-表单处理
-
在Django中创建表单实际上类似于创建模型。同样,我们只需要从Django类继承,则类属性将是表单字段。让我们在myapp文件夹中添加一个forms.py文件以包含我们的应用程序表单。我们将创建一个...
- Django测试入门:打造坚实代码基础的钥匙
-
这一篇说一下django框架的自动化测试,...
- Django ORM vs SQLAlchemy:到底谁更香?从入门到上头的选择指南
-
阅读文章前辛苦您点下“关注”,方便讨论和分享,为了回馈您的支持,我将每日更新优质内容。...
- 超详细的Django 框架介绍,它来了!
-
时光荏苒,一晃小编的Tornado框架系列也结束了。这个框架虽然没有之前的FastAPI高流量,但是,它也是小编的心血呀。总共16篇博文,从入门到进阶,包含了框架的方方面面。虽然小编有些方面介绍得不是...
- 20《Nginx 入门教程》使用 Nginx 部署 Python 项目
-
今天的目标是完成一个PythonWeb项目的线上部署,我们使用最新的Django项目搭建一个简易的Web工程,然后基于Nginx服务部署该PythonWeb项目。1.前期准备...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)