【发布时间】:2016-10-09 12:19:50
【问题描述】:
HLearn 的自述文件指出 Monoid 类型类用于并行批量训练。我在几个文件中看到过trainMonoid,但我很难剖析这个庞大的代码库。有人可以用初学者友好的术语解释它是如何工作的吗?我猜它与关联属性有某种关系。
【问题讨论】:
标签: haskell machine-learning parallel-processing monoids
HLearn 的自述文件指出 Monoid 类型类用于并行批量训练。我在几个文件中看到过trainMonoid,但我很难剖析这个庞大的代码库。有人可以用初学者友好的术语解释它是如何工作的吗?我猜它与关联属性有某种关系。
【问题讨论】:
标签: haskell machine-learning parallel-processing monoids
this article 对此进行了解释,该链接在您在问题中链接的页面中链接。既然你想要一个初学者友好的描述,我会给你一个非常高层次的描述,说明我在阅读这篇文章后所理解的内容。将此视为对想法的粗略概述,以准确了解您拥有研究文章的所有内容。
基本思想是使用代数属性来避免重复做同样的工作。他们通过使用幺半群运算和同态的结合性来做到这一点。
给定两个集合 A 和 B 以及两个二元运算 + 和 * 同态是一个函数 f: A -> B 使得 f(x + y) = f(x) * f(y),即它是一个保留两个集合之间结构的函数.
在那篇文章中,函数f 基本上是将输入集映射到训练模型的函数。
所以想法是你可以将输入数据分成不同的部分x 和y,而不是像T(x + y) 那样计算整个事物的模型,你可以只在@上进行训练987654332@ 和y 然后合并结果:T(x) * T(y)。
现在这并没有太大帮助但是,在训练中你经常重复工作。例如,在交叉验证中,对于k 次,将数据采样到训练器的一组输入和一组用于测试训练器的数据中。但这意味着在这些k 迭代中,您将多次对输入的相同部分执行T。
这里 monoids 发挥作用:您可以首先将域拆分为子集,并在这些子集上计算 T,然后计算交叉验证的结果,您只需将相应子集的结果放在一起即可。
给个思路:如果数据是{1,2,3,4}和k = 3而不是做:
T({1,2}) 加上对{3, 4} 的测试
T({1,3}) 加上对{2, 4} 的测试
T({1,4}) 加上对{2, 3} 的测试
在这里你可以看到我们训练了1 3 次。使用同态我们可以计算T({1})一次,然后将结果与其他部分结果相结合,得到最终的训练模型。
运算的结合性和同态性保证了最终结果的正确性。
在并行化时可以应用相同的想法:您将输入分成k 组,并行执行训练,然后复合结果:T(x_1 + x_2 + ... + x_k) = T(x_1) * T(x_2) * ... * T(x_k) 其中T(x_i) 调用完全并行执行,并且仅在最后你必须复合结果。
关于在线训练算法,想法是给定一个“批量”训练算法T,您可以通过以下方式将其变为在线训练算法:
T_O(m, d) = m * T(d)
其中m 是已经训练好的模型(在此之前通常是训练好的模型),d 是您为训练添加的新数据点。
同样,结果的精确性是由于同态告诉您如果m = T(x) 则m * T(d) = T(x+d),即在线算法对所有这些数据点给出与批处理算法相同的结果。
所有这一切中更有趣(和复杂)的部分是您如何将训练任务视为同态等。我将把它留给您个人研究。
【讨论】: