Scikit-learn: GridSearchCVは、マルチスレッドが有効になっていると無期限にフリーズします(つまり、n_jobs!= 1)

作成日 2015年08月12日  ·  88コメント  ·  ソース: scikit-learn/scikit-learn

私は、Python 2.7、3.3、3.4、2つのジョブ、いくつかの異なるmac osxプラットフォーム/ラップトップ、およびnumpyとscikit-の多くの異なるバージョンで、GridSearchCVでこの問題(件名)に断続的に遭遇しています。学ぶ(私はそれらをかなりよく更新し続けます)。

私はこれらの提案をすべて試しましたが、常に機能するとは

https://github.com/scikit-learn/scikit-learn/issues/3605-マルチプロセッシング開始メソッドを「forkserver」に設定
https://github.com/scikit-learn/scikit-learn/issues/2889-カスタムスコアリング関数が渡された場合にのみ問題が発生します(同じGridSearchCVがn_jobsで呼び出す場合にのみ問題が発生します!= 1がフリーズしますカスタムスコアラーですが、スコアラーがなくても問題ありません)
https://github.com/joblib/joblib/issues/138-MKLスレッドカウントからの環境変数の設定(Anacondaディストリビューションのmklに対してビルドされたnumpy / sklearnを実行するときにこれを試しました)
入力をスケーリングし、n_jobs = 1でエラーがないことを確認します-複数のスレッドで実行しようとしていることは、1つのスレッドで短時間で正しく実行されると完全に確信しています

これは非常に苛立たしい問題であり、それがなくなったと確信したときに常に元に戻るように見えます。100%の時間で機能する唯一の回避策は、使用しているsklearnディストリビューションのGridSearchCVのソースにアクセスすることです。 Paralellの呼び出しで設定されたバックエンドを(マルチプロセッシングではなく)「スレッド化」に手動で変更します。

そのハックとn_jobs = 1の設定の違いをベンチマークしていませんが、並列化をまったく行わずにスレッドバックエンドで利益が得られると期待する理由はありますか? 確かに、マルチプロセッシングほど良くはありませんが、少なくともより安定しています。

ところで、私が同じ問題を抱えていた最新のバージョンは次のとおりです。

  • 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
  • パンダ== 0.16.2
  • joblib == 0.8.4
Bug

最も参考になるコメント

@ eric-czech Python 3.4または3.5を使用している場合は、次の環境変数を設定してから、Pythonプログラムを再起動してください。

export JOBLIB_START_METHOD="forkserver"

joblibのドキュメントで説明されているように。 forkserver isモードは、インタラクティブに定義された機能を中断するため、デフォルトでは有効になっていません。

全てのコメント88件

そのプラットフォームで一貫して問題がありますか?

マルチスレッドに関して:マルチスレッドが実質的な利益をもたらす可能性が高いいくつかの推定量があります。ほとんどの作業は、GILを使用せずにnumpyまたはCython操作で実行されます。 本当に、これはあまり評価されていないと思います。 backend='threading'はごく最近のものです。

本当の問題は、問題が何であるかを特定するために、これ以上何ができるかということです。

まず、どの基本推定量を検討しましたか?

@jnothmanプラットフォーム

以前に省略した可能性のある主要な詳細の1つは、問題が発生したときに常にIPythonノートブックを使用していることです。 現在、ノートブックのカーネルがロードされています。n_jobs!= 1で「スコアリング」引数を追加すると、GridSearchCVは永久にハングしますが、その引数を削除すると、すべて問題ありません。 私が与えたスコアリング関数は一定のfloat値を返すだけですが、それでもフリーズします(ただし、n_jobs = 1で期待するとおりに実行します)。

Re:聞いて良かったスレッドなので、GridSearchCVのそのオプションが実際に意味をなすかもしれません。

私が問題を抱えている推定量に関する限り、それを大幅に絞り込むことができるかどうかはわかりません。 私は通常、ここであなたに役立つ情報を得るために、管理できる限り多くのそれらを試しますが、上記の条件を任意の推定量で再現できることを確認したところ、すべての場合にできることがわかりました(または少なくとも試しました) LogisticRegression、SGDClassifier、GBRT、およびRF)。

