Scikit-learn: GridSearchCV se congela indefinidamente con el subproceso múltiple habilitado (es decir, w / n_jobs! = 1)

Creado en 12 ago. 2015  ·  88Comentarios  ·  Fuente: scikit-learn/scikit-learn

Me he encontrado intermitentemente con este problema (en el tema) con GridSearchCV durante más de un año, en python 2.7, 3.3 y 3.4, dos trabajos, varias plataformas / computadoras portátiles mac osx diferentes y muchas versiones diferentes de numpy y scikit- aprender (los mantengo bastante bien actualizados).

Probé todas estas sugerencias y ninguna de ellas siempre funciona:

https://github.com/scikit-learn/scikit-learn/issues/3605 - Configuración del método de inicio de multiprocesamiento en 'forkserver'
https://github.com/scikit-learn/scikit-learn/issues/2889 - Tengo problemas SOLO cuando se pasan las funciones de puntuación personalizadas (absolutamente he tenido este problema en el que las mismas llamadas GridSearchCV con n_jobs! = 1 se congelan con un anotador personalizado pero funciona bien sin uno)
https://github.com/joblib/joblib/issues/138 - Configuración de variables de entorno a partir de los recuentos de subprocesos MKL (he intentado esto cuando ejecuté un numpy / sklearn construido contra mkl desde una distribución Anaconda)
Escalando las entradas y asegurándome de que no haya errores con n_jobs = 1: estoy completamente seguro de que las cosas que estoy tratando de hacer en varios subprocesos se ejecutan correctamente en un subproceso y en una pequeña cantidad de tiempo

Es un problema muy frustrante que siempre parece volver a aparecer justo cuando estoy seguro de que se ha ido, y la ÚNICA solución que funciona el 100% del tiempo para mí es ir a la fuente de GridSearchCV en cualquier distribución de sklearn en la que esté cambiando manualmente el conjunto de backend en la llamada a Paralell a 'subprocesamiento' (en lugar de multiprocesamiento).

No he evaluado la diferencia entre ese truco y la configuración de n_jobs = 1, pero ¿habría alguna razón para esperar ganancias con el backend de subprocesos sobre ninguna paralelización? Ciertamente, no sería tan bueno como el multiprocesamiento, pero al menos es más estable.

por cierto, las versiones más recientes en las que he tenido el mismo problema son:

  • Mac OS 10.9.5
  • Python 3.4.3 :: Continuum Analytics, Inc.
  • scikit-learn == 0.16.1
  • scipy == 0.16.0
  • numpy == 1.9.2
  • pandas == 0.16.2
  • joblib == 0.8.4
Bug

Comentario más útil

@ eric-czech Si está bajo Python 3.4 o 3.5, intente configurar la siguiente variable de entorno y luego reinicie su programa de Python:

export JOBLIB_START_METHOD="forkserver"

como se explica en los documentos de joblib . El modo de forkserver no está habilitado de forma predeterminada ya que interrumpe funciones definidas de forma interactiva.

Todos 88 comentarios

¿Tiene problemas constantemente en esa plataforma?

En términos de subprocesos múltiples: hay algunos estimadores para los cuales el subproceso múltiple probablemente dará ganancias sustanciales, aquellos en los que la mayor parte del trabajo se realiza en operaciones numpy o Cython sin GIL. Realmente, no creo que esto se haya evaluado mucho; backend='threading' es algo bastante reciente.

La verdadera pregunta es: ¿qué más podemos hacer para identificar cuál es el problema?

Para empezar, ¿qué estimadores base ha considerado?

@jnothman Por plataforma, ¿OSX 10.9.5? Si es así, entonces sí, no es la primera vez que tengo ese problema.

Sin embargo, un detalle posiblemente importante que omití antes fue que siempre estoy usando portátiles IPython cuando tengo problemas. Tengo un kernel para un cuaderno cargado en este momento donde si agrego un argumento de "puntuación" con n_jobs! = 1, GridSearchCV se bloquea para siempre, pero si elimino ese argumento, todo está bien. Incluso si la función de puntuación que doy no hace más que devolver un valor flotante constante, todavía se congela (pero hace exactamente lo que esperaría con n_jobs = 1).

Re: enhebrar es bueno escuchar, así que tal vez esa opción para GridSearchCV realmente tenga sentido en ese momento.

En cuanto a los estimadores con los que tengo problemas, no estoy seguro de poder reducirlo mucho. Normalmente pruebo todos los que puedo para obtener información útil para usted aquí, solo verifiqué que podía reproducir las condiciones que mencioné anteriormente con cualquier estimador y descubrí que podía en todos los casos (o al menos lo intenté LogisticRegression, SGDClassifier, GBRT y RF).

Me encantaría hacer cualquier cosa y todo lo que pueda para proporcionar algo más para continuar, aunque no estoy familiarizado con qué contexto es generalmente más útil para problemas de subprocesos múltiples como este. ¿Tienes alguna sugerencia para mí?

¿Utiliza numpy vinculado contra el marco acelerado?

No, a menos que me esté perdiendo algo. Pensé que la versión de numpy instalada cambia cuando haces eso o al menos que el paquete de aceleración estaría presente:

(research3.4) eczech $ pip freeze | grep numpy
numpy == 1.9.2
(research3.4) actualización de eczech $ conda acelerar
Error: el paquete 'Acelerar' no está instalado en /Users/eczech/anaconda/envs/research3.4

