HLearn 的自述文件指出 Monoid 类型类用于并行批量训练。我在几个文件中看到了 trainMonoid,但我很难剖析这个庞大的代码库。有人可以用初学者友好的术语解释它是如何工作的吗?我想它与关联属性有某种关系。

最佳答案

它在 this article 中有解释,它链接在您在问题中链接的页面中。由于您想要一个初学者友好的描述,我将在阅读本文后对我所理解的内容进行非常高级的描述。将此视为对想法的粗略概述,要准确了解 研究 文章所需的一切。

基本思想是使用代数性质来避免一遍又一遍地重新做同样的工作。他们通过使用幺半群运算和同态的结合性来做到这一点。

给定两个集合 AB 以及两个二进制操作 +* ,同态是一个函数 f: A -> B 使得 f(x + y) = f(x) * f(y) ,即它是一个保留两个集合之间结构的函数。
在那篇文章的情况下,函数 f 基本上是将输入集映射到训练模型的函数。

所以这个想法是你可以将输入数据分成不同的部分 xy ,而不是像在 T(x + y) 中那样计算整个事物的模型,你可以只对 xy 进行训练,然后组合结果: 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/

    10-13 21:35