我正在使用Windows计算机,并且有一个为python 2.7设计的代码,用于解决统计模型。由于模型取决于参数的值,因此我创建了并行化的版本,该版本针对参数的每个值求解一个模型。
例如,考虑一个名为main_function
的第一个文件,该文件包含以下代码(此代码出于可复制性起见,但与问题无关):
import numpy as np
import cvxpy
def lm_lasso(x, y, lambda1=None):
n = x.shape[0]
m = x.shape[1]
lambda_param = cvxpy.Parameter(sign="positive")
# Define the objective function
beta_var = cvxpy.Variable(m)
lasso_penalization = lambda_param * cvxpy.norm(beta_var, 1)
lm_penalization = (1.0 / n) * cvxpy.sum_squares(y - x * beta_var)
objective = cvxpy.Minimize(lm_penalization + lasso_penalization)
problem = cvxpy.Problem(objective)
beta_sol_list = []
for l in lambda1:
lambda_param.value = l
problem.solve(solver=cvxpy.ECOS)
beta_sol = np.asarray(np.row_stack([b.value for b in beta_var])).flatten()
beta_sol_list.append(beta_sol)
return beta_sol_list
还有另一个名为parallel_function
的文件,其中包含以下代码:
import multiprocessing as mp
import numpy as np
import functools
import zz_main_function as mf
def lm_lasso_parallel(x, y, lambda1):
chunks = np.array_split(lambda1, mp.cpu_count())
pool = mp.Pool(processes=mp.cpu_count())
results = pool.map(functools.partial(mf.lm_lasso, x, y), chunks)
pool.close()
pool.join()
return results
之所以将功能拆分为两个文件,是因为这种方式在不添加多处理所需的常规if __name__ == '__main__':
的情况下,一切似乎都能正常工作。
这段代码是几个月前编写的,可以在python控制台中运行,也可以通过runnig这样的python文件完美运行:
import zz_parallel_function as pf
from sklearn.datasets import load_boston
boston = load_boston()
x = boston.data
y = boston.target
lambda1 = [0, 1e-3, 1e-2, 1e-1, 1, 1e2, 1e3]
r_parallel = pf.lm_lasso_parallel(x, y, lambda1)
最近我不得不格式化我的计算机,当我重新安装python 2.7并尝试运行前面描述的代码时,遇到以下错误:
如果我尝试直接从python控制台运行它:
import zz_parallel_function as pf
from sklearn.datasets import load_boston
boston = load_boston()
x = boston.data
y = boston.target
lambda1 = [0, 1e-3, 1e-2, 1e-1, 1, 1e2, 1e3]
r_parallel = pf.lm_lasso_parallel(x, y, lambda1)
所以我的问题是:
为什么此代码以前而不是现在有效? (可能)唯一更改的是所安装的某些模块的版本,但我认为这并不相关
您猜怎么使它重新工作?
通过将if __name__ == '__main__':
添加到代码中并将其作为独立文件运行,它可以毫无问题地执行。但是,当我尝试在python控制台中执行它时,它会提供与以前相同的错误。
根据收到的评论,这可能是由于需要冻结代码所致。 python控制台中的代码未冻结,这可能是问题的原因。然后,我考虑从multiprocessing for windows
运行以下示例from multiprocessing import Process, freeze_support
def foo():
print 'hello'
if __name__ == '__main__':
freeze_support()
p = Process(target=foo)
p.start()
答案 0 :(得分:1)
您不能直接使用python解释器中的mulitprocessing
产生新的子进程。
从docs,
注意:此软件包中的功能需要主要 该模块可由儿童导入。这在编程中有介绍 准则,但是这里值得指出。这意味着一些 示例(例如Pool示例)在交互式环境中将不起作用 解释器。
安全导入主模块
确保可以通过新的Python解释器安全地导入主模块,而不会引起意外的副作用(例如 开始一个新过程)。
在任何操作上调用freeze_support()均无效 Windows以外的系统。另外,如果模块正在运行 通常由Windows上的Python解释器提供(程序没有 被冻结),则freeze_support()无效。
另外,应该使用if __name__ == '__main__':
来保护程序的“入口点”,如下所示:
from multiprocessing import Process, freeze_support
def f():
print 'hello world!'
if __name__ == '__main__':
freeze_support()
Process(target=f).start()
如果省略了freeze_support()
行,则尝试运行冻结的可执行文件(例如,使用pyinstaller
或py2exe
创建的可执行文件将引发RuntimeError
。