Scikit-learn: L'exécution parallèle de GridSearchCV avec son propre marqueur se bloque

Créé le 24 févr. 2014  ·  99Commentaires  ·  Source: scikit-learn/scikit-learn

J'ai cherché des heures sur ce problème et je peux le reproduire de manière cohérente :

clf = GridSearchCV( sk.LogisticRegression(),
                            tuned_parameters,
                            cv = N_folds_validation,
                            pre_dispatch='6*n_jobs', 
                            n_jobs=4,
                            verbose = 1,
                            scoring=metrics.make_scorer(metrics.scorer.f1_score, average="macro")
                        )

Cet extrait se bloque à cause de scoring=metrics.make_scorer(metrics.scorer.f1_score, average="macro") où les métriques font référence au module sklearn.metrics. Si j'annule la ligne scoring=..., l'exécution parallèle fonctionne. Si je veux utiliser le score f1 comme méthode d'évaluation, je dois annuler l'exécution parallèle en définissant n_jobs = 1.

Existe-t-il un moyen de définir une autre méthode de partition sans perdre la possibilité d'exécution parallèle ?

Merci

Commentaire le plus utile

Hum, cela est probablement lié à des problèmes de multitraitement sur Windows. Peut-être que @GaelVaroquaux ou @ogrisel peuvent vous aider.
Je ne sais pas ce que le cahier fait du __name__ == "__main__" .
Essayez de ne pas définir la métrique dans le bloc-notes, mais dans un fichier séparé et importez-le. Je pense que ça arrangerait ça.
Ce n'est pas vraiment lié à GridSearchCV, mais à une interaction intéressante entre le multitraitement Windows, le bloc-notes IPython et joblib.

Tous les 99 commentaires

C'est surprenant, nous devrons donc déterminer quel est le problème et nous assurer que cela fonctionne !

Pouvez-vous s'il vous plaît fournir un peu plus de détails:

  • Qu'entendez-vous par « crash » ?
  • De quelle version de scikit-learn s'agit-il ? S'il s'agit de 0,14, cela se produit-il toujours dans la version de développement actuelle ?
  • Le multitraitement a des problèmes spécifiques à la plate-forme. Tu es sur quelle plateforme ? (par exemple import platform; platform.platform() )
  • L'avez-vous essayé sur différents jeux de données ?

FWIW, ma machine n'a aucun problème à ajuster l'iris avec cet extrait sur la version de développement de sklearn.

Merci pour votre réponse rapide.

Avec crash, je veux dire geler. Cela ne continue plus et il n'y a également plus d'activité à surveiller dans le processus python du gestionnaire de tâches de windows. Les processus sont toujours là et consomment une quantité constante de RAM mais ne nécessitent aucun temps de traitement.

Il s'agit de la version 0.14 de scikit-learn, mise à jour pour la dernière fois et exécutée à l'aide d'Enthought Canopy.

Je suis sur la plate-forme "Windows-7-6.1.7601-SP1".

J'irai plus en profondeur en fournissant un exemple générique du problème. Je pense que cela a à voir avec le GridSearchCV placé dans une boucle for. (Pour ne pas perdre trop de temps, vous devriez probablement commencer par la méthode run_tune_process() qui est appelée en bas du code et appelle la méthode contenant GridSearchCV() dans une boucle for)

Code:

import sklearn.metrics as metrics
from sklearn.grid_search import GridSearchCV
import numpy as np
import os
from sklearn import datasets
from sklearn import svm as sk


def tune_hyperparameters(trainingData, period):
    allDataTrain = trainingData

    # Define hyperparameters and construct a dictionary of them
    amount_kernels = 2
    kernels = ['rbf','linear']
    gamma_range =   10. ** np.arange(-5, 5)
    C_range =       10. ** np.arange(-5, 5)
    tuned_parameters = [
                        {'kernel': ['rbf'],     'gamma': gamma_range , 'C': C_range},
                        {'kernel': ['linear'],  'C': C_range}
                       ]

    print("Tuning hyper-parameters on period = " + str(period) + "\n")

    clf = GridSearchCV( sk.SVC(), 
                        tuned_parameters,
                        cv=5,
                        pre_dispatch='4*n_jobs', 
                        n_jobs=2,
                        verbose = 1,
                        scoring=metrics.make_scorer(metrics.scorer.f1_score, average="macro")
                        )
    clf.fit(allDataTrain[:,1:], allDataTrain[:,0:1].ravel())

    # other code will output some data to files, graphs and will save the optimal model with joblib package


    #   Eventually we will return the optimal model
    return clf

def run_tune_process(hyperparam_tuning_method,trainingData, testData):    
    for period in np.arange(0,100,10):
                clf = hyperparam_tuning_method(trainingData,period)

                y_real = testData[:,0:1].ravel()
                y_pred = clf.predict(testData[:,1:])

# import some data to play with
iris = datasets.load_iris()
X_training = iris.data[0:100,:]  
Y_training = (iris.target[0:100]).reshape(100,1)
trainingset = np.hstack((Y_training, X_training))

X_test = iris.data[100:150,:]  
Y_test = (iris.target[100:150]).reshape(50,1)
testset = np.hstack((Y_test, X_test))

run_tune_process(tune_hyperparameters,trainingset,testset)

Encore une fois, ce code ne fonctionne sur mon ordinateur que lorsque je modifie n_jobs à 1 ou lorsque je ne définis pas d'argument scoring=.

