精读《深度学习 - 函数式之美》

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

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

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

相关文章

使用Python合并PDF文件并添加自定义目录及页脚

如何用Python合并PDF文件并添加自定义目录及页脚 步骤一:准备环境步骤二:合并PDF文件步骤三:处理特定文件步骤四:合并并添加目录与页脚步骤五:保存最终文档结语完整代码 在处理文档时,我们经常遇到需要合并…

Mybaties-Plus saveBatch()、自定义批量插入、多线程批量插入性能测试和对比

一.背景 最近在做一个项目的时候,由于涉及到需要将一个系统的基础数据全量同步到另外一个系统中去,结果一看,基础数据有十几万条,作为小白的我,使用单元测试,写了一段代码,直接采用了MP(Mybati…

element---tree树形结构(返回的数据与官方的不一样)

项目中要用到属性结构数据&#xff0c;后端返回的数据不是官方默认的数据结构&#xff1a; <el-tree:data"treeData":filter-node-method"filterNode":props"defaultProps"node-click"handleNodeClick"></el-tree>这是文档…

SpringCloudGateway全局过滤器

文章目录 全局过滤器的作用自定义全局过滤器过滤器执行的顺序 上一篇 Gateway理论与实践 介绍的过滤器&#xff0c;网关提供了31种&#xff0c;但每一种过滤器的作用都是固定的。如果我们希望拦截请求&#xff0c;做自己的业务逻辑则没办法实现。 全局过滤器的作用 全局过滤器的…

怎样添加、移除、移动、复制、创建和查找节点?

1&#xff09;创建新节点 createDocumentFragment() //创建一个 DOM 片段createElement() //创建一个具体的元素createTextNode() //创建一个文本节点 2&#xff09;添加、移除、替换、插入 appendChild() //添加removeChild() //移除replaceChild() //替换insertBefore() /…

高级语言讲义2010计专(仅高级语言部分)

1.编写一程序&#xff0c;对输入的正整数&#xff0c;求他的约数和。 如&#xff1a;18的约数和为1236939 #include <stdio.h>int getsum(int n){int i,sum0;for(i1;i<n;i)if(n%i0)sumi;return sum; } int main(){int sum getsum(18);printf("%d",sum); …

JS直接量及其相关对象

什么是直接量 直接量是指不需要创建对象就可以直接使用的变量。ES中的直接量主要有三种类型&#xff1a;表示字符串的string类型、表示数字的number类型和表示true/false的boolean类型。当我们直接将值赋给变量后&#xff0c;ES就会自动判断其类型&#xff0c;而且当参数发生变…

Android14之编译输出system/product/vendor/odm分区(一百九十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

机器学习流程—数据预处理 Encoding

机器学习流程—数据预处理 Encoding 在机器学习中,我们经常会遇到分类变量,这些分量变量往往机器学习模型没有办法从中学习,往往有两种,一种是字符型,一种是数值型。通常需要对分类型变量做一些处理,常用的方法有两种:label encoding和one hot encoding。 例如,假设数…

「AI工程师」数据处理与分析-工作指导

工作指导书 一、工作职责 负责数据的收集、清洗、整合和处理,确保数据质量和准确性。进行数据分析和挖掘,提取有价值的信息,为业务决策提供支持。构建和维护数据处理和分析的流程和工具,提高数据处理效率。与其他团队成员合作,共同解决数据处理和分析过程中遇到的问题。二…

深度学习相关概念及术语总结

目录 1.CNN2.RNN3.LSTM4.NLP5.CV6.正向传播7.反向传播8.sigmoid 函数9.ReLU函数10.假设函数11.损失函数12.代价函数 1.CNN CNN 是卷积神经网络&#xff08;Convolutional Neural Network&#xff09;的缩写。卷积神经网络是一种深度学习模型&#xff0c;专门用于处理具有网格状…

kotlin筑基(2)

文章目录 一、internal二、infix三、object四、open五、operator六、sealed class1. 用法一2. 用法二 七、typealias八、when1. 带参数2. 不带参数 一、internal internal 修饰方法&#xff0c;表示这个方法只适合当前 module 使用&#xff0c;同理修饰 class 也是一样。 Syn…

mysql的time_zone导致性能下降

mysql的 time_zone有哪些 MySQL 的 time_zone 变量可以设置为多种不同的时区值。这些值通常由字母和数字组成&#xff0c;代表世界上不同的地理区域和它们的标准时间。以下是一些常见的 time_zone 设置选项&#xff1a; UTC&#xff1a;协调世界时&#xff0c;是国际标准时间…

2024年3月ZZUACM 招新赛题解

2024年3月ZZUACM 招新赛 题号题目A区间次大值B上课签到C魔法森林&#xff08;一&#xff09;D魔法森林&#xff08;二&#xff09;ELOPF跳格子G猜数字H抽卡记录I安达的二维矩阵J安达的数字手术K跳楼梯L前缀和 A 区间次大值—循环/签到题 题目描述 给定一个 n n n的全排列 a i…

顶顶通呼叫中心中间件(基于FreeSWITCH)对接mrcp asr 和 tts配置

介绍 顶顶通呼叫中心中间件通过asrproxy程序对接各种asr和tts,本文主要讲解 asrproxy程序 对接 mrcp v1 和 mrcp v2的配置。 asrproxy.json配置 asr配置 "asr":{"interface": {"mrcp": {"count": 0,"fault_threshold": 0…

外包干了10天,技术退步明显···

先说一下自己的情况&#xff0c;本科生&#xff0c;通过校招进入杭州某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试&…

【鸿蒙开发】第十七章 Web组件(一)

1 Web概述 Web组件用于在应用程序中显示Web页面内容&#xff0c;为开发者提供页面加载、页面交互、页面调试等能力。 页面加载&#xff1a;Web组件提供基础的前端页面加载的能力&#xff0c;包括&#xff1a;加载网络页面、本地页面、html格式文本数据。 页面交互&#xff1a…

Java必须掌握的clear【】(含面试大厂题和源码)

面试题&#xff1a;“如何在Java中清除一个数组中的所有元素&#xff1f;” 在Java中&#xff0c;清除一个数组中的所有元素并不意味着逐个删除数组的每个元素&#xff0c;因为这在数组中是不可能做到的。数组的大小在初始化之后是固定的&#xff0c;无法改变。因此&#xff0…

IOS面试题object-c 1-10

1、简述Object-C的理解与特性&#xff1f; OC 作为一门 面向对象 的语言&#xff0c;自然具有面向对象的语言特性&#xff1a;封装、继承、多态。 它既具有 静态语言的特性&#xff08;如C&#xff09;&#xff0c;又有 动态语言的效率&#xff08;动态绑定、动态加载等&#…

JAVA使用的工具类-Hutool

文章目录 Hutool工具类简介1&#xff1a;身份证工具类相关方法1.1 身份证脱敏处理 字符串补零处理(此处是JAVA类的方法&#xff0c;并无引用StrUtil)springboot前后端分离&#xff0c;后端返回json字符串带斜杠问题处理 在这里整理一下博主常用的工具类方法-hutool工具类,这里囊…