Perdona mi ignorancia al no poder responder eso con un 100% de confianza, pero ciertamente no hice nada intencionalmente para instalarlo.

Conda Acelerar no es lo mismo que Apple Acelerar:
http://docs.continuum.io/accelerate/index
https://developer.apple.com/library/mac/documentation/Accelerate/Reference/AccelerateFWRef/

Conda Accelerate es la versión MKL de paquetes acelerados, Apple Accelerate es su alternativa a MKL.

¿Puede darnos numpy.__config__.show() ?

el multiprocesamiento no funciona con el IIRC acelerado. ping @ogrisel

ciertamente:

notario público. config .show ()
atlas_3_10_blas_threads_info:
NO DISPONIBLE
atlas_info:
NO DISPONIBLE
atlas_3_10_info:
NO DISPONIBLE
atlas_threads_info:
NO DISPONIBLE
atlas_3_10_blas_info:
NO DISPONIBLE
blas_opt_info:
extra_compile_args = ['-msse3', '-DAPPLE_ACCELERATE_SGEMV_PATCH', '-I / System / Library / Frameworks / vecLib.framework / Headers']
extra_link_args = ['-Wl, -framework', '-Wl, Acelerar']
define_macros = [('NO_ATLAS_INFO', 3)]
lapack_mkl_info:
NO DISPONIBLE
atlas_blas_info:
NO DISPONIBLE
mkl_info:
NO DISPONIBLE
lapack_opt_info:
extra_compile_args = ['-msse3', '-DAPPLE_ACCELERATE_SGEMV_PATCH']
extra_link_args = ['-Wl, -framework', '-Wl, Acelerar']
define_macros = [('NO_ATLAS_INFO', 3)]
blas_mkl_info:
NO DISPONIBLE
atlas_3_10_threads_info:
NO DISPONIBLE
openblas_info:
NO DISPONIBLE
openblas_lapack_info:
NO DISPONIBLE
atlas_blas_threads_info:
NO DISPONIBLE

Sí, ese es un problema conocido que no puedo encontrar en el rastreador de problemas. Accelerate no funciona con multiprocesamiento.

Estoy un poco confundido. El backend de subprocesos solo hace algo cuando se lanza el GIL, ¿verdad?

Entendido, ¿sabes cómo debería hacer para reconstruir Numpy entonces? ¿Debería instalarlo por pip en lugar de usar el paquete conda para ello? ¿O sería mejor construir desde la fuente y asegurarme de que los argumentos de aceleración de Apple no estén presentes?

Parece que esto es un poco incierto de todos modos. Ciérrese si solo está golpeando a un caballo muerto.

si puede acelerar la conda, funcionaría;)

tal vez podríamos intentar rescatar joblib ?

Ah, genial, continuum debe haber pagado a Apple para hacer eso jaja.

¿Tienes alguna sugerencia de $ 0? Y gracias por la información de cualquier manera.

Ah, y también sé que esto se ha preguntado antes, pero ¿es el hecho de que solo tengo este problema en mi plataforma actual cuando utilizo una función de puntuación personalizada? Por mi vida, no puedo ver qué podría ser problemático dado el código fuente grid_search.py, pero ¿podría tener algo que ver con el decapado de la función personalizada?

Y algo ajeno a eso, acabo de recordar que también traté de solucionar esto en el pasado creando una versión modificada de GridSearchCV que usa el backend paralelo IPython en su lugar, así que suponiendo que volviera a visitar esa solución, ¿valdría la pena compartirla de alguna manera? Esa solución funcionó bien, pero fue un poco difícil de usar porque las clases y funciones personalizadas tenían que estar disponibles en pythonpath en lugar de en los propios cuadernos, pero si no hay otras opciones mejores, tal vez esa tenga algunas patas.

Puede vincular contra atlas, pero eso será más lento [Apple] acelerar, me parece.
¿Quizás hay un número gratuito vinculado a MKL para OS X? Hay uno para windows.

[si eres un académico, la aceleración continua es gratis por cierto]

Estoy bastante seguro de que esto no tiene nada que ver con el uso de una función de puntuación personalizada.
¿Puede dar sniplets autónomos que rompan con una función de puntuación personalizada pero no sin ella?

Quizás el hecho de la función de puntuación personalizada sea relevante (por ejemplo, los problemas de decapado o el paralelismo anidado pueden ser pertinentes). ¿Podríamos ver el código?

¿O simplemente te refieres a una métrica estándar con make_scorer ?

Ciertamente, aquí hay una parte relevante y parece que las cosas están bien con make_scorer pero no con una función personalizada:

from sklearn.linear_model import LogisticRegression
from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import StratifiedKFold
from sklearn.metrics import average_precision_score, make_scorer
import functools

res = []
clfs = []

for response in responses:
    X, y = d_in[features], d_in[response]
    for i, (train, test) in enumerate(StratifiedKFold(y, 5)):
        X_train, y_train, X_test, y_test = X.iloc[train], y.iloc[train], X.iloc[test], y.iloc[test]
        clf = LogisticRegression(penalty='l1')
        grid = {
            'class_weight': [{0: 1, 1: 10}, {0: 1, 1: 100}, {0: 1, 1: 1000}],
            'C': np.logspace(-3, 0, num=4)
        }

        # Using make_scorer doesn't cause any issues
        # clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 3),  
        #                    scoring=make_scorer(average_precision_score), n_jobs=-1)

        # This however is a problem:
        def avg_prec_score(estimator, X, y):
            return average_precision_score(y, estimator.predict_proba(X)[:, 1])
        clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 5),  
                           scoring=avg_prec_score, n_jobs=-1)

        clf = clf.fit(X_train, y_train)
        print('Best parameters for response {} inferred in fold {}: {}'.format(response, i, clf.best_params_))

        y_pred = clf.predict(X_test)
        y_proba = clf.predict_proba(X_test)

        clfs.append((response, i, clf))
        res.append(pd.DataFrame({
            'y_pred': y_pred, 
            'y_actual': y_test, 
            'y_proba': y_proba[:,1],
            'response': np.repeat(response, len(y_pred))
        }))

res = functools.reduce(pd.DataFrame.append, res)
res.head()

Trabajaré en una versión autónoma que incluya alguna versión de los datos que estoy usando también (pero llevará más tiempo). Mientras tanto, sin embargo, el decapado de esas funciones personalizadas suena como una buena pista; lo he probado varias veces nuevamente para estar seguro y se cuelga el 100% del tiempo con una función personalizada y el 0% del tiempo cuando uso make_scorer con alguna función métrica importada conocida.

Y es que en main (es decir, el script de nivel superior que se está interpretando) o un
módulo importado?

El 15 de agosto de 2015 a las 23:37, Eric Czech [email protected] escribió:

Ciertamente, aquí hay una parte relevante y parece que todo está bien
con make_scorer pero no con una función personalizada:

desde sklearn.linear_model import LogisticRegression desde sklearn.grid_search import GridSearchCV desde sklearn.cross_validation import StratifiedKFold desde sklearn.metrics import average_precision_score, make_scorerimport functools

res = []
clfs = []
para la respuesta en las respuestas:
X, y = d_in [características], d_in [respuesta]
para i, (entrenar, probar) en enumerate (StratifiedKFold (y, 5)):
X_train, y_train, X_test, y_test = X.iloc [tren], y.iloc [tren], X.iloc [prueba], y.iloc [prueba]
clf = LogisticRegression (penalización = 'l1')
grid = {
'class_weight': [{0: 1, 1: 10}, {0: 1, 1: 100}, {0: 1, 1: 1000}],
'C': np.logspace (-3, 0, num = 4)
}

    # Using make_scorer doesn't cause any issues
    # clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 3),
    #                    scoring=make_scorer(average_precision_score), n_jobs=-1)

    # This however is a problem:
    def avg_prec_score(estimator, X, y):
        return average_precision_score(y, estimator.predict_proba(X)[:, 1])
    clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 5),
                       scoring=avg_prec_score, n_jobs=-1)

    clf = clf.fit(X_train, y_train)
    print('Best parameters for response {} inferred in fold {}: {}'.format(response, i, clf.best_params_))

    y_pred = clf.predict(X_test)
    y_proba = clf.predict_proba(X_test)

    clfs.append((response, i, clf))
    res.append(pd.DataFrame({
        'y_pred': y_pred,
        'y_actual': y_test,
        'y_proba': y_proba[:,1],
        'response': np.repeat(response, len(y_pred))
    }))

res = functools.reduce (pd.DataFrame.append, res)
res.head ()

Trabajaré en una versión autónoma que incluya alguna versión del
datos que estoy usando también (pero tomará más tiempo). Mientras tanto, sin embargo,
el decapado de esas funciones personalizadas suena como una buena pista; lo he probado
varias veces para estar seguro y se cuelga el 100% del tiempo con un personalizado
función y el 0% del tiempo cuando se usa make_scorer con algunos conocidos,
función métrica importada.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298
.

Oh, es ipynb. Hmmm interesante. Sí, el decapado podría ser un problema ...?

El 15 de agosto de 2015 a las 23:51, Joel Nothman joel. [email protected] escribió:

Y es que en main (es decir, el script de nivel superior que se está interpretando) o
un módulo importado?

El 15 de agosto de 2015 a las 23:37, Eric Czech [email protected] escribió:

Ciertamente, aquí hay una parte relevante y parece que todo está bien
con make_scorer pero no con una función personalizada:

desde sklearn.linear_model import LogisticRegression desde sklearn.grid_search import GridSearchCV desde sklearn.cross_validation import StratifiedKFold desde sklearn.metrics import average_precision_score, make_scorerimport functools

res = []
clfs = []
para la respuesta en las respuestas:
X, y = d_in [características], d_in [respuesta]
para i, (entrenar, probar) en enumerate (StratifiedKFold (y, 5)):
X_train, y_train, X_test, y_test = X.iloc [tren], y.iloc [tren], X.iloc [prueba], y.iloc [prueba]
clf = LogisticRegression (penalización = 'l1')
grid = {
'class_weight': [{0: 1, 1: 10}, {0: 1, 1: 100}, {0: 1, 1: 1000}],
'C': np.logspace (-3, 0, num = 4)
}

    # Using make_scorer doesn't cause any issues
    # clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 3),
    #                    scoring=make_scorer(average_precision_score), n_jobs=-1)

    # This however is a problem:
    def avg_prec_score(estimator, X, y):
        return average_precision_score(y, estimator.predict_proba(X)[:, 1])
    clf = GridSearchCV(clf, grid, cv=StratifiedKFold(y_train, 5),
                       scoring=avg_prec_score, n_jobs=-1)

    clf = clf.fit(X_train, y_train)
    print('Best parameters for response {} inferred in fold {}: {}'.format(response, i, clf.best_params_))

    y_pred = clf.predict(X_test)
    y_proba = clf.predict_proba(X_test)

    clfs.append((response, i, clf))
    res.append(pd.DataFrame({
        'y_pred': y_pred,
        'y_actual': y_test,
        'y_proba': y_proba[:,1],
        'response': np.repeat(response, len(y_pred))
    }))

res = functools.reduce (pd.DataFrame.append, res)
res.head ()

Trabajaré en una versión autónoma que incluya alguna versión del
datos que estoy usando también (pero tomará más tiempo). Mientras tanto, sin embargo,
el decapado de esas funciones personalizadas suena como una buena pista; lo he probado
varias veces para estar seguro y se cuelga el 100% del tiempo con un personalizado
función y el 0% del tiempo cuando se usa make_scorer con algunos conocidos,
función métrica importada.

-
Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298
.

Eso está en un cuaderno

Intentaré importarlo desde un módulo y veré cómo funciona.

Mmmm, ¿qué sabes? Funciona bien cuando se define fuera del portátil.

Básicamente, tengo el mismo código ejecutándose en Python 2.7 (necesitaba una biblioteca que sea más antigua), así como este código en Python 3.4 y aunque tengo el problema de suspensión en 2.7, independientemente de si es una función personalizada o algo que usa make_scorer, yo Creo que eso resuelve todos mis problemas en la versión más nueva para que pueda vivir con soluciones en la anterior.

¿Hay algo más que pueda hacer para averiguar por qué las funciones de decapado definidas en un portátil pueden ser un problema?

Bueno, nos gustaría entender:

  • ¿El decapado y desencadenamiento es generalmente un problema para las funciones definidas localmente en esa plataforma, o estamos teniendo un problema en particular?
  • ¿Por qué, si el decapado es un problema, se cuelga en lugar de generar una excepción? ¿Podría probar el parche de mono o similar, para ver si reemplaza el pickle.dumps(function) verifique https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/externals/joblib/parallel? py # L150 con pickle.loads(pickle.dumps(function)) da como resultado un error? (Para explicar, esta es una verificación de seguridad para garantizar la capacidad de selección antes de ejecutar el multiprocesamiento).

@ogrisel podría estar interesado en esto.

Por lo que vi en Windows, los portátiles tienen interacciones extrañas con el multiprocesamiento.

¿Ha intentado simplemente decapado y despegado de la función definida en el mismo cuaderno?

Hoy he visto accidentalmente esto https://pythonhosted.org/joblib/parallel.html#bad -interaction-of-multiprocessing-and-third-party-libraries, ¿no está relacionado?
¿Quizás debería actualizar a Python 3.4 o más reciente?

Lo siento, me fui de vacaciones largas. Sin embargo, para responder a sus preguntas:

  1. re @jnothman : puse pickle.loads(pickle.dumps(function)) en paralelo.py y una declaración de impresión después para asegurarme de que se estaba ejecutando de forma limpia y que no había problemas allí. Para ser claros, GridSearchCV.fit llamado desde el cuaderno todavía se atascó como antes sin cambios (excepto por la declaración de impresión que agregué que aparece 16 veces con n_jobs = -1).
  2. re @amueller : Si te entiendo correctamente, ejecuté algo como esto en el cuaderno sin problemas:
def test_function(x):
    return x**2
pickle.loads(pickle.dumps(test_function))(3)
# 9
  1. re @olologin : estoy en 3.4.3. O más específicamente: '3.4.3 | Continuum Analytics, Inc. | (predeterminado, 6 de marzo de 2015, 12:07:41) n [GCC 4.2.1 (compilación 5577 de Apple Inc.)] '

No he leído la conversación anterior, pero me gustaría señalar que esta prueba mínima falla bajo la compilación Python 2.6 de travis, pero pasó bajo una configuración similar en mi PC ... (lo que sugiere que falla cuando n_jobs = -1 está configurado en una máquina de un solo núcleo para las versiones antiguas de python / joblib / scipy?)

def test_cross_val_score_n_jobs():
    # n_jobs = -1 seems to hang in older versions of joblib/python2.6
    # See issue 5115
    cross_val_score(LinearSVC(), digits.data, digits.target, cv=KFold(3),
                    scoring="precision_macro", n_jobs=-1)

+1 por tener este problema, me complace proporcionar detalles si puede ayudar

@ eric-czech Si está bajo Python 3.4 o 3.5, intente configurar la siguiente variable de entorno y luego reinicie su programa de Python:

export JOBLIB_START_METHOD="forkserver"

como se explica en los documentos de joblib . El modo de forkserver no está habilitado de forma predeterminada ya que interrumpe funciones definidas de forma interactiva.

Tiene el mismo problema en OS X 10.11.4 y Ubuntu 14.04 con el último software instalado.

# Metrics
B_R = 10.0

def raw_TPR(y_true, y_pred):
    return np.sum((y_true == 1) & (y_pred == y_true))

def raw_FPR(y_true, y_pred):
    return np.sum((y_true == 0) & (y_pred != y_true))

def AMS(y_true, y_pred):
    print("Hello")
    tpr = raw_TPR(y_true, y_pred)
    fpr = raw_FPR(y_true, y_pred)
    score = np.sqrt(2 * ((tpr + fpr + B_R) * np.log(1 + tpr / (fpr + B_R))) - tpr)
    return score


# Grid search