このようなマルチスレッドの問題に一般的に最も役立つコンテキストについてはよくわかりませんが、何かを提供するためにできることは何でもしたいと思っています。 私に何か提案はありますか?

Accelerateフレームワークに対してリンクされたnumpyを使用していますか?

いいえ、何かが足りない場合を除きます。 インストールされたnumpyバージョンは、それを行うと、少なくとも、acceleratedパッケージが存在するようになると変更されると思いました。

(research3.4)eczech $ pipフリーズ| grep numpy
numpy == 1.9.2
(research3.4)eczech $ condaアップデートが加速
エラー:パッケージ「accelerate」が/Users/eczech/anaconda/envs/research3.4にインストールされていません

100%の自信を持って答えることができないという私の無知を許してください、しかし私は確かにそれをインストールするために意図的に何もしませんでした。

コンダアクセラレーションはアップルアクセラレーションと同じではありません。
http://docs.continuum.io/accelerate/index
https://developer.apple.com/library/mac/documentation/Accelerate/Reference/AccelerateFWRef/

condaaccelerateはパッケージのMKLアクセラレーションバージョンであり、appleaccelrateはMKLの代替バージョンです。

numpy.__config__.show()を教えていただけますか?

マルチプロセッシングは、アクセラレーションIIRCでは機能しません。 ping @ogrisel

もちろん:

np。 config .show()
atlas_3_10_blas_threads_info:
利用不可
atlas_info:
利用不可
atlas_3_10_info:
利用不可
atlas_threads_info:
利用不可
atlas_3_10_blas_info:
利用不可
blas_opt_info:
extra_compile_args = ['-msse3'、 '-DAPPLE_ACCELERATE_SGEMV_PATCH'、 '-I / System / Library / Frameworks / vecLib.framework / Headers']
extra_link_args = ['-Wl、-framework'、 '-Wl、Accelerate']
define_macros = [( 'NO_ATLAS_INFO'、3)]
lapack_mkl_info:
利用不可
atlas_blas_info:
利用不可
mkl_info:
利用不可
lapack_opt_info:
extra_compile_args = ['-msse3'、 '-DAPPLE_ACCELERATE_SGEMV_PATCH']
extra_link_args = ['-Wl、-framework'、 '-Wl、Accelerate']
define_macros = [( 'NO_ATLAS_INFO'、3)]
blas_mkl_info:
利用不可
atlas_3_10_threads_info:
利用不可
openblas_info:
利用不可
openblas_lapack_info:
利用不可
atlas_blas_threads_info:
利用不可

ええ、それは私が課題追跡システムで見つけることができない既知の問題です。 Accelerateはマルチプロセッシングでは機能しません。

私は少し混乱しています。 スレッドバックエンドは、GILがリリースされたときにのみ何かを実行しますよね?

ガッチャ、それならどうやってnumpyを再構築するべきか知っていますか? condaパッケージを使用する代わりに、pipインストールする必要がありますか? それとも、ソースからビルドして、それらのアップルアクセラレーションの議論が存在しないことを確認したほうがいいでしょうか?

このように聞こえますが、それにもかかわらず、問題の初心者ではありません。 死んだ馬を倒しているだけなら、すぐに閉じてください。

あなたがコンダを加速させることができれば、それはうまくいくでしょう;)

たぶん私たちはjoblib保釈を試みることができますか?

ああ、すごい、連続体はそのハハをするためにリンゴにお金を払ったに違いない。

$ 0の提案はありますか? そして、どちらの方法でも洞察に感謝します。

ああ、これは以前に尋ねられたことがあることも知っていますが、カスタムスコアリング関数を使用しているときに現在のプラットフォームでのみこの問題が発生しているという事実はありますか? 私の人生では、grid_search.py​​のソースコードを考えると、それについて何が問題になる可能性があるのか​​わかりませんが、カスタム関数のピクルスと関係があるのでしょうか?

