多处理 ImportError:没有名为 <input> 的模块

Posted

技术标签:

【中文标题】多处理 ImportError:没有名为 <input> 的模块【英文标题】:multiprocessing ImportError: No module named <input> 【发布时间】:2020-01-23 11:22:58 【问题描述】:

我使用的是 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 控制台还是运行 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)
    

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

所以我的问题是:

    为什么这段代码以前有效而现在无效?唯一(可能)改变的是安装的一些模块的版本,但我认为这无关紧要

    你猜猜如何让它再次工作?

编辑 1

通过将if __name__ == '__main__': 添加到代码中并将其作为独立文件运行,它可以毫无问题地执行。但是,当我尝试在 python 控制台中执行它时,它会提供与以前相同的错误。

根据收到的 cmets,这可能是由于冻结代码的必要性。 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 控制台中运行它时,我得到了和以前一样的错误。

【问题讨论】:

if __name__ == '__main__' 在 windows iirc 中使用多处理时始终需要保护,因为在 windows 中创建进程的方式 Alvaro,你能不能 if __name__ == '__main__':..r_parallel = pf.lm_lasso_parallel(x, y, lambda1) 和类似地在另一个文件中看看? @hansolo。如果我添加 if __name__ == '__main__' 并在 python 控制台中运行它,我会得到与问题中发布的相同的错误。如果我将它作为独立文件运行,它似乎工作正常。这是否意味着无法直接从 python 控制台运行并行化代码? 我查看了多处理指南docs.python.org/2/library/multiprocessing.html 并尝试在我的python 控制台中运行第一个示例。结果相同。 Alvaro,控制台中的代码没有冻结。代码应该被冻结以便在 Windows 中运行。让我检查一下,是否有任何方法可以从控制台运行,尽管我认为机会很小 【参考方案1】:

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

来自docs,

注意:此包中的功能需要 ma​​in 模块可由孩子们导入。这在编程中有所介绍 指南但是值得在这里指出。这意味着一些 示例,例如 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

【讨论】:

以上是关于多处理 ImportError:没有名为 <input> 的模块的主要内容,如果未能解决你的问题,请参考以下文章

ImportError:没有模块名为六

“ImportError:没有名为 selenium 的模块”

ImportError:没有名为地理编码器的模块

ImportError:没有名为 scipy 的模块

ImportError:没有名为“utils”的模块

ImportError:没有名为“backports”的模块