param_grid = {
    "max_depth":[6, 10],
    "learning_rate":[0.01, 0.5],
    "subsample":[0, 1],
    "min_child_weight":[0.1, 1],
    "colsample_bytree":[0.1, 1],
    "base_score":[0.1, 1],
    "gamma":[0.5, 3.5]
}

scorer = make_scorer(AMS, greater_is_better=True)


clf = XGBClassifier()
gridclf = GridSearchCV(clf, param_grid, scorer, n_jobs=-1, verbose=2)
gridclf.fit(X_train, y_train)

En realidad, este código no se congela solo si n_jobs=1 .

Esto ahora debería funcionar de forma predeterminada en Python 3 y ser una solución habitual en Python 2, ¿verdad @ogrisel ? ¿Deberíamos cerrar?

Si se cuelga silenciosamente en Python 2 sin arrojar ninguna advertencia o error ("n_jobs> 1 no es compatible con Python 2"), eso no es aceptable; ¿Podemos lanzar un error?

@amueller en Python 3, puede seguir https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -187683383 para solucionar el problema, es decir, no funcionará de forma predeterminada incluso en Python 3.

Sin embargo, no estoy seguro de si deberíamos cerrar porque el OP original parecía decir que configurar joblib start_method en forkserver no siempre funcionaba ...

Por cierto, el xgboost es conocido, consulte https://github.com/scikit-learn/scikit-learn/issues/6627#issuecomment -206351138.

Editar: Es posible que el cambio a continuación no solucione las cosas. También hice un cambio no relacionado con la forma en que manejaba el multiprocesamiento con Pathos que podría haber sido mi solución real.

Arreglo rapido:
np.random.seed(0)

Explicación:
También me había encontrado con este problema, de manera más aguda en el conjunto de pruebas para auto_ml . Las primeras (2?) Veces que ejecuté GridSearchCV, estuvo bien, pero luego las ejecuciones posteriores se colgarían sin errores.

Simplemente configuré np.random.seed(0) dentro de cada una de mis pruebas, para garantizar la reproducibilidad y, al mismo tiempo, darme la flexibilidad de reordenar las pruebas a lo largo del tiempo sin alterar la aleatoriedad. Tan pronto como hice eso, todas las pruebas que colgaban del error GSCV comenzaron a funcionar nuevamente.

def test_name():
    np.random.seed(0)
    test_code_involving_gscv_here

¡Espero que esto ayude con la depuración!

Entorno de desarrollo:
Mac OS X (Sierra)
Python 2.7
Versiones actualizadas de bibliotecas.

@ClimbsRocks bueno, probablemente sea algún error en sus estimadores. Háganos saber si tiene un ejemplo reproducible;)

@amueller : buena

Creo que probablemente fue un problema al usar la paralelización de GSCV, cuando también estoy usando la paralelización de Pathos en otras partes del programa. Esa es la única otra cosa relacionada que he cambiado en la última semana.

Desde entonces, he refactorizado para cerrar y abrir más a fondo su grupo de multiprocesamiento.

Lo que me hace pensar que no fue solo un error en uno de los estimadores es que al construir el conjunto de pruebas, cada una de las pruebas se ejecutó y pasó individualmente. Fue solo cuando ejecuté varias pruebas en la misma pasada que todo dependía de GSCV que comenzó a colgarse.

Comentario anterior editado para notar esta incertidumbre.

si combina joblib con cualquier otra paralelización, es muy probable que falle y no debería intentarlo.

Lamento subir este hilo, pero también encuentro este problema.
Creé un kernel de Python 3.5 y definí el método de inicio de la biblioteca de trabajo para forkserver, pero todavía tengo el problema.

De hecho, ni siquiera funciona con n_jobs = 1. Veo que calcula excepto por el último parámetro.

Hay alguna noticia ?

De hecho, ni siquiera funciona con n_jobs = 1. Veo que calcula excepto por el último parámetro.

Esto es extraño y muy probablemente no esté relacionado con este problema (que es aproximadamente n_jobs != 1 ). La mejor manera de obtener buenos comentarios sería abrir un problema separado con un fragmento de código independiente que reproduzca el problema.

Estoy bastante seguro de que me estoy encontrando con este problema. Después de probar muchas combinaciones, todo lo que hago con n_jobs> 1 simplemente se congela después de algunos pliegues. Estoy en una computadora portátil Ubuntu Linux con sklearn = 0.19.0, por lo que esta es una configuración diferente de otras que he leído. Aquí está el código "ofensivo":

import xgboost as xgb
from sklearn.model_selection import GridSearchCV
cv_params = {'max_depth': [3,5,7], 'min_child_weight': [1,3,5]}

ind_params = {'learning_rate': 0.1, 'n_estimators': 1000, 'seed':0, 'subsample': 0.8, 'colsample_bytree': 0.8,  'objective': 'binary:logistic'}
optimized_XGB = GridSearchCV(xgb.XGBClassifier(**ind_params), 
                            cv_params, scoring = 'roc_auc', cv = 5, n_jobs = 1, verbose=2) 
optimized_XGB.fit(xgboost_train, label_train,eval_metric='auc')

Una de las cosas interesantes es que cuando importo xgboost, recibo una advertencia de obsolescencia en GridSearchCV como si no se estuviera importando desde model_selection. Sin embargo, estoy en xgboost 0.62 y al mirar su repositorio parece que están importando el GridSearchCV correcto. Para ser claros, la advertencia de desaprobación no es el problema que me preocupa, sino el que me ocupa: la ejecución se congela con n_jobs> 1. Solo señalando en caso de que pueda ayudar.