それとは少し関係がありませんが、過去にIPython並列バックエンドを使用するGridSearchCVの修正バージョンを作成してこれを回避しようとしたことを思い出しました。そのソリューションを再検討したとすると、何らかの方法で共有する価値がありますか? そのソリューションは問題なく機能しましたが、カスタムクラスと関数はノートブック自体ではなくpythonpathで利用できる必要があるため、使用するのが少し面倒でしたが、他に良いオプションがない場合は、いくつかの足があります。

アトラスに対してリンクすることはできますが、それは[アップル]の加速が遅くなります。
たぶん、OS X用の無料のMKLリンクnumpyがありますか? Windows用のものがあります。

[あなたが学者なら、連続加速は無料です]

これは、カスタムスコアリング関数の使用とはまったく関係がないと確信しています。
カスタムスコアリング関数で機能するが、機能なしでは機能しない自己完結型のスニプレットを提供できますか?

おそらく、カスタムスコアリング関数の事実が関連しています(たとえば、酸洗いの問題やネストされた並列処理が適切な場合があります)。 コードを見ることができますか?

それとも、 make_scorer標準メトリックを意味するだけですか?

確かに、ここに関連する部分があり、make_scorerでは問題ないように見えますが、カスタム関数では問題ありません。

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()

使用しているデータのいくつかのバージョンを含む自己完結型のバージョンで作業します(ただし、時間がかかります)。 それまでの間、これらのカスタム関数のピクルスは良いリードのように聞こえます-確かに何度か試しましたが、カスタム関数では100%の確率でハングし、make_scorerを使用すると0%の確率でハングします。いくつかの既知のインポートされたメトリック関数。

そして、それはメイン(つまり、解釈されているトップレベルのスクリプト)または
インポートされたモジュール?

23時37分に2015年8月15日、エリック・チェコ[email protected]書きました:

確かに、ここに関連する部分があり、物事は大丈夫のようです
make_scorerを使用しますが、カスタム関数は使用しません。

from sklearn.linear_model import LogisticRegressionfrom sklearn.grid_search import GridSearchCVfrom sklearn.cross_validation import StratifiedKFoldfrom sklearn.metrics importaverage_precision_score、make_scorerimport functools

res = []
clfs = []
応答の応答の場合:
X、y = d_in [機能]、d_in [応答]
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')
グリッド= {
'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()

のいくつかのバージョンを含む自己完結型のバージョンで作業します
私も使用しているデータです(ただし、時間がかかります)。 それまでの間、
それらのカスタム関数の酸洗いは良いリードのように聞こえます-私はそれを試しました
確認のためにもう一度数回、カスタムで100%ハングします
関数と、既知のmake_scorerを使用する場合の0%の時間
インポートされたメトリック関数。


このメールに直接返信するか、GitHubで表示してください
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298

ああ、それはipynbです。 うーん、面白い。 はい、酸洗いが問題になる可能性があります。

2015年8月15日23:51、ジョエルノスマンジョエル。 [email protected]は書いた:

そしてそれはメイン(つまり、解釈されているトップレベルのスクリプト)または
インポートされたモジュール?

23時37分に2015年8月15日、エリック・チェコ[email protected]書きました:

確かに、ここに関連する部分があり、物事は大丈夫のようです
make_scorerを使用しますが、カスタム関数は使用しません。

from sklearn.linear_model import LogisticRegressionfrom sklearn.grid_search import GridSearchCVfrom sklearn.cross_validation import StratifiedKFoldfrom sklearn.metrics importaverage_precision_score、make_scorerimport functools

res = []
clfs = []
応答の応答の場合:
X、y = d_in [機能]、d_in [応答]
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')
グリッド= {
'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()

のいくつかのバージョンを含む自己完結型のバージョンで作業します
私も使用しているデータです(ただし、時間がかかります)。 それまでの間、
それらのカスタム関数の酸洗いは良いリードのように聞こえます-私はそれを試しました
確認のためにもう一度数回、カスタムで100%ハングします
関数と、既知のmake_scorerを使用する場合の0%の時間
インポートされたメトリック関数。


このメールに直接返信するか、GitHubで表示してください
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298

それはノートブックにあります

代わりにモジュールからインポートしてみて、どうなるか見てみましょう

うーん、あなたは何を知っていますか、ノートブックの外で定義されたときにうまく機能します。

私は基本的にPython2.7で実行されているのと同じコード(古いライブラリが必要でした)とPython 3.4のこのコードを持っていますが、カスタム関数であるかmake_scorerを使用するものであるかに関係なく、2.7でハングする問題があります。これで新しいバージョンのすべての問題が解決されるので、古いバージョンの回避策をそのまま使用できます。

ノートブックで定義されたピクルス関数が問題になる理由を追跡するために他にできることはありますか?

さて、私たちは理解したいと思います:

  • ピクルスとピクルス解除は、そのプラットフォームでローカルに定義された関数の一般的な問題ですか、それとも特定の問題にぶつかっていますか?
  • なぜ、酸洗いが問題になるのなら、例外を起こすのではなく、ぶら下がっているのですか? モンキーパッチなどを試して、 pickle.dumps(function)チェックhttps://github.com/scikit-learn/scikit-learn/blob/master/sklearn/externals/joblib/parallelを置き換えるかどうかを確認してpickle.loads(pickle.dumps(function))を含むpy#L150はエラーになりますか? (説明すると、これはマルチプロセッシングを実行する前にピクルス性を確認するための安全チェックです。)

@ogriselはこれに興味があるかもしれません。

私がWindowsで見たものから、ノートブックはマルチプロセッシングと奇妙な相互作用を持っています。

同じノートブックで定義されている関数をピクルスおよびピクルス解除してみましたか?

今日、私は誤ってこのhttps://pythonhosted.org/joblib/parallel.html#bad -interaction-of-multiprocessing-and-third-party-librariesを見ましたが、関連していませんか?
たぶん、Python 3.4以降にアップグレードする必要がありますか?

すみません、長い休暇に行きました。 しかしあなたの質問に答えるために:

  1. re @jnothmanpickle.loads(pickle.dumps(function))をparallel.pyに配置し、その後にprintステートメントを配置して、正常に実行されていることを確認しましたが、問題はありませんでした。 明確にするために、ノートブックから呼び出されたGridSearchCV.fitは、変更なしで以前と同じようにスタックしました(n_jobs = -1で16回表示されるように追加したprintステートメントを除く)。
  2. re @amueller :私があなたを正しく理解しているなら、私は問題なくノートブックでこのようなものを実行しました:
def test_function(x):
    return x**2
pickle.loads(pickle.dumps(test_function))(3)
# 9
  1. re @olologin :私は3.4.3を使用しています。 より具体的には: '3.4.3 | Continuum Analytics、Inc。| (デフォルト、2015年3月6日、12:07:41)n [GCC 4.2.1(Apple Inc.ビルド5577)] '

上記の会話を読んでいませんが、この最小限のテストは、Python 2.6ビルドのtravisでは失敗しますが、PCの同様の構成では合格しました...( n_jobs = -1場合

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、問題が解決する場合は詳細をお知らせください

@ eric-czech Python 3.4または3.5を使用している場合は、次の環境変数を設定してから、Pythonプログラムを再起動してください。

export JOBLIB_START_METHOD="forkserver"

joblibのドキュメントで説明されているように。 forkserver isモードは、インタラクティブに定義された機能を中断するため、デフォルトでは有効になっていません。

最新のソフトウェアがインストールされているOSX10.11.4とUbuntu14.04の両方で同じ問題が発生します。

# 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)

実際、このコードはn_jobs=1場合にのみフリーズしません。

これは、Python 3ではデフォルトで機能し、Python 2ではwontfixになるはずです、右

警告やエラーをスローせずにPython2でサイレントにハングする場合(「n_jobs> 1はPython2ではサポートされていません」)、それは受け入れられません。 エラーをスローできますか?

Python 3の@amuellerではhttps: //github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -187683383に従って問題を回避できます

元のOPはjoblibstart_methodをforkserverに設定すると常に機能するとは限らないと言っていたため、閉じる必要があるかどうかはわかりません...

ところで、xgboostは既知のものです。https: //github.com/scikit-learn/scikit-learn/issues/6627#issuecomment-206351138を参照して

編集:以下の変更は実際には問題を修正しない可能性があります。 Pathosを使用したマルチプロセッシングの処理方法にも無関係な変更が加えられましたが、これが私の本当の修正であった可能性があります。

クイックフィックス:
np.random.seed(0)

説明:
私もこの問題に遭遇していましたが、 最も深刻でした。 最初に(2?)GridSearchCVを実行したときは問題ありませんでしたが、その後の実行はエラーなしでハングしました。

各テスト内にnp.random.seed(0)設定するだけで、再現性を確保しながら、ランダム性を損なうことなく、時間の経過とともにテストを並べ替えることができます。 それを行うとすぐに、GSCVエラーでハングしたすべてのテストが再び機能し始めました。

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

これがデバッグに役立つことを願っています!

開発環境:
Mac OS X(シエラ)
Python 2.7
ライブラリの最新バージョン。

@ClimbsRocksよく、それはおそらくあなたの推定量のいくつかのエラーです。 再現可能な例がある場合はお知らせください;)

@amueller :いいね。 急いで枝を切って再現しましたが、今回はすべて正常に動作しました。

プログラムの他の部分でもPathosの並列化を使用している場合、GSCVの並列化を使用した場合はおそらく問題だったと思います。 これは、私がこの1週間ほどで変更した他の唯一の関連事項です。

それ以来、マルチプロセッシングプールをより完全に閉じたり開いたりするようにリファクタリングしました。

見積もり担当者の1人のバグだけではなかったのは、テストスイートを構築するときに、各テストが個別に実行されて合格したことです。 同じパスで複数のテストを実行したときにのみ、すべてがGSCVに依存してハングし始めました。

この不確実性に注意するために以前のコメントを編集しました。

joblibを他の並列化と組み合わせると、クラッシュする可能性が非常に高いため、試してはいけません。

このスレッドをアップして申し訳ありませんが、私もこの問題に遭遇します。
Python 3.5カーネルを作成し、forkserverにjob lib startメソッドを定義しましたが、まだ問題があります。

実際、n_jobs = 1では機能しません。最後のパラメーターを除いて計算されるようです。

ニュースはありますか?

実際、n_jobs = 1では機能しません。最後のパラメーターを除いて計算されるようです。

これは奇妙で、この問題とは関係がない可能性が非常に高いです(これは約n_jobs != 1 )。 良いフィードバックを得る最良の方法は、問題を再現するスタンドアロンのスニペットで別の問題を開くことです。

私は自分でこの問題に遭遇していると確信しています。 多くの組み合わせを試した後、n_jobs> 1で行うことはすべて、数回折りたたむとフリーズします。 私はsklearn = 0.19.0のUbuntuLinuxラップトップを使用しているので、これは私が読んだ他の構成とは異なる構成です。 「問題のある」コードは次のとおりです。

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')

興味深い点の1つは、xgboostをインポートすると、model_selectionからインポートしていないかのようにGridSearchCVで非推奨の警告が表示されることです。 ただし、私はxgboost 0.62を使用しており、リポジトリを見ると、正しいGridSearchCVをインポートしているように見えます。 明確にするために、非推奨の警告は私に関係する問題ではなく、目前の問題です。n_jobs> 1で実行がフリーズします。 それが役立つ場合に備えて指摘するだけです。

問題の再現に役立つデータを提供できますか?

20:29で2017年8月24日、ザビエルAmatriain [email protected]
書きました:

私は自分でこの問題に遭遇していると確信しています。 多くを試した後
組み合わせ、n_jobs> 1で行うすべてのことは、数回後にフリーズするだけです。
ひだ。 私はsklearn = 0.19.0のUbuntuLinuxラップトップを使用しているので、これは
私が読んだ他のものとは異なる構成。 これが
「問題のある」コード:

`xgboostをxgbとしてインポートします
sklearn.model_selectionからインポートGridSearchCV
cv_params = {'max_depth':[3,5,7]、 'min_child_weight':[1,3,5]}

ind_params = {'learning_rate':0.1、 'n_estimators':1000、 'シード':0、
'subsample':0.8、 'colsample_bytree':0.8、 'objective': ' binary:logistic '}
最適化された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') `

興味深いことの1つは、xgboostをインポートすると、
GridSearchCVからのインポートではないかのような非推奨の警告
model_selection。 しかし、私はxgboost 0.62を使用していて、
リポジトリは、正しいGridSearchCVをインポートしているように見えます。 することが
明らかに、非推奨の警告は私に関係する問題ではなく、むしろ
手元にあるもの:n_jobs> 1で実行がフリーズします。 ただ指摘する
それが役立つ場合があります。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-324597686
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAEz66DbfTlnU_-dcxLKa5zkrcZ-0qVOks5sbVCmgaJpZM4FqYlN

確かに、私が使用している正確なファイルは次の場所からダウンロードできます。
https://xamat.github.io/xgboost_train.csv
https://xamat.github.io/label_train.csv

HTTP404

申し訳ありませんが、最初のリンクに誤りがありました。修正する必要があります。 2番目も大丈夫なはずです、私はちょうどチェックしました。

xgboostの既知の問題。たとえば、 https: //github.com/scikit-learn/scikit-learn/issues/6627#issuecomment-206351138を参照して

参考までに、

これはまだバグですか? デフォルト(n_jobs = 1)とpre_dispatch = 1で同じ問題が発生し、 RandomForestClassifierを使用し、パラメーターとShuffleSplit CVの組み合わせが80あります(n = 20)。

また、最新リリースと開発バージョンの両方で、パイプライン( SelectKBest(score_func=mutual_info_classif, k=10)後にRandomForestClassifier続く)がハングします。

回避策、または確実に機能する他のモデル選択方法を見つけた場合はお知らせください。 scikit-optimizeを試してみることを考えています。

n_jobs = 1のことですか、それともタイプミスですか? この問題はn_jobs!= 1に関するものです。

質の高いフィードバックを得る最良の方法は、問題を再現する方法を提供することです。 この場合、発生している問題が実際にn_jobs = 1にある場合は、別の問題を開いてください。

「マルチスレッド対応」という意味を書きました
n_jobs!= 1 'のように' 1に等しくない '。 同様に、n_jobs> 1です。たとえば、n_jobs = 4

n_jobs = 4のフリーズを再現できないと言っていますか?

もしそうなら、私は一ヶ月以内にテストケースを提供します(私は新しいマシンに変更します)。

2017年9月12日には、7:10 AMで、ロイック・エステベ< [email protected] [email protected] >書きました:

n_jobs = 1のことですか、それともタイプミスですか? この問題はn_jobs!= 1に関するものです。

質の高いフィードバックを得る最良の方法は、問題を再現する方法を提供することです。 この場合、発生している問題が実際にn_jobs = 1にある場合は、別の問題を開いてください。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328864498で表示するか、スレッドをミュートしてくださいhttps://github.com/notifications/unsubscribe- auth / ABH-rd7wgU5lcS6oD5VMl0YOB8CXfSTJks5shpDZgaJpZM4FqYlN

@smcinerneyあなたは@raamanaですか? @lesteven_jobs=1を書いた@raamanaに返信したと思いますが、これはこの問題とは関係がないようです。

申し訳ありませんが、私は@raamanaではありません。 はい@raamanaの問題は異なります(ただし、おそらく同じコードが原因です)

2017年9月12日には、午前9時23分AMで、アンドレアス・ミューラー< [email protected] [email protected] >書きました:

@smcinerney https://github.com/smcinerneyあなたは@raamanahttps ://github.com/raamanaですか? @lestevehttps ://github.com/lesteveがn_jobs = 1を書いた@raamanahttps //github.com/raamanaに返信したと思いますが、これはこの問題とは関係がないようです。


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信するか、GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328905819で表示するか、スレッドをミュートしてくださいhttps://github.com/notifications/unsubscribe- auth / ABH-rYKQA3L5ifINBX6enrk5oDIsf1Lqks5shrASgaJpZM4FqYlN

私の悪い、私はものを混ぜるつもりはなかった。 別の問題を開きます(それを再現するための最小限のコードで)が、デフォルトのn_jobs = 1でもGridSearchCVがハングしないことは、n_jobs> 1よりも大きな懸念事項です(デフォルトで動作するはずです)。

@raamanaはい、それはより大きな懸念事項ですが、関連する問題が原因である可能性も低いです。

@ eric-czech @jnothman
したがって、backend = 'threading'を使用することにした場合。 sklearnコードを変更しない簡単な方法の1つは、parallel_backendコンテキストマネージャーを使用し、GSVのfitメソッドを変更しないことです。

from sklearn.externals.joblib import parallel_backend

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

PS:「スレッド化」がすべての推定量で機能するかどうかはわかりません。 しかし、GSV njob> 1のエスティメータでも同じ問題が発生し、ライブラリを変更せずにこれを使用すると期待どおりに機能します。

システムが試してみました:
MAC OS:10.12.6
Python:3.6
numpy == 1.13.3
pandas == 0.21.0
scikit-learn == 0.19.1

うーん...でスレッドバックエンドを使用すると、並行性の問題が発生する可能性があります
グリッド検索、たとえば#10329のバグは競合状態を引き起こします...

3時59分に2017年12月22日、Trideepラース[email protected]書きました:

@ eric-czech https://github.com/eric-czech @jnothman
https://github.com/jnothman
したがって、backend = 'threading'を使用することにした場合。 なしの1つの簡単な方法
sklearnコードを変更するには、parallel_backendコンテキストマネージャーを使用します
GSVの適合方法は変更されません。

sklearn.externals.joblibからimportparallel_backend

clf = GridSearchCV()
parallel_backend( 'threading')を使用:
clf.fit(x_train、y_train)

PS:「スレッド化」がすべての推定量で機能するかどうかはわかりません。 しかし、私は
GSV njob> 1の推定器で同じ問題が発生し、これを使用する
ライブラリを変更せずに期待どおりに動作します。

システムが試してみました:
MAC OS:10.12.6
Python:3.6
numpy == 1.13.3
pandas == 0.21.0
scikit-learn == 0.19.1


あなたが言及されたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-353402474
またはスレッドをミュートします
https://github.com/notifications/unsubscribe-auth/AAEz64SfwYpjLU1JK0vukBRXJvWYs3LKks5tCo51gaJpZM4FqYlN

ケース:バックエンドを「スレッド化」として使用し、BaseEstimatorとClassifierMixinを拡張するEstimatorを使用します。 競合状態がどこで発生したのかわかりません。 詳しく教えていただけますか。

私の理解と実験によると、競合状態は観察されませんでした。

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はclone(base_estimator)で呼び出されます。 これはdeep_copyを実行し、それ自体のデータのコピーを持ちます。

outは、_fit_and_scoreメソッドの出力です。 したがって、この後、すべてのスレッドがEstimatorのfitメソッドの実行を完了し、結果を報告します。

結果は、GCV_clf.cv_results_から得られるものです。

この特定のケースで、なぜ競合状態が発生するのか説明していただけますか?

ネストされたパラメータを設定している場合、つまり競合状態が発生するのは
変更された1つのパラメーターは推定量であり、別のパラメーターはそのパラメーターです
推定量。

最近のバージョンのWin7でmake_scorerGridSearchCvおよびn_jobs=-1と組み合わせて使用​​すると、同じ問題が発生します。

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バージョンとプラットフォームを投稿してございます。 質の高いフィードバックを得る最良のチャンスは、問題を再現するためのスタンドアロンスニペットを提供することです。 詳細については、 https://stackoverflow.com/help/mcveをお読み

カスタム前処理ステップでWin7で同じ問題が発生します。
ツールチェーン:

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))

Pythonマルチプロセッシングがif __name__ == '__main__'ないWindowsでは機能しないことをご存知ですか?

はい、そうです。 申し訳ありませんが、Jupyterを使用していることを伝えるのを忘れました。
if __name__ == '__main__'を使用するスタンドアロンスクリプトは、次のトレースを出力した後もフリーズします。

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 >

ああ、面白い。 単純な怠惰から、スクリプト全体をif __name__ == '__main__'下に置き、前のコメントから結果を得ました。

pipeline = make_pipeline...だけを配置すると、正常に実行されました。 たぶんそれがJupyterの原因ですか?

とにかく、前のコメントの動作が有効で、 if __name__ == '__main__'の不適切な使用が原因であるのか、それともSkLearnのせいなのかはわかりません。

ライブラリの問題ではなく、実行についての問題のようです。
Windowsでのマルチプロセッシングのコンテキスト...

それは厄介です。 そして確かに、私はすべての同じバージョンでUbuntuの下で問題のどれも再現することができませんでした。 手伝ってくれてありがとう!

このバグが健在であることを確認できます。

ジュピターノートブック、Python3、Sklearn0.19.1のWindows10で実行

Linux Mint(Ubuntu 16.10)Python3.5でも同じ問題

各コアの最初のエポックですべてがスタックし、CPUが混乱しているため、作業は行われていません。

@MrLobsはピクルスエラーのようですね。 CustomTransformerを別のPythonファイルに入れます。

@ Chrisjw42 @avatsaevコンテキストがないと、実際には多くのことができません。
@avatsaevは、テンソルフローを使用しているように聞こえますか?

@amuellerはい、テンソルフローです

@avatsaevそれはまだ本当に十分な情報ではありません。 再現するための最小限の例はありますか? どのブラスを使用していますか、GPUを使用していますか、どのバージョンのscikit-learnを使用していますか...。

わかりました。TFGPUを使用しているため、n_jobsを> 1に設定しても実際には機能しません。これは、GPUが1つしかないため正常です。

ええ、どちらの方法でも、TFでn_jobsを実際に使用するべきではありません。

何故なの?

@amueller 、はい、カスタムトランスフォーマーを別のファイルに入れると解決します

n_jobs!= 1が、ハングアップする環境でエラー(または少なくとも警告)をスローする可能性はありますか? 私はjupyterノートブックでこの問題に遭遇したばかりで、私が(クラスの他のメンバーのように)より初心者のユーザーである場合、gridsearchcvがハングし続ける理由を理解できなかったでしょう。実際、教師はn_jobs =-を使用するようにアドバイスしました。 1.1。 ここでの問題がわかっている場合、パッケージ(kerasまたはsklearnのいずれか)は、問題が発生することを警告し、ハングを防ぐことができますか?

