многопроцессорная обработка ImportError: нет модуля с именем <input> - PullRequest
0 голосов
/ 23 сентября 2019

Я использую машину 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)

Недавно мне пришлось отформатировать компьютер и после переустановки python2.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

Если я запускаю его как самостоятельный файл:

enter image description here

Поэтому мой вопрос:

  1. Почему этот код работал раньше, а не сейчас?Единственное, что (возможно) изменилось - это версия некоторых из установленных модулей, но я не думаю, что это уместно

  2. Есть предположения о том, как заставить его работать снова?

РЕДАКТИРОВАТЬ 1

Добавив if __name__ == '__main__': к коду и запустив его как самостоятельный файл, он выполняется без проблем.Тем не менее, когда я пытаюсь выполнить его в консоли Python, он предлагает ту же ошибку, что и раньше.

Судя по полученным комментариям, это могло быть связано с необходимостью заморозки кода.Код в консоли Python не заморожен, и это может быть причиной проблемы.Затем я подумал о запуске следующего примера из многопроцессорной обработки для 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 Ответ

1 голос
/ 23 сентября 2019

Вы не можете порождать новые дочерние процессы, используя mulitprocessing непосредственно из интерпретатора Python.

Из документов ,

Примечание: Функциональностьв рамках этого пакета требуется, чтобы модуль main был импортирован детьми.Это описано в Руководстве по программированию, но на это стоит обратить внимание.Это означает, что некоторые примеры, такие как примеры пула, не будут работать в интерактивном интерпретаторе.

А в директиве говорится, что

Безопасный импорт основного модуля

Убедитесь, что основной модуль может быть безопасно импортирован новым интерпретатором Python, не вызывая непреднамеренных побочных эффектов (таких как запуск нового процесса).

Вызов freeze_support () не действует при вызове в любой операционной системе, кроме Windows.Кроме того, если модуль нормально запускается интерпретатором Python в Windows (программа не была заморожена), то 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.

...