¿Podría proporcionar datos para ayudar a replicar el problema?

El 24 de agosto de 2017 a las 20:29, Xavier Amatriain [email protected]
escribió:

Estoy bastante seguro de que me estoy encontrando con este problema. Después de probar muchos
combinaciones, todo lo que hago con n_jobs> 1 simplemente se congela después de algunas
pliegues. Estoy en una computadora portátil Ubuntu Linux con sklearn = 0.19.0, así que esta es una
configuración diferente de otras que he leído. Aquí está el
código "ofensivo":

`importar xgboost como xgb
desde sklearn.model_selection importar GridSearchCV
cv_params = {'max_depth': [3,5,7], 'min_child_weight': [1,3,5]}

ind_params = {'tasa_de_aprendizaje': 0.1, 'n_estimadores': 1000, 'semilla': 0,
'submuestra': 0.8, 'colsample_bytree': 0.8, 'objetivo': ' binario: logístico '}
optimizado_XGB = GridSearchCV (xgb.XGBClassifier (** ind_params),
cv_params, scoring = 'roc_auc', cv = 5, n_jobs = 1, verbose = 2)
optimizado_XGB.fit (xgboost_train, label_train, eval_metric = 'auc') `

Una de las cosas interesantes es que cuando importo xgboost, obtengo un
advertencia de desaprobación en GridSearchCV como si no se estuviera importando desde
model_selection. Sin embargo, estoy en xgboost 0.62 y estoy mirando su
repositorio, parece que están importando el GridSearchCV correcto. Ser - estar
claro, la advertencia de desaprobación no es el problema que me preocupa, sino más bien
el que tenemos a mano: la ejecución congelada con n_jobs> 1. Solo señalando en
caso de que pudiera ayudar.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-324597686 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAEz66DbfTlnU_-dcxLKa5zkrcZ-0qVOks5sbVCmgaJpZM4FqYlN
.

Claro, puede descargar los archivos exactos que estoy usando desde:
https://xamat.github.io/xgboost_train.csv
https://xamat.github.io/label_train.csv

HTTP404

Lo sentimos, hubo un error en el primer enlace, ahora debería corregirse. El segundo también debería estar bien, acabo de comprobarlo.

Problema conocido con xgboost, consulte https://github.com/scikit-learn/scikit-learn/issues/6627#issuecomment -206351138 por ejemplo.

Para su información, el backend loky en joblib eliminará este tipo de problemas, pero solo estará disponible en scikit-learn 0.20.

¿Sigue siendo un error? Tengo el mismo problema con los valores predeterminados (n_jobs = 1) así como con pre_dispatch = 1, usando un RandomForestClassifier , con 80 combinaciones de parámetros y ShuffleSplit CV (n = 20).

También se cuelga para un Pipeline ( SelectKBest(score_func=mutual_info_classif, k=10) seguido de RandomForestClassifier ), tanto en la última versión como en la versión de desarrollo.

Avíseme si encontraron una solución alternativa u otros métodos de selección de modelos que funcionen de manera confiable. Pensando en probar scikit-optimize .

¿Quiere decir n_jobs = 1 o es un error tipográfico? Este problema es sobre n_jobs! = 1.

La mejor forma de obtener una retroalimentación de calidad es proporcionar una forma de reproducir el problema. Abra un problema por separado en este caso si el problema que está viendo es realmente con n_jobs = 1.

Escribí lo que quería decir, que es "multiproceso habilitado"
n_jobs! = 1 como en 'no igual a 1'. De manera equivalente, n_jobs> 1. Por ejemplo, n_jobs = 4

¿Estás diciendo que no puedes reprogramar la congelación de n_jobs = 4?

Si es así, proporcionaré un caso de prueba dentro de un mes (voy a cambiar a una nueva máquina).

El 12 de septiembre de 2017, a las 7:10 a. M., Loïc Estève < [email protected] [email protected] > escribió:

¿Quiere decir n_jobs = 1 o es un error tipográfico? Este problema es sobre n_jobs! = 1.

La mejor forma de obtener una retroalimentación de calidad es proporcionar una forma de reproducir el problema. Abra un problema por separado en este caso si el problema que está viendo es realmente con n_jobs = 1.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328864498 , o silencie el hilo https://github.com/notifications/unsubscribe- auth / ABH-rd7wgU5lcS6oD5VMl0YOB8CXfSTJks5shpDZgaJpZM4FqYlN .

@smcinerney ¿eres @raamana? Creo que @lesteve respondió a @raamana que escribió n_jobs=1 , lo que parece no estar relacionado con este problema.

Oh, lo siento, no, no soy @raamana. Sí, el problema de @ raamana es diferente (pero probablemente debido al mismo código)

El 12 de septiembre de 2017, a las 9:23 a. M., Andreas Mueller < [email protected] [email protected] > escribió:

@smcinerney https://github.com/smcinerney ¿eres @raamana https://github.com/raamana ? Creo que @lesteve https://github.com/lesteve respondió a @raamana https://github.com/raamana que escribió n_jobs = 1, que parece no estar relacionado con este problema.

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328905819 , o silencie el hilo https://github.com/notifications/unsubscribe- auth / ABH-rYKQA3L5ifINBX6enrk5oDIsf1Lqks5shrASgaJpZM4FqYlN .