Généralement, le multitraitement sous Windows rencontre beaucoup de problèmes. Mais je
Je ne sais pas pourquoi cela devrait être corrélé avec une métrique personnalisée. Il y a
rien sur l'option moyenne=macro dans 0.14 qui suggère qu'elle devrait être
plus susceptible de se bloquer que la moyenne par défaut (pondérée). Au développement
head, cela se termine en 11s sur mon macbook, et en 7s à la version 0.14
(c'est quelque chose à vérifier!)

Pouvez-vous essayer cela dans la version de développement actuelle, pour voir si
c'est toujours un problème ?

Le 25 février 2014 à 20h40, adverley [email protected] a écrit :

Merci pour votre réponse rapide.

Avec crash, je veux dire geler. ça ne continue plus et
il n'y a également plus d'activité à surveiller dans le processus python de
gestionnaire de tâches de windows. Les processus sont toujours là et consomment un
quantité constante de RAM mais ne nécessitent aucun temps de traitement.

Il s'agit de la version 0.14 de scikit-learn, mise à jour pour la dernière fois et exécutée à l'aide d'Enthought
Canopée.

Je suis sur la plate-forme "Windows-7-6.1.7601-SP1".

J'irai plus en profondeur en fournissant un exemple générique du problème. je
pense que cela a à voir avec le GridSearchCV placé dans une boucle for. (À
ne perdez pas trop de temps, vous devriez probablement commencer par le
méthode run_tune_process() qui est appelée en bas du code
et appelle la méthode contenant GridSearchCV() dans une boucle for)
Code:

importer sklearn.metrics en tant que métriques
de sklearn.grid_search importer GridSearchCV
importer numpy en tant que np
importer le système d'exploitation
à partir de jeux de données d'importation sklearn
de sklearn importer svm en tant que sk

def tune_hyperparameters(trainingData, période):
allDataTrain = trainingData

# Define hyperparameters and construct a dictionary of them
amount_kernels = 2
kernels = ['rbf','linear']
gamma_range =   10. ** np.arange(-5, 5)
C_range =       10. ** np.arange(-5, 5)
tuned_parameters = [
                    {'kernel': ['rbf'],     'gamma': gamma_range , 'C': C_range},
                    {'kernel': ['linear'],  'C': C_range}
                   ]

print("Tuning hyper-parameters on period = " + str(period) + "\n")

clf = GridSearchCV( sk.SVC(),
                    tuned_parameters,
                    cv=5,
                    pre_dispatch='4*n_jobs',
                    n_jobs=2,
                    verbose = 1,
                    scoring=metrics.make_scorer(metrics.scorer.f1_score, average="macro")
                    )
clf.fit(allDataTrain[:,1:], allDataTrain[:,0:1].ravel())

# other code will output some data to files, graphs and will save the optimal model with joblib package


#   Eventually we will return the optimal model
return clf

def run_tune_process(hyperparam_tuning_method,trainingData, testData):
pour la période dans np.arange(0,100,10) :
clf = hyperparam_tuning_method(trainingData,période)

            y_real = testData[:,0:1].ravel()
            y_pred = clf.predict(testData[:,1:])

importer des données pour jouer avec

iris = jeux de données.load_iris()
X_training = iris.data[0:100,:]
Y_training = (iris.target[0:100]).reshape(100,1)
trainingset = np.hstack((Y_training, X_training))

X_test = iris.data[100:150,:]
Y_test = (iris.target[100:150]).reshape(50,1)
ensemble de tests = np.hstack((Y_test, X_test))

run_tune_process(tune_hyperparameters,trainingset,testset)

Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment -35990430
.

(En passant ,
surcharge de parallélisation dans le maître - sur OS X au moins - ce n'était pas là
en 0,14...)

Le 25 février 2014 à 21h52, Joel Nothman [email protected] a écrit :

Généralement, le multitraitement sous Windows rencontre beaucoup de problèmes. Mais je
Je ne sais pas pourquoi cela devrait être corrélé avec une métrique personnalisée. Il y a
rien sur l'option moyenne=macro dans 0.14 qui suggère qu'elle devrait être
plus susceptible de se bloquer que la moyenne par défaut (pondérée). Au développement
head, cela se termine en 11s sur mon macbook, et en 7s à la version 0.14
(c'est quelque chose à vérifier!)

Pouvez-vous essayer cela dans la version de développement actuelle, pour voir si
c'est toujours un problème ?

Le 25 février 2014 à 20h40, adverley [email protected] a écrit :

Merci pour votre réponse rapide.

Avec crash, je veux dire geler. ça ne continue plus et
il n'y a également plus d'activité à surveiller dans le processus python de
gestionnaire de tâches de windows. Les processus sont toujours là et consomment un
quantité constante de RAM mais ne nécessitent aucun temps de traitement.

Il s'agit de la version 0.14 de scikit-learn, mise à jour pour la dernière fois et exécutée à l'aide d'Enthought
Canopée.

Je suis sur la plate-forme "Windows-7-6.1.7601-SP1".

J'irai plus en profondeur en fournissant un exemple générique du problème.
Je pense que cela a à voir avec le GridSearchCV placé dans une boucle for. (À
ne perdez pas trop de temps, vous devriez probablement commencer par le
méthode run_tune_process() qui est appelée en bas du code
et appelle la méthode contenant GridSearchCV() dans une boucle for)
Code:

importer sklearn.metrics en tant que métriques
de sklearn.grid_search importer GridSearchCV
importer numpy en tant que np
importer le système d'exploitation
à partir de jeux de données d'importation sklearn
de sklearn importer svm en tant que sk

def tune_hyperparameters(trainingData, période):
allDataTrain = trainingData

# Define hyperparameters and construct a dictionary of them
amount_kernels = 2
kernels = ['rbf','linear']
gamma_range =   10. ** np.arange(-5, 5)
C_range =       10. ** np.arange(-5, 5)
tuned_parameters = [
                    {'kernel': ['rbf'],     'gamma': gamma_range , 'C': C_range},
                    {'kernel': ['linear'],  'C': C_range}
                   ]

print("Tuning hyper-parameters on period = " + str(period) + "\n")

clf = GridSearchCV( sk.SVC(),
                    tuned_parameters,
                    cv=5,
                    pre_dispatch='4*n_jobs',
                    n_jobs=2,
                    verbose = 1,
                    scoring=metrics.make_scorer(metrics.scorer.f1_score, average="macro")
                    )
clf.fit(allDataTrain[:,1:], allDataTrain[:,0:1].ravel())

# other code will output some data to files, graphs and will save the optimal model with joblib package


#   Eventually we will return the optimal model
return clf

def run_tune_process(hyperparam_tuning_method,trainingData, testData):
pour la période dans np.arange(0,100,10) :
clf = hyperparam_tuning_method(trainingData,période)

            y_real = testData[:,0:1].ravel()
            y_pred = clf.predict(testData[:,1:])

importer des données pour jouer avec

iris = jeux de données.load_iris()
X_training = iris.data[0:100,:]
Y_training = (iris.target[0:100]).reshape(100,1)
trainingset = np.hstack((Y_training, X_training))

X_test = iris.data[100:150,:]
Y_test = (iris.target[100:150]).reshape(50,1)
ensemble de tests = np.hstack((Y_test, X_test))

run_tune_process(tune_hyperparameters,trainingset,testset)

Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment -35990430
.

Cela n'a rien à voir avec les marqueurs personnalisés. C'est une fonctionnalité bien connue du multitraitement Python sous Windows : vous devez exécuter tout ce qui utilise n_jobs=-1 dans un bloc if __name__ == '__main__' ou vous obtiendrez des blocages/plantages. Peut-être devrions-nous documenter cela quelque part en évidence, par exemple dans le README ?

vous devez exécuter tout ce qui utilise n_jobs= -1 dans un nom if ==
bloc ' main ' ou vous obtiendrez des blocages/plantages.

Eh bien, la bonne nouvelle est que de nos jours, joblib donne une erreur significative
message sur un tel accident, plutôt qu'une bombe à fourche.

@GaelVaroquaux, le scikit-learn actuel donne-t-il ce message d'erreur? Si tel est le cas, le problème peut être considéré comme résolu, à mon humble avis.

@GaelVaroquaux, le scikit-learn actuel donne-t-il ce message d'erreur? Si c'est le cas, le
problème peut être considéré comme résolu, à mon humble avis.

Ça devrait le faire. Le seul moyen d'être sûr est de vérifier. je suis en mouvement à droite
maintenant, et je ne peux pas démarrer une machine virtuelle Windows pour le faire.

Je ne vais pas installer un compilateur C sur Windows juste pour ça. Désolé, mais je ne fais vraiment pas Windows :)

Je ne vais pas installer un compilateur C sur Windows juste pour ça. Désolé mais je
ne fais vraiment pas Windows :)

J'ai une machine virtuelle Windows. je peux vérifier. C'est juste une question de trouver un
peu de temps pour le faire.

@larsmans , tu as tout à fait raison. L'objet scoreur personnalisé était une erreur de ma part, le problème réside en effet dans le multitraitement sur windows. J'ai essayé ce même code sur un Linux et il fonctionne bien.

Je ne reçois aucun message d'erreur car il ne plante pas, il arrête simplement de faire quelque chose de significatif.

@adverley Pourriez-vous essayer la version la plus récente de GitHub sur votre ordinateur Windows ?

Fermeture en raison d'un manque de retour d'information et il s'agit probablement d'un problème connu qui est résolu dans la nouvelle joblib.

Je ne sais pas si c'est lié, ça semble l'être.

Dans Windows, le marqueur personnalisé se fige toujours. J'ai rencontré ce fil sur google - j'ai supprimé le marqueur et la recherche par grille fonctionne.

Lorsqu'il se fige, il n'affiche aucun message d'erreur. Il y a aussi 3 processus python générés (car j'ai défini n_jobs=3). Cependant, l'utilisation du processeur reste 0 pour tous les processus python. J'utilise IPython Notebook.

Pouvez-vous partager le code du marqueur ? Cela semble un peu improbable.

