multiprocessing ImportError:没有名为<input>的模块

时间:2019-09-23 11:35:44

标签: python windows python-2.7 multiprocessing python-multiprocessing

我正在使用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并尝试运行前面描述的代码时,遇到以下错误:

  1. 如果我尝试直接从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)
    

enter image description here

  1. 如果我将其作为独立文件运行:

enter image description here

所以我的问题是:

  1. 为什么此代码以前而不是现在有效? (可能)唯一更改的是所安装的某些模块的版本,但我认为这并不相关

  2. 您猜怎么使它重新工作?

编辑1

通过将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()

该代码可能会冻结该代码,但是在python控制台中运行该代码时,会出现与以前相同的错误。enter image description here

1 个答案:

答案 0 :(得分:1)

您不能直接使用python解释器中的mulitprocessing产生新的子进程。

docs

  

注意:此软件包中的功能需要主要   该模块可由儿童导入。这在编程中有介绍   准则,但是这里值得指出。这意味着一些   示例(例如Pool示例)在交互式环境中将不起作用   解释器。

guideline

  

安全导入主模块

     

确保可以通过新的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()行,则尝试运行冻结的可执行文件(例如,使用pyinstallerpy2exe创建的可执行文件将引发RuntimeError