Mi mal, no quise mezclar las cosas. Abriré otro problema (con un código mínimo para reproducirlo), pero GridSearchCV no está colgado incluso con n_jobs = 1 predeterminado es una preocupación mayor (dado que es predeterminado y se supone que funciona) que n_jobs> 1.

@raamana, sí, es una preocupación mayor, pero tampoco es probable que sea causada por un problema relacionado.

@ eric-checo @jnothman
Entonces, si decides usar backend = 'threading'. Un método fácil sin cambiar el código sklearn sería usar el administrador de contexto paralelo_backend y no cambiar el método de ajuste de GSV.

from sklearn.externals.joblib import parallel_backend

clf = GridSearchCV()
with parallel_backend('threading'):
    clf.fit(x_train, y_train)

PD: No estoy seguro de si el "enhebrado" funciona para todos los estimadores. Pero estaba teniendo el mismo problema con mi estimador con GSV njob> 1 y usar esto funciona como se esperaba para mí sin cambiar la biblioteca.

Sistema probado:
MAC OS: 10.12.6
Python: 3.6
numpy == 1.13.3
pandas == 0.21.0
scikit-learn == 0.19.1

Hmm ... Puede haber algunos problemas de simultaneidad con el uso del backend de subprocesos en
búsqueda de cuadrícula, por ejemplo, el error en # 10329 crea condiciones de carrera ...

El 22 de diciembre de 2017 a las 03:59, Trideep Rath [email protected] escribió:

@ eric-czech https://github.com/eric-czech @jnothman
https://github.com/jnothman
Entonces, si decides usar backend = 'threading'. Un método sencillo sin
cambiar el código sklearn sería usar el administrador de contexto paralelo_backend
y no cambiar el método de ajuste de GSV.

de sklearn.externals.joblib importar paralelo_backend

clf = GridSearchCV ()
con paralelo_backend ('subprocesamiento'):
clf.fit (tren_x, tren_y)

PD: No estoy seguro de si el "enhebrado" funciona para todos los estimadores. Pero yo estaba
tener el mismo problema con mi estimador con GSV njob> 1 y usar esto
funciona como se esperaba para mí sin cambiar la biblioteca.

Sistema probado:
MAC OS: 10.12.6
Python: 3.6
numpy == 1.13.3
pandas == 0.21.0
scikit-learn == 0.19.1

-
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-353402474 ,
o silenciar el hilo
https://github.com/notifications/unsubscribe-auth/AAEz64SfwYpjLU1JK0vukBRXJvWYs3LKks5tCo51gaJpZM4FqYlN
.

Caso: Usar backend como "subprocesamiento" y usar Estimator que extiende BaseEstimator y ClassifierMixin. No estoy seguro de dónde se debe la condición de carrera. ¿Puede dar más detalles?

Según mi comprensión y experimentos, no observé ninguna condición de carrera.

out = Parallel(
    n_jobs=self.n_jobs, verbose=self.verbose,
    pre_dispatch=pre_dispatch
)(delayed(_fit_and_score)(clone(base_estimator), X, y, scorers, train,
                          test, self.verbose, parameters,
                          fit_params=fit_params,
                          return_train_score=self.return_train_score,
                          return_n_test_samples=True,
                          return_times=True, return_parameters=False,
                          error_score=self.error_score)
  for parameters, (train, test) in product(candidate_params,
                                           cv.split(X, y, groups)))

_fit_and_score se llama en el clon (base_estimator). Esto hace una copia profunda y tiene una copia de sus propios datos.

out es el resultado del método _fit_and_score. Entonces, después de esto, todos los hilos completaron la ejecución del método de ajuste del estimador e informaron los resultados.

Los resultados son los que obtiene de GCV_clf.cv_results_

¿Podría explicar en este caso específico por qué causaría una condición de carrera?

La condición de carrera ocurre si está configurando parámetros anidados, es decir, cuando
un parámetro cambiado es un estimador y otro es un parámetro de ese
estimador.

Estoy experimentando el mismo problema al usar make_scorer en combinación con GridSearchCv y n_jobs=-1 en Win 7 con versiones recientes:

Windows-7-6.1.7601-SP1
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)]
NumPy 1.12.1
SciPy 1.0.0
Scikit-Learn 0.19.1

@mansenfranzen ¡ gracias por publicar sus versiones y plataforma! La mejor posibilidad de obtener una retroalimentación de buena calidad es proporcionar un fragmento independiente para reproducir el problema. Lea https://stackoverflow.com/help/mcve para obtener más detalles.

Experimentar el mismo problema en Win7 con cualquier paso de preprocesamiento personalizado.
Cadena de herramientas:

Python 3.6.2
NumPy 1.13.1, 1.14.2 (under both)
SciPy 1.0.0
SkLearn 0.19.1

MCVE:

from sklearn.pipeline import Pipeline, make_pipeline
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
import numpy as np

class CustomTransformer:
    def fit(self, X, y):
        return self

    def transform(self, X):
        return X

pipeline = make_pipeline(CustomTransformer(),
                         SVC())

X_train = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0], [7.0, 8.0]])
y_train = np.array([1.0, 0.0, 0.0, 1.0])

print(cross_val_score(pipeline, X_train, y_train, cv=2, n_jobs=-1))

¿Sabe que el multiprocesamiento de Python no funcionará en Windows sin if __name__ == '__main__' ?

