函数求值需要运行所有线程_精读《深度学习 - 函数式之美》

7793ac035f5378b112ea02ec086ceffc.png

1 引言

函数式语言在深度学习领域应用很广泛,因为函数式与深度学习模型的契合度很高,The Beauty of Functional Languages in Deep Learning — Clojure and Haskell 就很好的诠释了这个道理。

通过这篇文章可以加深我们对深度学习与函数式编程的理解。

2 概述与精读

深度学习是机器学习中基于人工神经网络模型的一个分支,通过模拟多层神经元的自编码神经网络,将特征逐步抽象化,这需要多维度、大数据量的输入。TensorFlow 和 PyTorch 是比较著名的 Python 深度学习框架,同样 Keras 在 R 语言中也很著名。然而在生产环境中,基于 性能和安全性 的考虑,一般会使用函数式语言 Clojure 或 Haskell。

在生产环境中,可能要并发出里几百万个参数,因此面临的挑战是:如何高效、安全的执行这些运算。

所以为什么函数式编程语言可以胜任深度学习的计算要求呢? 深度学习的计算模型本质上是数学模型,而数学模型本质上和函数式编程思路是一致的:数据不可变且函数间可以任意组合。这意味着使用函数式编程语言可以更好的表达深度学习的计算过程,因此更容易理解与维护,同时函数式语言内置的 Immutable 数据结构也保障了并发的安全性。

另外函数式语言的函数之间都是相互隔离的,即便在多线程环境下也不会发生竞争和死锁的情况,函数式编程语言会自动处理这些情况。

比如说 Clojure,它甚至可在两个同时修改同一引用的程序并发运行时,自动重试其中之一,而不需要手动加锁

(import ‘(java.util.concurrent Executors))
(defn test-stm [nitems nthreads niters](let [refs (map ref (repeat nitems 0))pool (Executors/newFixedThreadPool nthreads)tasks (map (fn [t](fn [](dotimes [n niters](dosync(doseq [r refs](alter r + 1 t))))))(range nthreads))](doseq [future (.invokeAll pool tasks)](.get future))(.shutdown pool)(map deref refs)))
(test-stm 10 10 10000) -> (550000 550000 550000 550000 550000 550000 550000 550000 550000 550000)

上面的代码创建了引用(refs),同时创建了多个线程自增这个引用对象,按理说每个线程都修改这个引用会导致竞争状态出现,但从结果来看是正常的,说明 Clojure 引擎在执行时会自动解决这个问题。实际上当两个线程出现竞争而失败时,Clojure 会自动重试其中之一。

原文介绍

Clojure 的另一个优势是并行效率高:

(defn calculate-pixels-2 [](let [n (* *width* *height*)work (partition (/ n 16) (range 0 n))result (pmap (fn [x](doall (map(fn [p](let [row (rem p *width*) col (int (/ p *height*))](get-color (process-pixel (/ row (double *width*)) (/ col (double *height*))))))x)))work)](doall (apply concat result))))

使用 partition 结合 pmap 可以使并发效率达到最大化,也就是 CPU 几乎都消耗在实际计算上,而不是并行的任务管理与上下文切换。Clojure 凭借 partition 对计算进行分区,采取分而治之并对分区计算结果进行合并的思路优化了并发性能。

原文介绍

Clojure 另一个特性是函数链式调用:

;; pipe arg to function
(-> "x" f1) ; "x1";; pipe. function chaining
(-> "x" f1 f2) ; "x12"

其中 (-> "x" f1 f2) 等价于 f2(f1("x")),这种描述不仅更简洁清晰,也更接近于实际数学模型。

原文介绍

最后,Clojure 还具备计算安全性,计算过程不会修改已有的数据,因此在神经网络的任何一层的原始值都会保留,每层计算都可以独立运行且函数永远幂等。

Haskell 也有独特的优势,它具有类型推断、惰性求值等特性,被认为更适合用于机器学习。

类型推断即 Haskell 类型都是静态的,如果试图赋予错误的类型会报错。

Haskell 的另一个优势是可以非常清晰的描述数学模型。

想想一般数学模型是怎么描述函数的:

fn =>f1 = 1f2 = 9f3 = 16n > 2, fn = 3fn-3 + 2fn-2 + fn-1

一般语言用 if-else 描述等价关系,但 Haskell 可以几乎原汁原味的还原函数定义过程:

solve :: Int -> Interger
solve 1 = 1
solve 2 = 9
solve 3 = 16
solve n = 3 * solve (n - 3) + 2 * solve (n - 2) + solve (n - 1)

这使得阅读 Haskell 代码和阅读数学公式一样轻松。

原文

