我在Python中做了一个机器学习期望最大化算法,基本上是IBM Model1的实现,用于进行机器翻译(如果你想看代码,这里是我的GitHub),它可以工作,但确实很懒散。我现在正在上并行计算课,我想知道我是否可以使用 Python 多处理来更快地实现收敛。谁能给我任何指示或提示?我什至不知道从哪里开始。
编辑:我正在阅读,发现这篇关于使用EM和MapReduce进行并行化的论文 - 也许这是一个更好的主意?
你的大部分问题是Python真的很慢。请记住,您的代码是在解释器中执行的。当你执行代码(例如第 82 行)时,一次执行一个元素的数值计算,你就有了这个计算 - 以及 Python 解释器的所有开销。
您要做的第一件事是使用 numpy 对代码进行矢量化。与普通的python代码不同,numpy调用预编译的高效二进制代码。你能隐藏在 numpy 中的工作越多,你在口译员中花费的时间就越少。
对代码进行矢量化后,如果代码仍然太慢,则可以开始对其进行分析。你应该能够找到很多关于如何矢量化python的简单例子,以及一些替代选项。
编辑:让我澄清一下,并行化本质上缓慢的代码大多毫无意义。首先,并行化慢速代码会给人一种错误的印象,即您已经进行了改进。并行代码的"纵向扩展"应始终针对同一代码的最快单线程版本完成(在合理范围内,在启动任何并行代码之前无需在汇编中编写所有内容)。例如,考虑争用下的锁。争夺锁的线程越多,代码运行的速度就越慢,并且您不会获得(或负面)性能提升。减少锁争用的一种方法是简单地减慢争用锁的代码。这使得它看起来好像没有锁争用的开销,而实际上 - 你没有改进,因为你最快的单线程版本的代码将优于你的并行代码。
此外,python真的不是一种学习如何编写并行代码的好语言。Python有GIL,它基本上强制python中的所有多线程代码运行,就好像只有一个CPU内核一样。这意味着必须完成奇怪的黑客(例如您链接的黑客),这些黑客有其自身的其他缺点和问题(有时需要/使用此类技巧,但它们不应该是在单台机器上运行代码的默认设置)。不要指望你学到的编写任何并行 python 代码会延续到其他语言或帮助你完成课程。
我认为你会有一些很好的成功,这取决于你的瓶颈在哪里。 需要注意的是,当我进行代码优化时,我总是喜欢分析代码,即使是非正式地了解瓶颈在哪里。 这将有助于确定时间花费在哪里,即文件 io、网络延迟、资源争用、CPU 周期不足等......
对于可能不熟悉期望最大化算法的其他人,Yair Weiss的Motion Segmentation using EM - 一个简短的教程。让我们假设我们有 M 个数据点和 N 个类/模型。
在 EM 算法中有两个步骤:计算数据点和模型之间的距离和使用加权最小二乘法更新我们的模型权重。
第 1 步 - 期望阶段
for data_point in M:
for current_model in N:
compute distance or residual between data_point and current_model
第 2 步 - 最大化阶段
for each model, compute weighted least squares solving for the model parameters
This requires solving N weighted least square problems where the size is
dependent on the number of parameters in the model that will be solved for.
瓶颈可能处于计算数据点与模型阶段 1 - E 步骤之间的残差或距离的阶段。 在此阶段,计算都是独立的。 我认为第一阶段是令人尴尬的并行的,并且非常适合使用并行映射reduce或python中的其他一些工具进行并行计算。我使用IPython完成此类任务取得了很好的成功,但还有其他很好的python包。