我是函数式编程的新手。
我有一个数千个神经元的大型神经网络,每个神经元之间的连接都有其权重。我需要经常更新这些权重,每次学习会话中要进行数千次更新。
函数式编程在这里仍然适用吗?我的意思是,在函数式编程中,我们不能修改变量,只能返回新变量而不能改变先前的值。这是否意味着我必须在每次权重更新时重新创建整个网络?
我是函数式编程的新手。
我有一个数千个神经元的大型神经网络,每个神经元之间的连接都有其权重。我需要经常更新这些权重,每次学习会话中要进行数千次更新。
函数式编程在这里仍然适用吗?我的意思是,在函数式编程中,我们不能修改变量,只能返回新变量而不能改变先前的值。这是否意味着我必须在每次权重更新时重新创建整个网络?
函数式编程在这里是否仍然适用?
你可以使用函数式风格编写具有良好渐进算法效率的代码,但是你不太可能获得10倍于良好命令式解决方案的性能,因为纯粹的函数式编程使得难以有效利用CPU缓存。
我的意思是,在fp中我们不能修改变量,只能返回新变量而不能更改先前的值。 这是否意味着我必须在每次权重更新时重新创建整个网络?
不需要,由于以下两个原因:
纯函数式数据结构可以高效地进行更新,因为它们将大型结构(例如哈希表)分解为许多小递归定义的结构(例如平衡二叉树)。当您更新不可变树中的单个节点时,您会从根到目标路径上的每个节点复制数据,但通过引用回到所有其他分支安全地知道它们在您下面不能更改,因为它们是不可变的。因此,您只需要做O(log n)的工作而不是O(n)的工作。
纯函数式数据结构通常提供像map
这样的函数,允许以相同的方式更新每个元素并通过复制源树的结构而避免重新平衡。因此,n次更新的时间为O(n),而不是O(n log n )。
因此,您应该能够实现类似或甚至相等的渐进时间复杂度,但是在绝对意义上,您将使用比命令式解决方案多几倍的空间和时间。我在我的书《Visual F# 2010 技术计算》中详细介绍了这些基础知识,并为OCaml Journal写了一篇名为人工智能:神经网络(2010年5月8日)的文章。
每次权重更新时,您不需要重新创建整个网络。假设您的神经元被建模为单独的对象-这意味着要“更新”一个单独的神经元,实际上是创建一个具有更新权重的新神经元。然后,将该神经元插入到网络中以替换旧神经元,而旧神经元则可以由垃圾回收器进行回收。
我不同意使用可变状态的想法。函数式语言知道它们是函数式的,因此它们对函数式编程进行了优化。如果函数式语言确实是最适合工作的工具,那么应该充分利用其优势。
如果您以这样的方式构建数据,即可以使用持久化数据结构来模拟神经网络,则对神经网络进行功能更新将会很便宜(至少与整个复制相比如此)。
如果速度仍然不够快,您的编程语言可能允许其他技术(例如谨慎使用变异)来加速;例如,如果您正在使用Clojure,则可以使用transients来实现一些额外的速度。
节点1 节点2 那么如果我创建节点3并用节点3替换节点1,这不意味着我正在改变整棵树吗? - Denis Gorodetskiy