これがどのような環境に陥るのか誰にもわからないと思います...このバグを信頼できる方法で再現できたとは思いません。

しかし、私たちはマルチプロセッシングインフラストラクチャの改善に取り組んでいます。
それがそのようなすべての問題を解決するかどうかは私にはわかりません。

@jnothman👍

それは聞いて素晴らしいです!

なぜこれが0.21とタグ付けされているのかわかりません。 これはほとんどの場合0.20で解決されます。 これを閉じて、人々に新しい問題を開かせるべきだと思います。 これは長すぎて不特定です。

AWSUbuntuでjupyterを使用して同じことに遭遇しました...

parallel_backendの使用は機能しているようです...


from sklearn.externals.joblib import parallel_backend

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

@morienor scikit-learn 0.20.1でこの問題を再現できる場合は、他の誰かが問題を再現できるようにするために必要なすべての詳細を含む新しい問題を開いてください(偽のランダムデータセットのインポートステートメントを含む完全なスクリプト) python、scikit-learn、numpy、scipy、およびオペレーティングシステムのすべてのバージョン番号が含まれています。

AWSUbuntuでjupyterを使用して同じことに遭遇しました...

parallel_backendの使用は機能しているようです...


from sklearn.externals.joblib import parallel_backend

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

それは私にとってはうまくいきます! どうもありがとう!

@ jmq19950824 @morienorええ、でもGILのためにthreadingバックエンドを使用しても意味がありません。

AWSUbuntuでjupyterを使用して同じことに遭遇しました...

parallel_backendの使用は機能しているようです...


from sklearn.externals.joblib import parallel_backend

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

天才は私のために働きます

このページは役に立ちましたか?
0 / 5 - 0 評価