速来报名!AICon北京站鸿蒙专场~ 了解详情
写点什么

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


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

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

关注

评论

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

短视频直播系统源码——如何优化满足用户需求?

开源直播系统源码

直播系统源码 开源源码 短视频直播系统源码

李宏毅《机器学习》丨2. Regression(回归)

AXYZdong

机器学习 7月月更

Okaleido或杀出NFT重围,你看好它吗?

鳄鱼视界

uni-app进阶之内嵌应用【day14】

恒山其若陋兮

7月月更

不会吧!钉钉都下载了,你还不知道可以这样玩?

Jianmu

钉钉 持续集成 自动化运维 建木CI 通知

云计算和大数据的关系以及区别详细讲解

行云管家

云计算 大大数据

还在羡慕其它平台有跨店满减,其实你也可以!

CRMEB

nacos注册中心之服务注册

急需上岸的小谢

7月月更

值得一看的智能运维AIOps关键核心技术概览!

云智慧AIOps社区

人工智能 机器学习 运维 智能运维 自动化运维

边无际 Shifu IoT 开源开发框架 助力物联网应用开发加速十倍

亚马逊云科技 (Amazon Web Services)

开源 Kubernetes 物联网 应用开发

2022年浙江省等保备案流程指南

行云管家

等保 等保备案

动手实践丨手把手教你用STM32做一个智能鱼缸

华为云开发者联盟

物联网 IoT

不是我说,Nacos和Apollo中的长轮询定时机制,真的太好用了

Java全栈架构师

Java 程序员 面试 微服务 nacos

面试官:你确定Redis是单线程的进程吗?

Java永远的神

Java redis 程序员 架构 面试

jdbc自带MySQL连接池实践

FunTester

模块七作业 - 王者荣耀商城异地多活架构设计

Elvis FAN

vueCli3.x版本中如何修改打包好的css、js、img文件名

木叶🐱

7月月更

易周金融 | 邮惠万家银行开业;微信公众号叫停四类金融营销宣传

易观分析

金融

易观千帆银行用户体验中心成立,助力银行业用户体验升级

易观分析

银行 用户体验

全新出品!阿里P5工程师~P8架构师晋升路线揭秘

程序员小毕

Java 程序员 面试 架构师 学习路线

想进大厂拿高薪?掌握Redis的Sentinel哨兵原理将是至关重要的突破口

了不起的程序猿

Java java程序员 Redis 数据结构

python小知识-rethinking python 生成器

AIWeker

Python python小知识 7月月更

TPC藏宝计划质押系统开发(Dapp)

薇電13242772558

智能合约 dapp

声网传输层协议 AUT 的总结与展望丨Dev for Dev 专栏

声网

传输协议 Dev for Dev

Google上网神器Ghelper

源字节1号

软件开发 小程序开发

Verilog HDL

贾献华

7月月更

向量化执行引擎框架 Gluten 宣布正式开源,并亮相 Spark 技术峰会

Kyligence

spark Gluten

音视频开发进阶|第四讲:音频自动增益控制 AGC

ZEGO即构

音视频开发 AGC

软件研发落地实践,要从设计就开始

华为云开发者联盟

云计算 后端 开发

MySQL数据库优化

五分钟学大数据

MySQL 7月月更

JAVA编程规范之控制语句

源字节1号

后端开发

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