HLearn 的自述文件中提到,Monoid 类型类被用于并行批量训练。我在几个文件中看到过 trainMonoid
的提及,但我很难解析这个庞大的代码库。能有人用适合初学者的语言解释一下它的工作原理吗?我猜这可能与结合律性质有关。
回答:
这个问题中链接的页面中提到的这篇文章对此进行了解释。由于你想要一个适合初学者的描述,我将提供一个非常高层次的描述,概述我阅读文章后的理解。请将此视为对该想法的粗略概述,要完全理解所有内容,你必须研究这些文章。
基本思想是利用代数性质来避免重复工作。他们通过使用幺半群操作的结合律和同态来实现这一点。
对于具有两个二元运算 +
和 *
的两个集合 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
进行了三次训练。使用同态,我们可以计算 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)
,即在线算法给出的结果与所有这些数据点的批量算法相同。
所有这些中更有趣(也更复杂)的一部分是如何将训练任务视为这样的同态等。我将这些留给你自己研究。