Haskell 如何从有向无环图导出FRP?
我目前正在研究我的下一个项目。这是一个预规划阶段,所以这个问题只是为了对现有技术进行概述 安装程序 我有一个有向无环图(DAG),有多个输入和输出,现在想想人工神经元网络: 处理这种结构的常用方法是在每个(时间)步骤上处理整个网络。我相信这就是frp库所使用的方法,例如 现在我处于幸运的位置,我有一个事件流,每个事件都表示其中一个输入节点中的变化。这个想法是,如果我可以静态地知道给定的更改只会影响网络的一部分,那么我可能不必对网络中的每个节点进行步进 示例 在上面的图像中,5、7和3是输入节点,11和8是“隐藏”节点,2、9和10是输出节点。节点5处的更改将只影响节点11,实际上影响节点2、9和10。我不需要处理节点7、3和8 目标 以尽可能少的延迟处理此类网络。图形的大小可能会达到100k个节点,每个节点需要进行适量的计算 计划 我希望有人会站出来,为X库做广告,这样才能完成工作 否则,我当前的计划是从图形描述中导出每个输入节点的计算。我可能会使用Haskell 如何从有向无环图导出FRP?,haskell,directed-acyclic-graphs,frp,Haskell,Directed Acyclic Graphs,Frp,我目前正在研究我的下一个项目。这是一个预规划阶段,所以这个问题只是为了对现有技术进行概述 安装程序 我有一个有向无环图(DAG),有多个输入和输出,现在想想人工神经元网络: 处理这种结构的常用方法是在每个(时间)步骤上处理整个网络。我相信这就是frp库所使用的方法,例如 现在我处于幸运的位置,我有一个事件流,每个事件都表示其中一个输入节点中的变化。这个想法是,如果我可以静态地知道给定的更改只会影响网络的一部分,那么我可能不必对网络中的每个节点进行步进 示例 在上面的图像中,5、7和3是输入节点
Par
monad,这样我就不必自己处理数据依赖性,而且仍然可以从多核机器中获益
问题
- 有没有图书馆能满足我的需要
- 我的
计划可行吗?这在多大程度上取决于每个节点所需的处理量Par
- 像这样的问题通常根据
应用程序或箭头抽象进行编码。我只讨论应用程序
。Control.Applicative
中的Applicative
类型类允许通过pure
提供值和函数,并允许将函数应用于具有
的值
通过遍历图,可以通过编程方式从图的表示中创建相同的编码,这样每个节点在其所有依赖项之后都将被访问
对于仅使用Applicative
编码的网络,您可能希望实现三种优化。一般策略是根据Applicative
和优化或额外功能所需的一些附加类对问题进行编码。然后提供一个或多个实现必要类的解释器。这允许您将问题与实现分离,允许您编写自己的解释器或使用现有的库,如,或。我不打算讨论如何编写这些口译员,也不打算将这里给出的表述改编为特定的口译员。我只想讨论程序的通用表示,它是底层解释器能够利用这些优化所需要的。我链接的所有三个库都可以避免重新计算值,并且可以适应以下优化
可观测共享
在前面的示例中,中间节点eleven
仅定义一次,但在三个不同的位置使用。Applicative
的实现将无法通过引用透明性看到这三个11个s都是相同的。您可以假设实现使用了一些网络,也可以定义网络,以便实现可以看到正在重用计算
以下是Applicative
Functor
s类,其中计算结果可被分割并在多个计算中重用。据我所知,这个类没有在任何库中定义
class Applicative f => Divisible f where
(</>) :: f a -> (f a -> f b) -> f b
infixl 2 </>
和与交换群
典型的神经元计算其输入的加权和,并对该和应用响应函数。对于程度较大的神经元,将其所有输入求和是非常耗时的。更新总和的一个简单优化方法是减去旧值并添加新值。这利用了加法的三个属性:
反向-a*b*b⁻CharStyle=a
减法是一个数字相加的倒数,这个倒数允许我们从总数中删除之前添加的数字
交换性-a*b=b*a
加减运算无论以何种顺序执行,都会得到相同的结果。这让我们在减去旧值并将新值添加到总值时,即使旧值不是最近添加的值,也能得到相同的结果
结合性-a*(b*c)=(a*b)*c
加法和减法可以在任意分组中执行,并且仍然可以达到相同的结果。当我们减去旧值并将新值添加到总数中时,即使在添加中间的某个地方添加旧值,也可以得到同样的结果。
任何具有这些属性以及闭包和标识的结构都是一个。下面的字典保存了足够的信息,使基础库能够执行相同的优化
data Abelian a = Abelian {
id :: a,
inv :: a -> a,
op :: a -> a -> a
}
这是一类可以对阿贝尔群求和的结构
class Total f where
total :: Abelian a -> [f a] -> f a
对于地图的构建,也可以进行类似的优化
阈值与平等
神经网络中的另一个典型操作是将值与阈值进行比较,并完全根据值是否超过阈值来确定响应。如果对输入的更新没有改变阈值的哪一侧,则响应不会改变。如果响应没有改变,就没有理由重新计算所有下游节点。能够检测到
example2 :: (Divisible f, Num a) => f a -> f a -> f a -> f (a, a, a)
example2 five seven three =
pure (+) <*> five <*> seven </> \eleven ->
pure (+) <*> seven <*> three </> \eight ->
pure id <*> eleven </> \two ->
pure (+) <*> eleven <*> eight </> \nine ->
pure (+) <*> eleven <*> three </> \ten ->
pure (,,) <*> two <*> nine <*> ten
data Abelian a = Abelian {
id :: a,
inv :: a -> a,
op :: a -> a -> a
}
class Total f where
total :: Abelian a -> [f a] -> f a
class Stabilizes f where
stabilize :: Eq a => f a -> f a