Votre marqueur utilise-t-il joblib / n_jobs n'importe où ? Cela ne devrait pas, et cela pourrait peut-être causer des problèmes (bien que je pense que joblib devrait le détecter).

Bien sûr - voici le code complet - http://pastebin.com/yUE26SNs

La fonction scorer est "score_model", elle n'utilise pas joblib.

Cela s'exécute à partir de l'invite de commande, mais pas à partir d'IPython Notebook. Le message d'erreur est -
AttributeError: Can't get attribute 'score_model' on <module '__main__' (built-in)>;

Ensuite, IPython et toutes les instances python générées deviennent inactives - silencieusement - et ne répondent plus à aucun code python jusqu'à ce que je le redémarre.

Corrigez l'erreur d'attribut, cela fonctionnera.
Faites-vous des importations pylab dans le bloc-notes IPython? Sinon tout devrait être pareil.

Eh bien, je ne sais pas ce qui cause l'AttributeError... Bien qu'il soit probablement lié aux joblibs, puisque _cela ne se produit que lorsque n_jobs est supérieur à 1_, fonctionne bien avec n_jobs=1 .

L'erreur parle de l'attribut score_model manquant dans __main__ , que j'aie ou non un if __name__ == '__main__' dans le bloc-notes IPython.

(J'ai réalisé que la ligne d'erreur avait été collée de manière incorrecte ci-dessus - j'ai édité dans le message ci-dessus.)

Je n'utilise pas pylab.

Voici le message d'erreur étendu complet - http://pastebin.com/23y5uHT2

Hum, cela est probablement lié à des problèmes de multitraitement sur Windows. Peut-être que @GaelVaroquaux ou @ogrisel peuvent vous aider.
Je ne sais pas ce que le cahier fait du __name__ == "__main__" .
Essayez de ne pas définir la métrique dans le bloc-notes, mais dans un fichier séparé et importez-le. Je pense que ça arrangerait ça.
Ce n'est pas vraiment lié à GridSearchCV, mais à une interaction intéressante entre le multitraitement Windows, le bloc-notes IPython et joblib.

les gars... merci pour le fil. Quoi qu'il en soit, j'aurais dû vérifier ce fil avant, j'ai perdu 5 heures de mon temps là-dessus. Essayer de fonctionner en traitement parallèle. Merci beaucoup :)
POUR AJOUTER UN RETOUR : il gèle encore. J'ai rencontré le même problème en présence de ma propre fonction de coût make_Score..mon système commence à geler. Lorsque je n'ai pas utilisé la fonction de coût personnalisé, je n'ai pas été confronté à ces blocages dans le traitement en parallèle

La meilleure façon de transformer ces 5 heures en quelque chose d'utile pour le projet serait de nous fournir un exemple autonome reproduisant le problème.

Je rencontrais le même problème sur Windows 10 travaillant dans le bloc-notes Jupyter en essayant d'utiliser un scoreur personnalisé dans une validation croisée imbriquée et n_jobs=-1. Je recevais le message AttributeError: Can't get attribute 'custom_scorer' on <module '__main__' (built-in)>; .
Comme @amueller l'a suggéré, importer le marqueur personnalisé au lieu de le définir dans le cahier fonctionne.

J'ai exactement le même problème sur OSX 10.10.5

Pareil ici.
OSX 10.12.5

Veuillez fournir un extrait de code reproductible. Nous aimerions aller au fond des choses. Il est difficile de comprendre sans code, y compris les données, qui nous montre le problème.

Exécutez simplement ces lignes dans un shell python

import numpy as np
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.preprocessing import RobustScaler
from sklearn.metrics import classification_report
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_predict

np.random.seed(1234)
X = np.random.sample((1000, 100))
Y = np.random.sample((1000)) > 0.5
svc_pipeline = Pipeline([('pca', PCA(n_components=95)), ('svc', SVC())])
predictions = cross_val_predict(svc_pipeline, X, Y, cv=30, n_jobs=-1)
print classification_report(Y, predictions)

Notez que la suppression de l'étape PCA du pipeline résout le problème.

Plus d'informations:

Darwin-16.6.0-x86_64-i386-64bit
('Python', '2.7.13 (par défaut, 4 avril 2017, 08:47:57) \n[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]')
('NumPy', '1.12.1')
('SciPy', '0.19.1')
('Scikit-Apprendre', '0.18.2')

étant donné que vous n'utilisez pas de marqueur personnalisé, devrions-nous supposer qu'il s'agit d'un
problème séparé?

Le 8 août 2017 à 18h15, "boazsh" [email protected] a écrit :

Exécutez simplement ces lignes dans un shell python

de sklearn.decomposition importer PCAde sklearn.svm importer SVCde sklearn.preprocessing importer RobustScalerde sklearn.metrics importer classification_reportde sklearn.pipeline importer Pipelinede sklearn.model_selection importer cross_val_predict

X = np.random.sample((1000, 100))
Y = np.échantillon.aléatoire ((1000)) > 0,5
svc_pipeline = Pipeline([('pca', PCA(n_composants=95)), ('svc', SVC())])
prédictions = cross_val_predict(svc_pipeline, X, Y, cv=30, n_jobs=-1)print classification_report(Y, prédictions)

Notez que la suppression de l'étape PCA du pipeline résout le problème.

Plus d'informations:

scikit-learn==0.18.2
scipy==0.19.1
numpy==1.12.1

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment-320885103 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAEz6-6Klhc67b5kZ17fFTxc8RfZQ_BWks5sWBkLgaJpZM4BkiD9
.

Lorsque j'ai rencontré ce problème pour la première fois, j'utilisais un marqueur personnalisé, mais en essayant de simplifier autant que possible l'exemple de code, j'ai découvert qu'il ne devait pas nécessairement contenir un marqueur personnalisé. Du moins sur ma machine. L'importation du marqueur n'a pas non plus aidé dans mon cas. Quoi qu'il en soit, les symptômes se ressemblent. Le script se bloque pour toujours et l'utilisation du processeur est faible.

@boazsh merci beaucoup pour l'extrait, il n'est cependant pas déterministe, pouvez-vous le modifier et utiliser un np.random.RandomState pour vous assurer que les nombres aléatoires sont toujours les mêmes à chaque exécution.

Il existe également une solution de contournement si vous utilisez Python 3 suggérée par exemple dans https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -187683383.

Je n'ai pas de moyen de tester cela sur OSX pour le moment, mais je pourrai peut-être essayer dans les prochains jours.

Quelques informations utiles (ajoutez simplement ce qui manque à votre commentaire précédent https://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment-320885103):

import platform; print(platform.platform())
import sys; print("Python", sys.version)
import numpy; print("NumPy", numpy.__version__)
import scipy; print("SciPy", scipy.__version__)
import sklearn; print("Scikit-Learn", sklearn.__version__)

Aussi comment as-tu installé scikit-learn, avec pip, avec conda, avec l'un des gestionnaires de paquets OSX (brew, etc...) ?

Mise à jour de l'extrait (utilisé np.random.seed)

Darwin-16.6.0-x86_64-i386-64bit
('Python', '2.7.13 (par défaut, 4 avril 2017, 08:47:57) \n[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.38)]')
('NumPy', '1.12.1')
('SciPy', '0.19.1')
('Scikit-Apprendre', '0.18.2')

Mise à jour de l'extrait (utilisé np.random.seed)

Merci beaucoup!

Aussi comment as-tu installé scikit-learn, avec pip, avec conda, avec l'un des gestionnaires de paquets OSX (brew, etc...) ?

Avez-vous répondu à celui-ci, je ne trouve pas votre réponse ...

Désolé, je l'ai raté - pip.

FWIW, je n'ai aucun problème à exécuter cet extrait avec :

plate-forme d'importation; print(plateforme.plateforme())
Darwin-16.7.0-x86_64-i386-64bit
système d'importation ; print("Python", sys.version)
Python 2.7.12 |Continuum Analytics, Inc.| (par défaut, le 2 juillet 2016, 17:43:17)
[GCC 4.2.1 (Basé sur Apple Inc. build 5658) (LLVM build 2336.11.00)]
importer numpy; print("NumPy", numpy.__version__)
NumPy 1.13.1
importer scipy; print("SciPy", scipy.__version__)
SciPy 0.19.1
importer sklearn; print("Scikit-Apprendre", sklearn.__version__)
Scikit-Learn 0.18.2

Pourriez-vous également mettre verbose=10 dans cross_val_predict, afin que nous puissions peut-être
voir où ça casse pour vous?

Le 8 août 2017 à 22h59, boazsh [email protected] a écrit :

Désolé, je l'ai raté - pip.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment-320948362 ,
ou couper le fil
https://github.com/notifications/unsubscribe-auth/AAEz67S64KIXUGvARGjvxBOw_4aCAdqhks5sWFu0gaJpZM4BkiD9
.

@jnothman Je suppose que votre environnement conda utilise MKL et non Accelerate. Ce problème de gel est spécifique au multitraitement Accelerate et Python. http://scikit-learn.org/stable/faq.html#why -do-i-sometime-get-a-crash-freeze-with-n-jobs-1-under-osx-or-linux pour plus de détails .

pip, d'autre part, utilisera des roues livrées avec Accelerate (au moment de la rédaction).

Une solution de contournement (autre que JOBLIB_START_METHOD) pour éviter ce bogue particulier est d'utiliser MKL (par exemple via conda) ou OpenBLAS (par exemple via le canal conda-forge).

Rien n'est imprimé...

screen shot 2017-08-08 at 16 43 35

@jnothman Je suppose que votre environnement conda utilise MKL et non Accelerate.

@jnothman au cas où vous voudriez reproduire le problème, IIRC vous pouvez créer un environnement avec Accelerate sur OSX avec quelque chose comme :

conda create -n test-env python=3 nomkl scikit-learn ipython

FWIW Je ne peux pas reproduire le problème sur ma VM OS X. J'ai essayé d'imiter au plus près les versions de @boazsh :

Darwin-16.1.0-x86_64-i386-64bit
('Python', '2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:05:08) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]')
('NumPy', '1.12.1')
('SciPy', '0.19.1')
('Scikit-Learn', '0.18.2')

Hmm en fait je peux reproduire mais votre extrait n'était pas un reproducteur complet. Voici un extrait mis à jour :

import numpy as np
from sklearn.decomposition import PCA
from sklearn.svm import SVC
from sklearn.preprocessing import RobustScaler
from sklearn.metrics import classification_report
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_predict

np.random.seed(1234)
X = np.random.sample((1000, 100))
Y = np.random.sample((1000)) > 0.5
svc_pipeline = Pipeline([('pca', PCA(n_components=95)), ('svc', SVC())])
PCA(n_components=95).fit(X, Y) # this line is required to reproduce the freeze
predictions = cross_val_predict(svc_pipeline, X, Y, cv=30, n_jobs=-1)
print(classification_report(Y, predictions))

Dans tous les cas, il s'agit d'un problème connu avec le multitraitement Accelerate et Python. Des solutions de contournement existent et ont été répertoriées dans les messages précédents. Le plus simple est probablement d'utiliser conda et de s'assurer que vous utilisez MKL et non Accelerate.

À plus long terme (probablement scikit-learn 0.20), ce problème sera universellement résolu par le nouveau backend Loky pour joblib : https://github.com/scikit-learn/scikit-learn/issues/7650

Avoir un correctif pour le multitraitement dépendant de la version scikit-learn est symptomatique des problèmes de vente....

Avoir un correctif pour le multitraitement dépendant de la version scikit-learn est symptomatique des problèmes de vente....

J'ai lu récemment ce qui suit, que j'ai trouvé intéressant :
https://lwn.net/Articles/730630/rss

J'ai un problème similaire avec RandomizedSearchCV; il se bloque indéfiniment. J'utilise un macbook pro de 3 ans, 16 Go de RAM et core i7 et ma version scikit-learn est de 0,19.

La partie déroutante est que cela fonctionnait vendredi dernier !!! Lundi matin, j'y retourne et j'essaie de courir et ça gèle. Je sais d'après les exécutions précédentes qu'il faut environ 60 minutes pour terminer, mais j'ai attendu beaucoup plus longtemps que cela et rien ne se passe, il se bloque, aucun message d'erreur, rien et mon ordinateur chauffe et consomme de l'énergie comme s'il n'y avait pas de lendemain. Code ci-dessous. J'ai essayé de changer n_iter en 2 et n_jobs=1 après avoir lu quelques commentaires ici et cela a fonctionné. Cela peut donc avoir quelque chose à voir avec n_jobs=-1. Pourtant, ce code a bien fonctionné vendredi dernier! il déteste juste les lundis. La taille de mon ensemble de données est inférieure à 20 000 exemples avec une dimensionnalité < 100 ..

from sklearn.metrics import make_scorer
from sklearn.cross_validation import cross_val_score
from sklearn.grid_search import RandomizedSearchCV
import sklearn_crfsuite

crf = sklearn_crfsuite.CRF(
    algorithm='lbfgs', 
    max_iterations=100, 
    all_possible_transitions=True
)
params_space = {
    'c1': scipy.stats.expon(scale=0.5),
    'c2': scipy.stats.expon(scale=0.05),
}

f1_scorer = make_scorer(metrics.flat_f1_score, 
                        average='weighted', labels=labels)
rs = RandomizedSearchCV(crf, params_space, 
                        cv=3, 
                        verbose=1, 
                        n_jobs=-1, 
                        n_iter=50, 
                        scoring=f1_scorer)

rs.fit(X_train, y_train)  # THIS IS WHERE IT FREEZES

qu'est-ce que le crf ? juste pour éliminer la possibilité, pourriez-vous essayer d'utiliser
return_train_score=Faux ?

Il est très probable que ce problème de faq .

Comment as-tu installé scikit-learn ?

Également pour référence future, pouvez-vous coller la sortie de :

import platform; print(platform.platform())
import sys; print("Python", sys.version)
import numpy; print("NumPy", numpy.__version__)
import scipy; print("SciPy", scipy.__version__)
import sklearn; print("Scikit-Learn", sklearn.__version__)

cela fonctionnait vendredi dernier !! Je n'ai rien fait depuis. Je pense que scikit learn fait partie d'anaconda, mais j'ai mis à niveau avec pip (pip install --upgrade sklearn), mais c'était avant d'avoir ce problème. J'ai bien exécuté le code après la mise à niveau vers 0.19.

voici le résultat des impressions ci-dessus :

Darwin-15.6.0-x86_64-i386-64bit
('Python', '2.7.12 |Continuum Analytics, Inc.| (default, Jul  2 2016, 17:43:17) \n[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)]')
('NumPy', '1.13.1')
('SciPy', '0.19.1')
('Scikit-Learn', '0.19.0')

@jnothman : J'utilise RandomizedSearchCV de sklearn.grid_search qui n'a pas le paramètre return_train_score. Je sais que sklearn.grid_search est obsolète. Je vais essayer celui de sklearn.model_selection, mais quelque chose me dit que j'aurai exactement le même problème). Commentaire original mis à jour avec plus d'informations et de code.

Pouvez-vous publier le résultat de conda list | grep numpy . Je suppose qu'en mettant à jour scikit-learn avec pip, vous avez également mis à jour numpy avec pip et vous avez obtenu les roues numpy qui utilisent Accelerate et ont la limitation mentionnée ci-dessus.

Petit conseil :

  • publier un extrait entièrement autonome (pour votre prochain numéro). Cela signifie que n'importe qui peut le copier et le coller dans une session IPython et essayer facilement de le reproduire. Cela vous donnera les meilleures chances d'obtenir une bonne rétroaction.
  • si vous utilisez conda, tenez-vous en à conda pour gérer les packages disponibles via conda. N'utilisez pip que lorsque vous le devez.
  • Si vous insistez pour utiliser pip install --update , je vous recommande fortement d'utiliser pip install --update --no-deps . Sinon, si un paquet dépend, disons de numpy, et que vous n'avez pas le dernier numpy, numpy sera mis à niveau avec pip, ce que vous ne voulez pas.

Oh oui et BTW, sklearn.grid_search est obsolète, vous voudrez probablement utiliser sklearn.model_selection à un moment donné pas trop loin sur la route.

De bons conseils, merci. Alors, la solution de contournement est-elle de rétrograder numpy? de quelle limitation parles-tu ? le lien FAQ ci-dessus? Je l'ai lu, mais je ne comprends pas ce genre de choses (je suis juste un gars algo :) ).

sortie de conda list | grep numpy

numpy 1.12.0
numpy 1.12.0 py27_0
numpy 1.13.1
numpydoc 0.7.0

Wow trois numpy installés j'en ai vu deux avant mais jamais trois ... de toute façon cela semble indicatif du problème que je mentionnais, c'est à dire que vous avez mélangé pip et conda ce qui est une mauvaise idée pour un package donné.

pip uninstall -y # maybe a few times to make sure you have removed pip installed packages
conda install numpy -f

Espérons qu'après cela, vous aurez un seul numpy qui utilise MKL.

Si j'étais vous, je vérifierais que vous n'avez pas le même problème pour les autres packages scientifiques de base, par exemple scipy, etc ...

la raison pour laquelle j'ai recours à pip pour certains packages est que conda n'a pas certains packages, ce qui est en fait très frustrant car je sais que mélanger pip avec conda est une mauvaise idée. La prochaine fois que cela se produira, j'utiliserai l'option --no-deps.

une chose que j'aurais dû mentionner est que j'ai installé Spyder dans l'environnement python dans lequel je travaillais. Cependant, j'ai pu exécuter le code après avoir installé Spyder, à la fois dans Spyder et dans Jupyter.

J'ai désinstallé Spyder et les numpys ci-dessus, réinstallé bumpy avec conda (qui a mis à jour scikit à 0.19) et j'obtiens toujours la même erreur. Quelque chose s'est peut-être produit à cause de l'installation de Spyder, mais alors pourquoi cela fonctionnerait-il pendant une journée puis s'arrêterait-il soudainement ??

ok, rien ne marche !! dois-je simplement créer un nouvel environnement (en utilisant conda) et tout réinstaller là-bas ? est-ce que cela le résoudra ou l'aggravera-t-il ?

Ça vaut le coup d'essayer !

créé un nouvel env et tout installé avec conda, se bloque toujours indéfiniment. une seule copie de chaque paquet, etc.

n_jobs=1 fonctionne, mais prend une éternité bien sûr (cela fonctionnait également dans l'environnement précédent). n_jobs=-1 est ce qui gèle indéfiniment.

conda list | grep numpy
numpy                     1.13.1           py27hd567e90_2


Darwin-15.6.0-x86_64-i386-64bit
('Python', '2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:05:08) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]')
('NumPy', '1.13.1')
('SciPy', '0.19.1')
('Scikit-Learn', '0.19.0')

Alors je ne sais pas. La seule façon dont nous pouvons enquêter est de publier un extrait de code entièrement autonome que nous pouvons simplement copier et coller dans une session IPython et voir si nous pouvons reproduire le problème.

va essayer de créer un exemple minimal qui reproduit le problème. Je dois le faire pour déboguer plus efficacement.

J'ai lu l'entrée de la FAQ à laquelle vous faites référence à propos de "Accélérer".. ce n'est pas très utile pour moi. Ce que j'en ai déduit, c'est que fork() NON suivi d'un appel exec() est mauvais. J'ai fait quelques recherches sur Google à ce sujet et rien jusqu'à présent ne fait même allusion à une solution de contournement. Pouvez-vous indiquer plus d'informations, plus de détails sur le problème? Merci,

Essayez cet extrait (tiré de https://github.com/numpy/numpy/issues/4776) :

import multiprocessing as mp

import numpy as np


def compute(n):
    print('Enter')
    np.dot(np.eye(n), np.eye(n))
    print('Exit')


print('\nWithout multiprocessing:')
compute(1000)

print('\nWith multiprocessing:')
workers = mp.Pool(1)
results = workers.map(compute, (1000, 1000))
  • Si cela se bloque (c'est-à-dire qu'il ne se termine pas en une seconde), cela signifie que vous utilisez Accelerate et que le gel est une limitation connue avec le multitraitement Python. La solution de contournement consiste à ne pas utiliser Accelerate. Sur OSX, vous pouvez le faire avec conda qui utilise MKL par défaut. Vous pouvez également utiliser OpenBLAS en utilisant conda-forge.
  • S'il ne se bloque pas, vous n'utilisez pas Accelerate et nous aurions besoin d'un extrait autonome pour enquêter.

essaiera de reproduire avec un minimum de code.

Without multiprocessing:
Enter
Exit

With multiprocessing:
Enter
Exit
Enter
Exit

@GaelVaroquaux scikit-learn n'est pas une application mais une bibliothèque dans un écosystème riche. Si tout le monde faisait ce que nous faisons, tout s'effondrerait. C'est un signal assez clair que nous devons changer. Et il existe de nombreux environnements où le contraire est vrai à partir de ce commentaire.

J'ai utilisé une instance virtuelle ubuntu dans le moteur de calcul du cloud google (cahoteux, épicé, scikit, etc. n'étaient pas les plus à jour). Le code a bien fonctionné. Ensuite, j'ai installé Gensim. Ceci a mis à jour numpy et scipy vers les dernières versions et a installé quelques autres éléments dont il a besoin (boto, bz2file et smart_open). Après cela, le code se fige. J'espère que cela donne un indice utile sur les causes de ce gel.

après avoir installé Gensim
numpy (1.10.4) mis à jour en numpy (1.13.3)
scipy (0.16.1) mis à jour vers scipy (0.19.1)

Plus d'informations:
En faisant quelques recherches, j'ai découvert que libblas, liblapack et liblapack_atlas manquaient dans mon /usr/lib/, et je n'ai pas non plus vu le répertoire /usr/lib/atlas-base/. Je ne sais pas s'ils étaient là et l'installation de gensim les a supprimés car il a mis à jour numpy, etc., mais c'est probablement parce que le code fonctionnait avant l'installation de gensim. Je les ai installés en utilisant sudo apt-get --yes install libatlas-base-dev et "_update-alternatives_" selon les instructions d'installation avancées de scikit, mais cela n'a pas aidé, le code se bloque toujours avec n_jobs=-1.

Je pense que le problème est que numpy utilise OpenBlas. Le passera à ATLAS et verra ce qui se passe.

>>> import numpy as np
>>> np.__config__.show()
lapack_opt_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
blas_opt_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
openblas_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
openblas_lapack_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
blas_mkl_info:
  NOT AVAILABLE

Toujours le même problème. Ce qui suit fonctionne bien, à moins que j'insère n_jobs=-1.

from sklearn.metrics import fbeta_score

def f2_score(y_true, y_pred):
    y_true, y_pred, = np.array(y_true), np.array(y_pred)
    return fbeta_score(y_true, y_pred, beta=2, average='binary')

clf_rf = RandomForestClassifier()
grid_search = GridSearchCV(clf_rf, param_grid=param_grid, scoring=make_scorer(f2_score), cv=5)
grid_search.fit(X_train, y_train)  

@paulaceccon vos installations Numpy et Scipy utilisent-elles ATLAS ou OpenBLAS ?

C'est un peu dur de suivre ce que tu as fait @KaisJM. Du point de vue d'un responsable, nous avons besoin d'un extrait de code Python entièrement autonome pour voir si nous pouvons le reproduire. Si nous pouvons nous reproduire, alors seulement pourrons-nous enquêter et essayer de comprendre ce qui se passe. Si cela ne se produit que lorsque vous installez gensim et que vous parvenez à reproduire ce comportement de manière cohérente, nous aurions besoin d'instructions complètes sur la façon de créer un environnement Python qui a le problème par rapport à un environnement Python qui n'a pas le problème.

Cela demande un temps et des efforts non négligeables, je suis tout à fait d'accord, mais sans cela, je crains qu'il n'y ait pas grand-chose que nous puissions faire pour enquêter sur le problème auquel vous êtes confronté.

selon les instructions d'installation avancées

@KaisJM soit dit en passant, cette page est obsolète, car de nos jours, les roues sont disponibles sur Linux et contiennent leur propre OpenBLAS. Si vous installez un scikit-learn publié avec pip, vous utiliserez OpenBLAS.

@lesteve êtes-vous en train de dire qu'Openblas ne provoque plus de gel ?

@lesteve paula a publié un extrait qui a également le même problème. Je peux voir que ce n'est pas le code complet, mais j'espère que cela donne une idée. Je peux faire ici un extrait "complet" et le poster pour vous. Cependant, il est clair que la page d'instructions "obsolète" -comme vous l'appelez- peut ne pas être si obsolète. La probabilité la plus élevée est qu'OpenBLAS soit à l'origine des frais dont ils parlent dans cette page.

Ces instructions sont obsolètes croyez-moi. Si vous lisez les détails, il est écrit "mais peut geler joblib/multiprocessing avant OpenBLAS version 0.2.8-4". J'ai vérifié une roue numpy récente et elle contient OpenBLAS 0.2.8.18. Le gel auquel ils font référence est celui de https://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment -334155175, que vous ne semblez pas avoir.

Je peux voir que ce n'est pas le code complet, mais j'espère que cela donne une idée

Non, pas vraiment. Nous avons des rapports d'utilisateurs qui semblent indiquer que le gel peut encore se produire, dont nous n'avons pas réussi à reproduire AFAIK. Cela semble indiquer que ce problème se produit dans une combinaison très spécifique de facteurs. À moins que quelqu'un qui a le problème passe du temps et trouve comment se reproduire de manière contrôlée et que nous parvenions à nous reproduire, il n'y a tout simplement aucun moyen que nous puissions faire quoi que ce soit à ce sujet.

Je peux faire ici un extrait "complet" et le poster pour vous

Ce serait génial. Ce serait formidable si vous pouviez vérifier si un tel extrait provoque toujours le gel dans un environnement conda séparé (ou virtualenv selon ce que vous utilisez).

@lesteve @paulaceccon : J'ai pris l'extrait de code de Paula et j'ai créé un extrait de code complet et

import platform; print(platform.platform())
import sys; print("Python", sys.version)
import numpy as np; print("NumPy", np.__version__)
import scipy; print("SciPy", scipy.__version__)
import sklearn; print("Scikit-Learn", sklearn.__version__)

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification

import scipy.stats
from sklearn.metrics import make_scorer
from sklearn.grid_search import RandomizedSearchCV
#from sklearn.model_selection import RandomizedSearchCV
#from sklearn.model_selection import GridSearchCV
from sklearn.metrics import fbeta_score

X, y = make_classification(n_samples=1000, n_features=4,
                           n_informative=2, n_redundant=0,
                           random_state=0, shuffle=False)

clf_rf = RandomForestClassifier(max_depth=2, random_state=0)

def f2_score(y_true, y_pred):
    y_true, y_pred, = np.array(y_true), np.array(y_pred)
    return fbeta_score(y_true, y_pred, beta=2, average='binary')

param_grid = {'max_depth':[2, 3, 4], 'random_state':[0, 3, 7, 17]}

grid_search = RandomizedSearchCV(clf_rf, param_grid, n_jobs=-1, scoring=make_scorer(f2_score), cv=5)

grid_search.fit(X, y)

@KaisJM Je pense qu'il est plus utile si vous commencez à partir de votre script de congélation et parvenez à simplifier et à publier un script entièrement autonome qui se fige pour vous.

@lesteve D'accord. J'ai créé un nouvel environnement python2 comme celui que j'avais avant d'installer Gensim. Le code a bien fonctionné, PAS de gel avec n_jobs=-1. De plus, Numpy utilise OpenBLAS et a la même configuration que l'environnement qui présente le gel (celui où Gensim a été installé). Il semble donc que openblas ne soit pas la cause de ce gel.

bumpy.__config__.show()
lapack_opt_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
blas_opt_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
openblas_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
openblas_lapack_info:
    libraries = ['openblas']
    library_dirs = ['/usr/local/lib']
    define_macros = [('HAVE_CBLAS', None)]
    language = c
blas_mkl_info:
  NOT AVAILABLE

@KaisJM J'exécute le même extrait ici (Windows) et il se bloque.

from sklearn.datasets import make_classification
X, y = make_classification()

from sklearn.ensemble import RandomForestClassifier
clf_rf_params = {
    'n_estimators': [400, 600, 800],
    'min_samples_leaf' : [5, 10, 15],
    'min_samples_split' : [10, 15, 20],
    'criterion': ['gini', 'entropy'],
    'class_weight': [{0: 0.51891309,  1: 13.71835531}]
}

import numpy as np
def ginic(actual, pred):
    actual = np.asarray(actual) # In case, someone passes Series or list
    n = len(actual)
    a_s = actual[np.argsort(pred)]
    a_c = a_s.cumsum()
    giniSum = a_c.sum() / a_s.sum() - (n + 1) / 2.0
    return giniSum / n

def gini_normalizedc(a, p):
    if p.ndim == 2:  # Required for sklearn wrapper
        p = p[:,1]   # If proba array contains proba for both 0 and 1 classes, just pick class 1
    return ginic(a, p) / ginic(a, a)

from sklearn import metrics
gini_sklearn = metrics.make_scorer(gini_normalizedc, True, True)

from sklearn.model_selection import GridSearchCV

clf_rf = RandomForestClassifier()
grid = GridSearchCV(clf_rf, clf_rf_params, scoring=gini_sklearn, cv=3, verbose=1, n_jobs=-1)
grid.fit(X, y)

print (grid.best_params_)

Je sais que c'est gênant, mais il n'a pas gelé lors de l'exécution avec une métrique _custom_.

J'ai le même problème. J'ai exécuté le même code et je voulais simplement mettre à jour le modèle avec les données du nouveau mois et il a cessé de fonctionner. je crois que sklearn a été mis à jour entre-temps à 0,19

Exécuter GridSearchCV ou RandomizedSearchCV dans une boucle et n_jobs > 1 se bloquerait silencieusement dans Jupiter & IntelliJ :

for trial in tqdm(range(NUM_TRIALS)):
    ...
    gscv = GridSearchCV(estimator=estimator, param_grid=param_grid,
                          scoring=scoring, cv=cv, verbose=1, n_jobs=-1)
    gscv.fit(X_data, y_data)

    ...

Suivi de la recommandation @lesteve et vérification de l'environnement et suppression de numpy installé avec pip :

Darwin-16.6.0-x86_64-i386-64bit
Python 3.6.1 |Anaconda personnalisé (x86_64)| (par défaut, le 11 mai 2017, 13:04:09)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
NumPy 1.13.1
SciPy 0.19.1
Scikit-Learn 0.19.0

liste $conda | grep numpy
gnumpy 0,2 pip
numpy 1.13.1 py36_0
numpy 1.13.3 pip
numpydoc 0.6.0 py36_0

$pip désinstaller numpy

liste $conda | grep numpy
gnumpy 0,2 pip
numpy 1.13.1 py36_0
numpydoc 0.6.0 py36_0

$conda install numpy -f // probablement inutile

liste $conda | grep numpy
gnumpy 0,2 pip
numpy 1.13.1 py36_0
numpydoc 0.6.0 py36_0

Correction de mon problème.

@paulaceccon votre problème est lié à

https://stackoverflow.com/questions/36533134/cant-get-attribute-abc-on-module-main-from-abc-h-py
Si vous déclarez le pool avant de déclarer la fonction que vous essayez d'utiliser en parallèle, cette erreur s'affichera. Inversez l'ordre et il ne lancera plus cette erreur.

Ce qui suit exécutera votre code :

import multiprocessing

if __name__ == '__main__':
    multiprocessing.set_start_method('spawn')

    from external import *

    from sklearn.datasets import make_classification
    X, y = make_classification()

    from sklearn.ensemble import RandomForestClassifier
    clf_rf_params = {
        'n_estimators': [400, 600, 800],
        'min_samples_leaf' : [5, 10, 15],
        'min_samples_split' : [10, 15, 20],
        'criterion': ['gini', 'entropy'],
        'class_weight': [{0: 0.51891309,  1: 13.71835531}]
    }

    from sklearn.model_selection import GridSearchCV

    clf_rf = RandomForestClassifier()
    grid = GridSearchCV(clf_rf, clf_rf_params, scoring=gini_sklearn, cv=3, verbose=1, n_jobs=-1)
    grid.fit(X, y)

    print (grid.best_params_)

avec external.py

import numpy as np
def ginic(actual, pred):
    actual = np.asarray(actual) # In case, someone passes Series or list
    n = len(actual)
    a_s = actual[np.argsort(pred)]
    a_c = a_s.cumsum()
    giniSum = a_c.sum() / a_s.sum() - (n + 1) / 2.0
    return giniSum / n

def gini_normalizedc(a, p):
    if p.ndim == 2:  # Required for sklearn wrapper
        p = p[:,1]   # If proba array contains proba for both 0 and 1 classes, just pick class 1
    return ginic(a, p) / ginic(a, a)

from sklearn import metrics
gini_sklearn = metrics.make_scorer(gini_normalizedc, True, True)

Résultats fonctionnant sur 8 cœurs

Essayage 3 plis pour chacun des 54 candidats, pour un total de 162 ajustements
{'class_weight' : {0 : 0,51891309, 1 : 13,71835531}, 'criterion' : 'gini', 'min_samples_leaf' : 10, 'min_samples_split' : 20, 'n_estimators' : 400}

Le problème est toujours là les gars. J'utilise un marqueur personnalisé et il continue indéfiniment lorsque je définis n_jobs sur quoi que ce soit. Lorsque je ne spécifie pas du tout n_jobs, cela fonctionne bien, mais sinon, cela se bloque.

Pouvez-vous fournir un extrait autonome pour reproduire le problème ? Veuillez lire https://stackoverflow.com/help/mcve pour plus de détails.

Toujours confronté à ce problème avec le même exemple de code.

Windows-10-10.0.15063-SP0
Python 3.6.4 |Anaconda personnalisé (64 bits)| (par défaut, 16 janvier 2018, 10:22:32) [MSC v.1900 64 bits (AMD64)]
NumPy 1.14.1
SciPy 1.0.0
Scikit-Apprendre 0.19.1

Pouvez-vous fournir un extrait autonome pour reproduire le problème ? Veuillez lire https://stackoverflow.com/help/mcve pour plus de détails.

Je soupçonne qu'il s'agit du même vieux problème de multitraitement dans Windows. voir notre FAQ

J'ai testé le code dans https://github.com/scikit-learn/scikit-learn/issues/2889#issuecomment -337985212 de thomberg1.

Système d'exploitation : Windows 10 x64 10.0.16299.309
Paquet Python : WinPython-64bit-3.6.1
numpy (1.14.2)
scikit-learn (0.19.1)
scipy (1.0.0)

Cela a bien fonctionné dans Jupyter Notebook et la ligne de commande.

Salut, j'ai le même problème, donc je ne voulais pas en ouvrir un nouveau qui pourrait conduire à un fil presque identique.

-Macos
-Anaconda
-scikit-learn 0.19.1
-scipy 1.0.1
-numpy 1.14.2

# MLP for Pima Indians Dataset with grid search via sklearn
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
import numpy

# Function to create model, required for KerasClassifier
def create_model(optimizer='rmsprop', init='glorot_uniform'):
  # create model
  model = Sequential()
  model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu'))
  model.add(Dense(8, kernel_initializer=init, activation='relu'))
  model.add(Dense(1, kernel_initializer=init, activation='sigmoid'))
  # Compile model
  model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
  return model

# fix random seed for reproducibility
seed = 7
numpy.random.seed(seed)
# load pima indians dataset
dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
# split into input (X) and output (Y) variables
X = dataset[:,0:8]
Y = dataset[:,8]


# create model
model = KerasClassifier(build_fn=create_model, verbose=0)
# grid search epochs, batch size and optimizer
optimizers = ['rmsprop', 'adam']
init = ['glorot_uniform', 'normal', 'uniform']
epochs = [50, 100, 150]
batches = [5, 10, 20]
param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=init)
grid = GridSearchCV(estimator=model, param_grid=param_grid)
grid_result = grid.fit(X, Y)
# summarize results
print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
  print("%f (%f) with: %r" % (mean, stdev, param))

Le code provient d'un tutoriel : https://machinelearningmastery.com/use-keras-deep-learning-models-scikit-learn-python/
J'ai essayé de changer le paramètre n_jobs en 1, -1, mais aucun de ceux-ci n'a fonctionné. Un indice ?

il s'exécute si j'ajoute l'import multitraitement et l'instruction if comme indiqué ci-dessous - je ne travaille pas avec keras donc je n'ai pas plus de perspicacité

import multiprocessing

if __name__ == '__main__':

    # MLP for Pima Indians Dataset with grid search via sklearn
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.wrappers.scikit_learn import KerasClassifier
    from sklearn.model_selection import GridSearchCV
    import numpy

    # Function to create model, required for KerasClassifier
    def create_model(optimizer='rmsprop', init='glorot_uniform'):
      # create model
      model = Sequential()
      model.add(Dense(12, input_dim=8, kernel_initializer=init, activation='relu'))
      model.add(Dense(8, kernel_initializer=init, activation='relu'))
      model.add(Dense(1, kernel_initializer=init, activation='sigmoid'))
      # Compile model
      model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
      return model

    # fix random seed for reproducibility
    seed = 7
    numpy.random.seed(seed)
    # load pima indians dataset
    dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
    # split into input (X) and output (Y) variables
    X = dataset[:,0:8]
    Y = dataset[:,8]


    # create model
    model = KerasClassifier(build_fn=create_model, verbose=0)
    # grid search epochs, batch size and optimizer
    optimizers = ['rmsprop', 'adam']
    init = ['glorot_uniform', 'normal', 'uniform']
    epochs = [5]
    batches = [5, 10, 20]
    param_grid = dict(optimizer=optimizers, epochs=epochs, batch_size=batches, init=init)
    grid = GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=12, verbose=1)
    grid_result = grid.fit(X, Y)
    # summarize results
    print("Best: %f using %s" % (grid_result.best_score_, grid_result.best_params_))
    means = grid_result.cv_results_['mean_test_score']
    stds = grid_result.cv_results_['std_test_score']
    params = grid_result.cv_results_['params']
    for mean, stdev, param in zip(means, stds, params):
      print("%f (%f) with: %r" % (mean, stdev, param))

Ajustement 3 plis pour chacun des 18 candidats, totalisant 54 ajustements

Meilleur : 0.675781 en utilisant {'batch_size' : 5, 'epochs' : 5, 'init' : 'glorot_uniform', 'optimizer' : 'adam'}
0.621094 (0.036225) avec : {'batch_size' : 5, 'epochs' : 5, 'init' : 'glorot_uniform', 'optimizer' : 'rmsprop'}
0.675781 (0.006379) avec : {'batch_size' : 5, 'epochs' : 5, 'init' : 'glorot_uniform', 'optimizer' : 'adam'}
...
0.651042 (0.025780) avec : {'batch_size' : 20, 'epochs' : 5, 'init' : 'uniform', 'optimizer' : 'adam'}


informations sur la version si besoin
sys 3.6.4 |Anaconda personnalisé (64 bits)| (par défaut, le 16 janvier 2018, 12:04:33)
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
numpy 1.14.2
pandas 0,22,0
sklearn 0.19.1
torche 0.4.0a0+9692519
IPython 6.2.1
Keras 2.1.5

compilateur : GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)
système : Darwin
version : 17.5.0
machine : x86_64
processeur : i386
Cœurs CPU : 24
interprète : 64 bits

