NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

Clojure 和 Haskell——深度学习中的函数式语言之美

  • 2019-10-02
  • 本文字数:3821 字

    阅读完需:约 13 分钟

Clojure和Haskell——深度学习中的函数式语言之美

深度学习是基于人工神经网络的机器学习方法的一个子集。这些方法的灵感来自于大脑等生物系统中的信息处理方式和分布式通信节点。在深度学习中,每一层都要通过学习将输入数据转换成更加抽象和综合的表示形式。例如在人脸识别系统中,系统的某一层可能是像素,而另一层可能是图像中的边缘,眼睛和脸也可能分别都用一层来表示。深度学习方法如此复杂,所以编程社区习惯使用现成的包。基于 Python 语言的的 TensorFlow 和 PyTorch 很受欢迎,基于 R 语言的 Keras 包也很流行。然而,在深度学习系统的生产环境中,性能和安全性这两问题促使公司倾向选择 Clojure 和 Haskell 等函数式编程语言


深度学习实现的难点

在将深度学习系统投入生产环境时,神经网络可能包含多达一百万个参数。为了训练这些参数,训练数据可能会呈现爆炸式增长。如此庞大的数据需求,让深度学习的训练只能通过具有安全并发性和并行能力的高效编程语言来实现。神经网络的数据是一层层传递的,这种复杂性意味着编程语言处理这些数据时应该足够简单和一致。这里所说的安全性是指以一致的方式保留原始数据状态的能力,而简单性是指能够轻松地读取和维护代码库,同时最大化性能指标。

为什么函数式编程更适合深度学习

为了解决实现深度学习时可能出现的困难,程序员发现函数式编程语言可以提供解决一些方案


在计算机科学中,函数式编程是一种将计算作为数学函数评估,避免状态变化和数据变化的编程范式。它是一种更接近数学思维的编程模式。


深度学习模型本质上是数学模型。例如,人工神经网络由相互连接的节点组成,每个节点执行简单的数学运算。通过使用函数式编程语言,程序员能够用更接近操作本身的语言描述这些数学操作。这些程序的显式编写方式使得读取和维护代码库变得容易许多。


与此同时,深度学习算法的合成性质意味着,在神经网络的每一层上,这些层或函数往往会链接在一起执行任务。这可以通过函数式编程语言的函数链轻松实现。



此外,在深度学习中,当函数应用于数据时,数据不会改变。新值可能是沿行顺序往下输出的,但是数据本身会保持一致。函数式编程语言的不可变特性允许程序员在每次生成新值时创建一个新的数据集,而不需要修改原始的不可变数据集。这使得维护整个神经网络数据的一致性变得更加容易。


最后,实现深度学习涉及到大量的参数和训练数据,这意味着并行性和并发性是创建生产级深度学习系统的关键所在。并行性意味着在不同的 CPU 上运行线程以加速学习过程。并发性则是指管理线程以避免冲突的能力。函数式编程允许并发和并行,而不引入额外开销。这意味着,从本质上讲,函数式编程(纯函数是无状态的)将始终为特定的输入生成相同的输出,因此我们能隔离任何函数,并随时执行它。这使得并发性和并行性更容易管理。您不必处理诸如死锁和条件竞争之类的问题。运行在不同 CPU 上的不同线程能够独立运行,没有竞争。

Clojure

随着函数式编程在深度学习中越来越受欢迎,同时出现了许多用于深度学习的健壮包。Clojure 现在受到了沃尔玛和 Facebook 等公司的青睐。它是一种基于 LISP 编程语言的高级动态函数式编程语言,还带有编译器,可以运行在 Java 和.NET 运行时环境中。

Clojure 中强大的并发编程

Clojure 并非 Java 线程系统的替代品,而是与后者协同工作。由于核心数据结构是不可变的,因此可以在线程之间轻松地共享它们。与此同时,程序中的状态可以更改的,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)
复制代码


源代码

Clojure 中的并行性很廉价

在深度学习中,模型必须训练大量的数据。并行性意味着在不同的 CPU 上可以运行多个线程。廉价的并行性意味着显著的性能改进,将分区与映射结合使用可以实现成本更低的并行性。


(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))))
复制代码


源代码

Clojure 中的链式函数意味着更清晰的代码