Haskell 另一个优势是惰性求值,即计算会在真正用到时才进行,而不会在计算前提前消费掉,比如:

let x = [1..]
let y = [2,4 ..]
head (tail tail( (zip x y)))

可以看到,xy 分别是 1,2,3,4,5,6...2,4,6,8... 的无限数组,而 zip 函数将其整合为一个新数组 (1,2),(2,4),(3,6),(4,8)... 这也是无限数组,如果将 zip 函数执行完那么程序就会永远执行下去。但 Haskell 却不会陷入死循环,而是直接输出第一位数字 1。这就是惰性计算的特性,无论数组有多长,只有真正用到某项时才对其进行计算,所以哪怕初始数据量或计算量很大,实际消耗的运算资源只取决于这次计算实际用到的部分。

由于深度学习数据量巨大,惰性求值可以忽略海量数据输入,大大提升计算性能。

3 总结

本文介绍了为什么深度学习更适合使用函数式语言,以及介绍了 Clojure 与 Haskell 语言的共性:安全性、高性能,以及各自独有的特性,证明了为何这两种语言更适合用在深度学习中。

在前端领域说到函数式或函数之美,大部分时候想到的是 Class Component 与 Function Component 的关系,这个理解是较为片面的。通过本文我们可以了解到,函数式的思想与数学表达式思想如出一辙,以写数学公式的思维方式写代码,就是一种较好的函数式编程思路。

函数式应该只有表达式,没有语句,这是因为函数式是为了处理运算而诞生的,因此很适合用在深度学习领域。

讨论地址是:精读《深度学习 - 函数式之美》 · Issue #212 · dt-fe/weekly

如果你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

d47f46dc483e6857fffdfcd4a1aa4d40.png
版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/266317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IOS(常用移动终端设备) push实现通知中心

参考文章: http://blog.csdn.net/zhuqilin0/article/details/6527113 http://www.dozer.cc/2013/03/push-notifications-server-side-implement/ http://blog.sina.com.cn/s/blog_71ce775e0101b43e.html PushSharp:https://github.com/Redth/PushShar…

Ubuntu下无法看到共享文件夹的解决办法

参考:Ubuntu下无法看到共享文件夹的解决办法 作者:一只青木呀 发布时间:2020-08-07 10:09:04 网址:https://blog.csdn.net/weixin_45309916/article/details/107856157 今天早上起来突然发现共享文件夹的查看不到了,找…

MySQL提供了以下三种方法用于获取数据库对象的元数据

MySQL提供了以下三种方法用于获取数据库对象的元数据: 1)show语句 2)从INFORMATION_SCHEMA数据库里查询相关表 3)命令行程序,如mysqlshow, mysqldump 用SHOW语句获取元数据 MySQL用show语句获取元数据是最常用的方法&a…

laravel 5.1 php版本号,发行版本说明 | 序言 | Laravel 5.1 中文文档

发行版本说明由 学院君 创建于5年前, 最后更新于 11个月前版本号 #219641 views23 likes0 collects支持政策LTS版本,比如Laravel 5.1,将会提供两年的bug修复和三年的安全修复支持。这些版本将会提供最长时间的支持和维护。对于其他通用版本,只…

NYOJ-522 Interval

Interval 时间限制&#xff1a;2000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;4描述There are n(1 < n < 100000) intervals [ai, bi] and m(1 < m < 100000) queries, -100000 < ai < bi < 100000 are integers.Each query contains an inte…

实现图书增删的代码_不仅仅是图书信息管理系统

点击蓝字 关注我们不仅仅是图书信息管理系统基于双链表&#xff0c;采用面向对象编程方法制作的图书管理系统❞效果演示root用户&#xff1a;账号&#xff1a;0&#xff0c;密码&#xff1a;0普通用户&#xff1a;账号&#xff1a;1001&#xff0c;密码&#xff1a;666666图书信…

HDU1846 - Brave Game【巴什博弈】

十年前读大学的时候&#xff0c;中国每年都要从国外引进一些电影大片&#xff0c;其中有一部电影就叫《勇敢者的游戏》&#xff08;英文名称&#xff1a;Zathura&#xff09;&#xff0c;一直到现在&#xff0c;我依然对于电影中的部分电脑特技印象深刻。 今天&#xff0c;大家…

Ubuntu18.04换源更新国内源

参考&#xff1a;Ubuntu18.04更新国内源 作者&#xff1a;一只青木呀 发布时间&#xff1a;2020-08-05 10:24:11 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107808268 树莓派换源博文&#xff1a;https://blog.csdn.net/zhuguanlin121/article/d…

php中解析数组,在PHP中解析多维数组