Merci @thomberg1 , mais en ajoutant

import multiprocessing
if __name__ == '__main__':

n'a pas aidé. Le problème est toujours le même

Même problème sur ma machine lors de l'utilisation de la fonction de notation personnalisée dans GridsearchCV .
python 3.6.4,
scikit-learn 0.19.1,
fenêtres 10.,
Cœurs de processeur : 24

@byrony pouvez-vous fournir le code à reproduire ? as-tu utilisé if __name__ == "__main__" ?

J'ai rencontré un problème similaire à plusieurs reprises sur ma machine en utilisant n_jobs=-1 ou n_jobs=8 comme argument pour GridsearchCV mais en utilisant l'argument de scoreur par défaut.

  • Python 3.6.5,
  • scikit-learn 0.19.1,
  • Arch Linux,
  • Cœurs de processeur : 8.

Voici le code que j'ai utilisé :

from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import MinMaxScaler
from sklearn.decomposition import PCA
from sklearn.utils import shuffle
from sklearn.neural_network import MLPClassifier
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np


def main():

    df = pd.read_csv('../csvs/my_data.csv', nrows=4000000)    

    X = np.array(list(map(lambda a: np.fromstring(a[1:-1] , sep=','), df['X'])))
    y = np.array(list(map(lambda a: np.fromstring(a[1:-1] , sep=','), df['y'])))

    scalerX = MinMaxScaler()
    scalerY = MinMaxScaler()
    X = scalerX.fit_transform(X)
    y = scalerY.fit_transform(y)

    grid_params = {
        'beta_1': [ .1, .2, .3, .4, .5, .6, .7, .8, .9 ],
        'activation': ['identity', 'logistic', 'tanh', 'relu'],
        'learning_rate_init': [0.01, 0.001, 0.0001]
    }

    estimator = MLPClassifier(random_state=1, 
                              max_iter=1000, 
                              verbose=10,
                              early_stopping=True)

    gs = GridSearchCV(estimator, 
                      grid_params, 
                      cv=5,
                      verbose=10, 
                      return_train_score=True,
                      n_jobs=8)

    X, y = shuffle(X, y, random_state=0)

    y = y.astype(np.int16)    

    gs.fit(X, y.ravel())

    print("GridSearchCV Report \n\n")
    print("best_estimator_ {}".format(gs.best_estimator_))
    print("best_score_ {}".format(gs.best_score_))
    print("best_params_ {}".format(gs.best_params_))
    print("best_index_ {}".format(gs.best_index_))
    print("scorer_ {}".format(gs.scorer_))
    print("n_splits_ {}".format(gs.n_splits_))

    print("Exporting")
    results = pd.DataFrame(data=gs.cv_results_)
    results.to_csv('../csvs/gs_results.csv')