在 Clojure 中,很多函数只有很少的数据类型。函数也可以作为参数传递给其他函数,于是深度学习中就可以使用链式函数了。因为 Clojure 的实现更接近实际的数学模型,其代码也更容易阅读和维护。


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


源代码

Clojure 中的标识和状态提供了安全性

在 Clojure 中,每个模型的标识在任何时候都有一个状态。这种状态是一个永远不会改变的真实值。如果标识看起来出现了变化,那是因为它关联到了不同的状态。新值是旧值的函数。在神经网络的每一层中,原始数据的状态始终保持不变。每组具有新值(函数的输出)的数据都可以独立操作。这意味着可以在这些数据集上安全地执行操作,不用考虑计算资源竞争。我们可以往回追溯,随时查阅数据的原始状态。因此在这种情况下,一致性即意味着安全性。

库和局限性

一直以来,Cortex机器学习库包含了在 Clojure 中实现机器学习算法所需的所有内容。随着最近用于深度学习的开源 MXNet 框架的日益流行,使用MXNet-Clojure API更容易实现深度学习。


尽管现在有许多不同的 API 和机器学习库可供 Clojure 使用,但是要熟练地使用 Clojure 仍然有一个陡峭的学习曲线。机器学习代码的报错信息可能是令人费解的,企业需要提前做一些投资,才能真正熟练使用它们,进而扩大机器学习系统的规模。随着使用 Clojure 编写的可用于生产系统的案例越来越多,这种语言将在未来几年变得越来越流行,但前提是使用 Clojure 语言的库的数量和规模持续增长。

Haskell

Haskell 是一种函数式语言,使用类型推断和延迟计算进行静态类型化。它在 Miranda 编程语言的语义之上,实现了一种更有表现力、更快、更安全的机器学习语言。

Haskell 中的类型安全提供了安全性和灵活性

类型安全定义了一种约束,即变量对应的值类型上的约束。这将有助于防止非法操作,提供更好的内存安全性,并减少逻辑错误。延迟计算意味着 Haskell 会延迟计算一个表达式,直到某个地方需要用到后再去计算它。它还避免了重复计算以节省运行时间。同时,延迟计算允许定义数量无限的数据结构。这给了程序员无限的数学可能性。

Haskell 中简单的显式代码提供了清晰的实现

Haskell 最大的优点之一是它可以用非常明确的数学结构描述算法。您可以用几行代码表示一个模型。您也可以像阅读数学方程一样阅读代码。这在复杂的算法中非常有用,比如机器学习中的深度学习算法就是一个典型例子。例如,下面实现的单层前馈神经网络就能看出代码的可读性优势。