您应该在将数据解析为Smarty之前准备好数据。你可以这样做&#xff1a;$result array(array(name > Hockey Team 1, category_id > 1),array(name > Hockey Team 2, category_id > 2),array(name > Hockey Team 3, category_id > 3),array(name > Footba…

了解jQuery并掌握jQuery对象和DOM对象的区别

jQuery的优势&#xff1a; 开源--开放源代码 轻量级 强大的选择器 出色的DOM操作(对DOM元素的一个增删改查) 完善的Ajax&#xff0c;出色的浏览器兼容性&#xff0c;丰富的插件支持&#xff0c;完善的文档&#xff08;说明书&#xff09; 链式操作方式&#xff0c; 写得少&…

linux下复制

复制文件 cp - i file tofile 复制目录 cp - r dic todic转载于:https://www.cnblogs.com/Hero-Qiang/archive/2013/03/20/2971579.html

rh php56 php,在全球范围内提供RHSCL PHP的最佳方法

我使用以下网址安装了RHSCL 2&#xff1a;使用RedHat订阅管理器.然后我运行yum删除php *,然后是yum install rh-php56一切顺利,除非现在找不到PHP.然后我运行find / -name php并在以下目录中找到rh-php56&#xff1a;/var/opt/rh/rh-php56/lib/php/opt/rh/rh-php56/register.co…

Vmware15的安装(ps解决:重装Vmware出现无法安装服务Vmware Authorization Service)

参考&#xff1a;Linux之Vmware的安装 作者&#xff1a;一只青木呀 发布时间&#xff1a; 2020-07-09 22:13:14 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/107238658 目录1.前言2.打开Vmware虚拟机安装包安装解决&#xff1a;重装Vmware出现无法…

python多线程模块_python 多线程模块参考

threading.active_count() 返回当前处于 active 状态的线程的数目 threading.current_thread() 返回调用者当前的 Thread 对象 threading.get_ident() 返回当前线程的“thread identifier”属性&#xff08;3.3新增&#xff09; threading.enumerate() 返回当前处于 active 状态…

谈谈即时通讯开发平台

由于即时通讯系统的复杂性和对服务器稳定性的很高要求&#xff0c;一般即时通讯系统开发至少需要1年左右的时间&#xff0c;而这还只是测试版&#xff0c;离"稳定"还有一定距离&#xff0c;而这时匆匆上马的不稳定的系统会让你失去用户&#xff0c;您也不可能召集上万…

内存,RAM(DDR),ROM(EEPROM、flash),存储卡(emmc,sd,tf)以及Cache的区别与联系

参考&#xff1a;内存&#xff0c;RAM&#xff0c;ROM&#xff0c;Cache的区别与联系 作者&#xff1a;一只青木呀 发布时间&#xff1a;2020-09-26 09:55:40 网址&#xff1a;https://blog.csdn.net/weixin_45309916/article/details/108808106 参考&#xff1a;EEPROM和flash…

PHP数据库可视化分析工具,5个MySQL GUI工具推荐,帮助你进行数据库管理

MySQL的数据库管理工具非常多&#xff0c;有哪些优秀的GUI工具可以帮助提高工作效率?不妨看一看这5个MySQL GUI工具。1、Navicat for MySQLNavicat for MySQL是数据库管理工具&#xff0c;与MySQL&#xff0c;MariaDB和云数据库兼容&#xff0c;是目前非常受欢迎的数据库前端用…

idea 项目jar反编译java_带你上手阿里开源的 Java 诊断利器:Arthas

本文适合有 Java 基础知识的人群。本文作者&#xff1a;HelloGitHub-秦人HelloGitHub 推出的《讲解开源项目》系列&#xff0c;今天给大家带来一款阿里开源的 Java 诊断利器 Arthas 项目—— Arthas项目源码地址&#xff1a;https://github.com/alibaba/arthas一、简介 为什么要…

22Java之JDBCTemplate总结

写在前面&#xff1a;这里总结4种方式来操作数据库&#xff08;SE阶段&#xff09; 一、JDBC JDBC有关的类&#xff1a;都在java.sql 和 javax.sql 包下.1.数据准备 这里假设已经在数据库中新建立了mydb4数据库&#xff0c;并且也插入了一些数据&#xff0c;并且还需要导入一个…

福布斯评科技未来五大趋势:电脑消失融入生活时间

福布斯评科技未来五大趋势&#xff1a;电脑消失融入生活时间 谈趋势似乎并不讨巧&#xff0c;因为所谓趋势通常都是指时尚。每每谈及趋势&#xff0c;人们立刻就会想到穿着夸张服饰在T台上昂首阔步的模特&#xff0c;但每当下一季的新款推出&#xff0c;再华丽的时装都会很快…