if __name__ == '__main__':
    main()

Je sais que c'est un gros ensemble de données, donc je m'attendais à ce qu'il faille un certain temps pour obtenir des résultats, mais après 2 jours d'exécution, il a simplement cessé de fonctionner (le script continue de s'exécuter mais n'utilise aucune ressource en dehors de la RAM et du swap).

captura de pantalla de 2018-05-25 17-53-11

captura de pantalla de 2018-05-25 17-54-59

Merci d'avance!

@amueller Je n'ai pas utilisé le if __name__ == "__main__" . Ci-dessous mon code, il ne fonctionne que lorsque n_jobs=1

def neg_mape(true, pred):
    true, pred = np.array(true)+0.01, np.array(pred)
    return -1*np.mean(np.absolute((true - pred)/true))

xgb_test1 = XGBRegressor(
    #learning_rate =0.1,
    n_estimators=150,
    max_depth=3,
    min_child_weight=1,
    gamma=0,
    subsample=0.8,
    colsample_bytree=0.8,
    objective= 'reg:linear',
    nthread=4,
    scale_pos_weight=1,
    seed=123,
)

param_test1 = {
    'learning_rate':[0.01, 0.05, 0.1, 0.2, 0.3],
}

gsearch1 = GridSearchCV(estimator = xgb_test1, param_grid = param_test1, scoring=neg_mape, n_jobs=4, cv = 5)