import Numeric.LinearAlgebra.Static.Backproplogistic :: Floating a => a -> alogistic x = 1 / (1 + exp (-x))feedForwardLog   :: (KnownNat i, KnownNat o)   => Model (L o i :& R o) (R i) (R o)feedForwardLog (w :&& b) x = logistic (w #> x + b)
复制代码


源代码

Haskell 中的多核并行提供了高性能

在深度学习中,典型的神经网络定义的模型包含一百万个参数。而且需要大量的数据来学习这些参数,这在计算上是非常耗时的。在一台机器上使用多个核并行地共享内存和进程对于实现深度学习来说是非常重要的。而在 Haskell 中,实现多核并行很容易

库和局限性

Haskell 的HLearn库包含机器学习算法实现,同时也可以使用 Tensorflow 中的Haskell绑定来做深度学习计算,并行和并发库则用于并行和并发需求。


尽管有一些机器学习库是用 Haskell 开发的,但生产级的 Haskell 实现还是需要做一些基础工作。因为用于特定深度学习和机器学习任务的公共库数量不多,Haskell 在人工智能中的应用也是受限的。Aetion Technologies 和瑞士信贷全球建模和分析集团(Credit Suisse Global Modeling and Analytics Group)等公司正在实践中使用 Haskell——使用 Haskell 的组织的完整列表在此

结论

深度学习模型是复杂的数学模型,需要特定的函数层。函数式编程语言(如 Clojure 和 Haskell)通常可以用更简洁、更接近模型数学表达式的代码表示复杂内容。这将节省时间、提高效率,并简化代码库的管理。函数式编程的特定属性使这些语言的实现比其他语言的实现更安全。随着人工智能技术的发展,越来越多的人们将根据 AI 大规模系统开发项目的需求来评估这些语言。


本文来自 Behind the Code。访问Behind the Code发现更多的文章和视频。


原文链接


https://www.welcometothejungle.co/fr/articles/btc-deep-learning-clojure-haskell


公众号推荐:

跳进 AI 的奇妙世界,一起探索未来工作的新风貌!想要深入了解 AI 如何成为产业创新的新引擎?好奇哪些城市正成为 AI 人才的新磁场?《中国生成式 AI 开发者洞察 2024》由 InfoQ 研究中心精心打造,为你深度解锁生成式 AI 领域的最新开发者动态。无论你是资深研发者,还是对生成式 AI 充满好奇的新手,这份报告都是你不可错过的知识宝典。欢迎大家扫码关注「AI前线」公众号,回复「开发者洞察」领取。

2019-10-02 08:596114
用户头像

发布了 61 篇内容, 共 23.8 次阅读, 收获喜欢 135 次。

关注

评论

发布
暂无评论
发现更多内容

Cookie & Session

爱好编程进阶

Java 程序员 后端开发

IntelliJ IDEA开发最佳配置

爱好编程进阶

Java 程序员 后端开发

11-SpringSecurity:Session共享

爱好编程进阶

Java 程序员 后端开发

2021金三银四必备:“基础-中级-高级

爱好编程进阶

Java 程序员 后端开发

2021最新一次Java面试,快手三面一轮游,如今已拿意向书

爱好编程进阶

Java 程序员 后端开发

7点建议助您写出优雅的Java代码

爱好编程进阶

Java 程序员 后端开发

Day435&436

爱好编程进阶

Java 程序员 后端开发

2020年底跳槽面试5家大厂,最后收获拼多多Java岗offer,分享三面总结!

爱好编程进阶

Java 程序员 后端开发

2021最强面试笔记非它莫属:3000字Java面试核心手册(大厂必备

爱好编程进阶

Java 程序员 后端开发

Dagger2源码分析(三)从源码角度分析注解在Dagger2中的使用

爱好编程进阶

Java 程序员 后端开发

网站开发进阶(一)Tomcat域名或IP地址访问配置详解

No Silver Bullet

tomcat 网站建设 5月月更

ArrayList、HashMap等集合初始容量的大小以及扩容的倍数

爱好编程进阶

Java 程序员 后端开发

模块三作业

天琪实刚亮

dubbo + zookeeper + spring 分布式系统

爱好编程进阶

Java 程序员 后端开发

7-52 两个有序链表序列的交集 (20 分)(思路加详解尾插法)come Boby!

爱好编程进阶

程序员 后端开发

PingCode 产品怎么样?产品底层逻辑是什么样的?

PingCode

4000字,详解Python操作MySQL数据库

爱好编程进阶

程序员 后端开发

client-go实战之一:准备工作

爱好编程进阶

Java 程序员 后端开发

Docker入门

爱好编程进阶

Java 程序员 后端开发

[Day32]-[二叉树]二叉树中的最大路径和

方勇(gopher)

LeetCode 二叉树 数据结构和算法

2021年九月最新Java面试必背八股文,338道最新大厂架构面试题

爱好编程进阶

Java 程序员 后端开发

SpringSecurity默认页面生成

急需上岸的小谢

5月月更

决战摸鱼之巅:将vscode撸成可局域网联机对战的moba平台

gamedilong

前端 vscode nodejs Node 摸鱼

Day386&387

爱好编程进阶

Java 程序员 后端开发

32 岁的我裸辞了,八年 Java 老鸟,只因薪水被应届生倒挂

爱好编程进阶

Java 程序员 后端开发

address list(dynamic)- 通讯录动态版本

爱好编程进阶

Java 程序员 后端开发

2020最新版Java学习路线图--妈妈再也不用担心我误删数据库被开除了

爱好编程进阶

Java 程序员 后端开发

2021最新分享字节四面成功拿Offer!

爱好编程进阶

Java 程序员 后端开发

2020面试官会经常问到的三个并发工具类,你都知道吗?

爱好编程进阶

程序员 后端开发

GitOps指南

俞凡

DevOps gitops

C++类设计和实现的十大最佳实践

俞凡

c++ 最佳实践

Clojure和Haskell——深度学习中的函数式语言之美_编程语言_Jun Wu_InfoQ精选文章