我在 Python 中做了一个机器学习期望最大化算法,基本上是 IBM Model1 的一个实现,用于进行机器翻译(如果你想查看代码,这里是我的 GitHub ),它可以工作,但是很慢。我现在正在学习并行计算课程,我想知道是否可以使用Python 多处理来更快地达到收敛。谁能给我任何指示或提示?我什至不知道从哪里开始。
编辑:我正在阅读并发现这篇关于使用 EM 和 MapReduce 进行并行化的论文——也许这是一个更好的主意?
我在 Python 中做了一个机器学习期望最大化算法,基本上是 IBM Model1 的一个实现,用于进行机器翻译(如果你想查看代码,这里是我的 GitHub ),它可以工作,但是很慢。我现在正在学习并行计算课程,我想知道是否可以使用Python 多处理来更快地达到收敛。谁能给我任何指示或提示?我什至不知道从哪里开始。
编辑:我正在阅读并发现这篇关于使用 EM 和 MapReduce 进行并行化的论文——也许这是一个更好的主意?
你的大部分问题是 Python 真的很慢。请记住,您的代码正在解释器中执行。当您编写代码(例如第 82 行)时,一次执行一个元素的数值计算,您将拥有该计算 - 以及 Python 解释器的所有开销。
您要做的第一件事是使用numpy对代码进行矢量化。与您的普通 python 代码不同,numpy 调用的是预编译的高效二进制代码。您可以隐藏到 numpy 中的工作越多,您在解释器中的时间就越少。
一旦你对你的代码进行了矢量化,如果它仍然太慢,你就可以开始分析它。您应该能够找到很多关于如何矢量化 python 的简单示例,以及一些替代选项。
编辑:让我澄清一下,并行化固有的慢代码几乎没有意义。首先,并行化慢代码会给人一种错误的印象,即您已经做出了改进。并行代码的“扩展”应始终针对同一代码的最快的单线程版本进行(在合理范围内,无需在开始任何并行代码之前将所有内容都写成汇编)。例如,考虑一个处于争用状态的锁。争夺锁的线程越多,代码运行的速度就越慢,您将不会获得任何(或负面的)性能提升。减少锁竞争的一种方法是简单地减慢竞争锁的代码。这看起来好像没有锁争用的开销,
此外,python 确实不是一种学习如何编写并行代码的好语言。Python 具有GIL,它本质上强制 python 中的所有多线程代码运行,就好像只有一个 CPU 内核一样。这意味着必须完成奇怪的 hack(例如您链接的那个),它们有自己的额外缺点和问题(有时需要/使用此类技巧,但它们不应该是在单个上运行代码的默认设置机器)。不要指望你所学的编写任何并行的 Python 代码可以转移到其他语言或帮助你完成你的课程。
我认为您将取得一些成功,具体取决于您的瓶颈所在。一个警告 - 当我进行代码优化时,我总是喜欢分析代码,甚至非正式地了解瓶颈所在。这将有助于确定时间花在哪里,即文件 io、网络延迟、资源争用、cpu 周期不足等...
对于可能不熟悉期望最大化算法的其他人,一个很好的介绍是使用 EM 进行运动分割 - 一个简短的教程,作者 Yair Weiss。假设我们有 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 Step 之间的残差或距离的阶段。在这个阶段,计算都是独立的。我认为第一阶段是令人尴尬的并行,并且非常适合使用并行 map reduce 或 python 中的其他一些工具进行并行计算。我在使用 IPython 完成此类任务方面取得了很好的成功,但也有其他优秀的 python 包。