我是功能编程的新手。
我有一个庞大的神经网络,有数千个神经元,神经元之间的每个连接都有它的重量。我必须经常更新这些权重,每次学习会话数千次。
FP在这里仍适用吗?我的意思是在fp中我们不能修改变量,只能返回不改变先前值的新变量。这是否意味着我必须在每次重量更新时重新创建整个网络?
答案 0 :(得分:18)
FP在这里仍适用吗?
你当然可以用功能性的渐近算法效率来编写这个函数,但你不太可能获得10倍的体面命令式解决方案的性能,因为纯粹的函数式编程使得很难有效地使用CPU缓存。
我的意思是在fp中我们不能修改变量,只能返回不改变先前值的新变量。这是否意味着我必须在每次重量更新时重新创建整个网络?
不,有两个原因:
纯功能数据结构可以有效地更新,因为它们将大型结构(例如散列表)分解成许多小的递归定义结构(例如平衡二叉树)。当您更新不可变树中的单个节点时,您将从路径中的每个节点复制数据从根到目标,但通过引用安全返回所有其他分支,因为它们不能在您之下更改,因为它们是不可变的。所以你只做O( log n )而不是O( n )工作。
纯粹的功能数据结构通常提供像map
这样的函数,允许以相同的方式更新每个元素,并通过复制源树的结构来避免重新平衡。因此 n 更新的时间是O( n )而不是O( n log n )。
所以你应该能够达到类似甚至相等的渐近时间复杂度,但从绝对意义上说,你将使用几倍于空间和时间的必要解决方案。我在我的书Visual F# 2010 for Technical Computing中详细介绍了这些基础知识,并为Artificial Intelligence: Neural Networks (8th May 2010)撰写了文章OCaml Journal。
答案 1 :(得分:2)
查看包含monad中可变变体的Haskell arrays。
答案 2 :(得分:1)
每次发生重量更新时,您都不需要重新创建整个网络。据推测,您的神经元被建模为单个对象 - 这意味着要“更新”单个神经元,您实际上将创建一个具有更新权重的新神经元。然后将这个神经元插入到网络中代替旧的神经元,然后垃圾收集器可以自由地进行回收。
我不同意使用可变状态的想法。功能语言知道它们是功能性的,因此它们对函数式编程进行了优化。如果功能语言确实是这项工作的最佳工具,那么就利用它的优势。
答案 3 :(得分:1)
如果您构建数据的方式可以使用持久数据结构来建模神经网络,那么神经网络的功能更新将会很便宜(至少与复制整个事物相比)。
如果仍然不够快,您的语言可能允许其他技术(例如小心使用突变)来加快速度;例如,如果你使用Clojure,你可以使用瞬态来获得额外的速度。