Sí lo soy. Lo siento, olvidé decirle que estoy usando Jupyter.
Un script independiente con if __name__ == '__main__' imprime los siguientes trazos y luego se congela:

Process SpawnPoolWorker-1:
Traceback (most recent call last):
  File "C:\Python\Python36\lib\multiprocessing\process.py", line 249, in _bootstrap
    self.run()
  File "C:\Python\Python36\lib\multiprocessing\process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Python\Python36\lib\multiprocessing\pool.py", line 108, in worker
    task = get()
  File "C:\Python\Python36\lib\site-packages\sklearn\externals\joblib\pool.py", line 362, in get
    return recv()
  File "C:\Python\Python36\lib\multiprocessing\connection.py", line 251, in recv
    return _ForkingPickler.loads(buf.getbuffer())
AttributeError: Can't get attribute 'CustomTransformer' on <module '__mp_main__' from 'C:\\projects\\Python\\Sandbox\\test.py'>
< same for SpawnPoolWorker-3 here >

Oh, interesante. Por simple pereza, coloqué todo el script debajo de if __name__ == '__main__' y obtuve los resultados del comentario anterior.

Ahora coloqué solo pipeline = make_pipeline... , y se ejecutó correctamente. ¿Quizás sea la causa en Jupyter?

De todos modos, no sé si el comportamiento del comentario anterior es válido y está causado por el uso indebido de if __name__ == '__main__' , o si es culpa de SkLearn.

parece que no es un problema con nuestra biblioteca, sino con la ejecución
contexto para multiprocesamiento en Windows ...

Eso es asqueroso. Y de hecho, no pude reproducir ninguno de los problemas en Ubuntu con las mismas versiones de todo. ¡Gracias por la ayuda!

Puedo confirmar que este error está vivo y coleando.

Ejecutando en Windows 10 en un cuaderno jupyter, Python3, Sklearn 0.19.1

El mismo problema en Linux Mint (Ubuntu 16.10) Python 3.5

Todo se atasca en la primera Epoch en cada núcleo y las CPU están inactivas, por lo que no se está realizando ningún trabajo.

@MrLobs eso suena como un error de decapado, ¿verdad? coloque CustomTransformer en un archivo de Python separado.

@ Chrisjw42 @avatsaev sin más contexto no podemos hacer mucho.
@avatsaev suena como si estuvieras usando tensorflow?

@amueller sí es tensorflow

@avatsaev, eso todavía no es suficiente información. ¿Tienes un ejemplo mínimo para reproducir? qué blas estás usando, estás usando GPU, qué versión de scikit-learn estás usando ...

Ok, resulta que es porque estoy usando TF GPU, por lo que configurar n_jobs en> 1 realmente no funciona, lo cual es normal porque solo tengo una GPU lol

sí, no deberías usar n_jobs con TF de ninguna manera.

¿Por qué no?

@amueller , sí, poner transformadores personalizados en un archivo separado lo resuelve

¿Sería posible que n_jobs! = 1 arrojara un error (o al menos una advertencia) en los entornos en los que se mantendrá? Acabo de encontrar este problema en los cuadernos de jupyter, y si yo fuera un usuario más principiante (como el resto de mi clase), nunca me habría dado cuenta de por qué gridsearchcv seguía colgando, de hecho, nuestro profesor incluso nos aconsejó que usáramos n_jobs = - 1. Si se conoce el problema aquí, ¿podría el paquete (keras o sklearn, lo que sea) advertir que ocurrirá y evitar el bloqueo?

No creo que nadie sepa en qué entorno se va a colgar ... No creo que nadie haya logrado reproducir este error de manera confiable.

pero estamos trabajando para mejorar nuestra infraestructura de multiprocesamiento.
No tengo claro si eso resolverá todos esos problemas.

@jnothman 👍

¡Es genial escuchar eso!

No estoy seguro de por qué está etiquetado como 0.21. Esto se resuelve en 0,20 en la mayoría de los casos. Creo que deberíamos cerrar esto y hacer que la gente abra nuevos temas. Este es demasiado largo e inespecífico.

Acabo de encontrar lo mismo en AWS Ubuntu con jupyter ...

El uso de paralelo_backend parece funcionar ...


from sklearn.externals.joblib import parallel_backend

clf = GridSearchCV(...)
with parallel_backend('threading'):
    clf.fit(x_train, y_train)

@morienor si puede reproducir este problema con scikit-learn 0.20.1, abra un nuevo problema con todos los detalles necesarios para que otra persona pueda reproducir el problema (el script completo con declaraciones de importación en un conjunto de datos aleatorio falso) junto con todos los números de versión para python, scikit-learn, numpy, scipy y el sistema operativo.

Acabo de encontrar lo mismo en AWS Ubuntu con jupyter ...

El uso de paralelo_backend parece funcionar ...


from sklearn.externals.joblib import parallel_backend

clf = GridSearchCV(...)
with parallel_backend('threading'):
    clf.fit(x_train, y_train)

¡Eso funciona para mí! ¡Muchas gracias!

@ jmq19950824 @morienor sí, pero no tiene sentido usar threading backend debido a GIL.

Acabo de encontrar lo mismo en AWS Ubuntu con jupyter ...

El uso de paralelo_backend parece funcionar ...


from sklearn.externals.joblib import parallel_backend

clf = GridSearchCV(...)
with parallel_backend('threading'):
    clf.fit(x_train, y_train)

el genio funciona para mí

¿Fue útil esta página
0 / 5 - 0 calificaciones