Vous utilisez XGBoost. Je ne sais pas ce qu'ils font en interne, il est très possible que ce soit le problème. Pouvez-vous essayer de voir si l'ajout de if __name__ aide ?
Sinon, je pense qu'il n'y a pas encore de solution.

@Pazitos10 pouvez-vous reproduire avec des données synthétiques et/ou des données plus petites ? Je ne peux pas reproduire sans vos données et ce serait bien de reproduire en moins de temps.

@amueller Ok, je le relancerai avec 500 000 lignes et publierai les résultats. Merci!

@amueller , l'exécution du script avec 50 000 lignes fonctionne comme prévu. Le script se termine correctement, affichant les résultats comme suit (désolé, je voulais dire 50k pas 500k):

captura de pantalla de 2018-05-26 13-09-00

captura de pantalla de 2018-05-26 13-09-51

Le problème est que je ne sais pas si ces résultats seront les meilleurs pour l'ensemble de mon ensemble de données. Aucun conseil?

On dirait que vous manquez de ram. Essayez peut-être d'utiliser Keras à la place, c'est probablement une meilleure solution pour les réseaux de neurones à grande échelle.

@amueller Oh, d'accord. Je vais essayer d'utiliser Keras à la place. Merci encore!

Cela n'a rien à voir avec les marqueurs personnalisés. C'est une fonctionnalité bien connue du multitraitement Python sous Windows : vous devez exécuter tout ce qui utilise n_jobs=-1 dans un bloc if __name__ == '__main__' ou vous obtiendrez des blocages/plantages. Peut-être devrions-nous documenter cela quelque part en évidence, par exemple dans le README ?

Est-ce peut-être une idée pour scikit, que dans le cas de Windows pour modifier la fonction
Et utilisez des files d'attente pour alimenter des tâches vers une collection de processus de travail et collecter les résultats
Comme décrit ici : https://docs.python.org/2/library/multiprocessing.html#windows
et pour la 3.6 ici : https://docs.python.org/3.6/library/multiprocessing.html#windows

@PGTBoos ceci est corrigé dans scikit-learn 0.20.0

Cette page vous a été utile?
0 / 5 - 0 notes