HLearn 的自述文件指出 Monoid 类型类用于并行批量训练。我在几个文件中看到了 trainMonoid
,但我很难剖析这个庞大的代码库。有人可以用初学者友好的术语解释它是如何工作的吗?我想它与关联属性有某种关系。
最佳答案
它在 this article 中有解释,它链接在您在问题中链接的页面中。由于您想要一个初学者友好的描述,我将在阅读本文后对我所理解的内容进行非常高级的描述。将此视为对想法的粗略概述,要准确了解 研究 文章所需的一切。
基本思想是使用代数性质来避免一遍又一遍地重新做同样的工作。他们通过使用幺半群运算和同态的结合性来做到这一点。
给定两个集合 A
和 B
以及两个二进制操作 +
和 *
,同态是一个函数 f: A -> B
使得 f(x + y) = f(x) * f(y)
,即它是一个保留两个集合之间结构的函数。
在那篇文章的情况下,函数 f
基本上是将输入集映射到训练模型的函数。
所以这个想法是你可以将输入数据分成不同的部分 x
和 y
,而不是像在 T(x + y)
中那样计算整个事物的模型,你可以只对 x
和 y
进行训练,然后组合结果: T(x) * T(y)
.
现在这实际上并没有多大帮助,但是在训练中你经常重复工作。例如,在交叉验证中,对于 k
时间,将数据采样到训练器的一组输入和用于测试训练器的一组数据中。但这意味着在这些 k
迭代中,您将在输入的相同部分多次执行 T
。
幺半群在这里发挥作用:您可以首先将域拆分为子集,并在这些子集上计算 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)
,即在线算法在所有这些数据点上都给出了与批处理算法相同的结果。所有这一切中更有趣(和复杂)的部分是您如何将训练任务视为同态等。我将把它留给您个人研究。
关于haskell - Monoid 如何协助并行训练?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39943545/