Scikit-learn: GridSearchCV membeku tanpa batas dengan mengaktifkan multithreading (mis. W / n_jobs! = 1)

Dibuat pada 12 Agu 2015  ·  88Komentar  ·  Sumber: scikit-learn/scikit-learn

Saya sesekali mengalami masalah ini (dalam subjek) dengan GridSearchCV lebih dari setahun sekarang, di python 2.7, 3.3, dan 3.4, dua pekerjaan, beberapa platform / laptop mac osx yang berbeda, dan banyak versi berbeda dari numpy dan scikit- belajar (saya terus memperbaruinya dengan cukup baik).

Saya sudah mencoba semua saran ini dan tidak ada yang selalu berhasil:

https://github.com/scikit-learn/scikit-learn/issues/3605 - Mengatur metode mulai multiprosesing ke 'forkserver'
https://github.com/scikit-learn/scikit-learn/issues/2889 - HANYA mengalami masalah ketika fungsi penilaian kustom dilewati (Saya benar-benar mengalami masalah ini di mana GridSearchCV yang sama memanggil dengan n_jobs! = 1 diam dengan pencetak gol khusus tetapi baik-baik saja tanpa satu)
https://github.com/joblib/joblib/issues/138 - Mengatur variabel lingkungan dari jumlah utas MKL (Saya telah mencoba ini saat menjalankan numpy / sklearn yang dibangun terhadap mkl dari distribusi Anaconda)
Menskalakan input dan memastikan tidak ada kesalahan dengan n_jobs = 1 - Saya sangat yakin bahwa hal-hal yang saya coba lakukan pada beberapa utas berjalan dengan benar pada satu utas, dan dalam waktu singkat

Ini adalah masalah yang sangat membuat frustrasi yang sepertinya selalu muncul kembali tepat ketika saya yakin itu hilang, dan SATU-SATUNYA solusi yang berhasil 100% dari waktu bagi saya adalah pergi ke sumber GridSearchCV dalam distribusi sklearn apa pun yang saya gunakan mengubah set backend secara manual dalam panggilan ke Paralell ke 'threading' (bukan multiprocessing).

Saya belum membandingkan perbedaan antara peretasan dan pengaturan n_jobs = 1, tetapi apakah ada alasan untuk mengharapkan keuntungan dengan backend threading tanpa paralelisasi sama sekali? Tentu saja, ini tidak akan sebagus multiprosesing tetapi setidaknya lebih stabil.

btw versi terbaru yang memiliki masalah yang sama adalah:

  • 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
  • panda == 0.16.2
  • joblib == 0.8.4
Bug

Komentar yang paling membantu

@ eric-czech Jika Anda menggunakan Python 3.4 atau 3.5, coba setel variabel lingkungan berikut dan kemudian mulai ulang program python Anda:

export JOBLIB_START_METHOD="forkserver"

seperti yang dijelaskan di dokumen joblib . Forkserver is mode tidak diaktifkan secara default karena merusak fungsi yang ditentukan secara interaktif.

Semua 88 komentar

Apakah Anda mengalami masalah secara konsisten pada platform itu ??

Dalam hal multithreading: ada beberapa penaksir yang multithreading kemungkinan akan memberikan keuntungan besar, yang sebagian besar pekerjaannya dilakukan dalam operasi numpy atau Cython tanpa GIL. Sungguh, saya rasa ini tidak banyak dievaluasi; backend='threading' adalah hal yang cukup baru.

Pertanyaan sebenarnya adalah: apa lagi yang bisa kita lakukan untuk mengidentifikasi apa masalahnya?

Sebagai permulaan, penduga dasar apa yang telah Anda pertimbangkan?

@jnothman Berdasarkan platform apakah Anda OSX 10.9.5? Jika demikian, maka ya, ini bukan pertama kalinya saya mengalami masalah itu.

Satu detail utama yang mungkin saya abaikan sebelumnya adalah bahwa saya selalu menggunakan notebook IPython ketika saya mengalami masalah. Saya punya kernel untuk notebook yang dimuat sekarang di mana jika saya menambahkan argumen "scoring" dengan n_jobs! = 1 maka GridSearchCV hang selamanya tetapi jika saya menghapus argumen itu, semuanya baik-baik saja. Bahkan jika fungsi penilaian yang saya berikan tidak melakukan apa pun selain mengembalikan nilai float konstan, ia masih membeku (tetapi melakukan persis seperti yang Anda harapkan dengan n_jobs = 1).

Re: threading yang bagus untuk didengar, jadi mungkin opsi untuk GridSearchCV itu benar-benar masuk akal.

Sejauh apa estimator yang bermasalah dengan saya, saya tidak yakin saya bisa mempersempitnya. Saya biasanya mencoba sebanyak mungkin yang dapat saya kelola untuk mendapatkan beberapa informasi berguna untuk Anda di sini, saya baru saja memverifikasi bahwa saya dapat mereproduksi kondisi yang saya sebutkan di atas dengan penaksir apa pun dan menemukan bahwa saya dapat dalam semua kasus (atau setidaknya saya mencoba LogisticRegression, SGDClassifier, GBRT, dan RF).

Saya ingin melakukan apa saja dan semua yang saya bisa untuk memberikan sesuatu yang lebih untuk melanjutkan meskipun saya tidak terbiasa dengan konteks apa yang umumnya paling membantu untuk masalah multithreading seperti ini. Punya saran untuk saya?

Apakah Anda menggunakan numpy linked dengan accelerate framework?

Tidak, kecuali aku melewatkan sesuatu. Saya pikir versi numpy yang diinstal berubah ketika Anda melakukan itu atau setidaknya paket akselerasi akan hadir:

(riset3.4) eczech $ pip freeze | grep numpy
numpy == 1.9.2
(research3.4) eczech $ conda update accelerate
Kesalahan: paket 'akselerasi' tidak diinstal di /Users/eczech/anaconda/envs/research3.4

Maafkan ketidaktahuan saya karena tidak dapat menjawabnya dengan keyakinan 100%, tetapi saya tentu saja tidak melakukan apa pun dengan sengaja untuk menginstalnya.

Conda accelerate tidak sama dengan apple accelerate:
http://docs.continuum.io/accelerate/index
https://developer.apple.com/library/mac/documentation/Accelerate/Reference/AccelerateFWRef/

Conda accelerate adalah versi paket yang dipercepat MKL, apple accelerate adalah alternatif mereka untuk MKL.

dapatkah Anda memberi kami numpy.__config__.show() ?

multiprocessing tidak bekerja dengan akselerasi IIRC. ping @ogrisel

pasti:

np. config .show ()
atlas_3_10_blas_threads_info:
TIDAK TERSEDIA
atlas_info:
TIDAK TERSEDIA
atlas_3_10_info:
TIDAK TERSEDIA
atlas_threads_info:
TIDAK TERSEDIA
atlas_3_10_blas_info:
TIDAK TERSEDIA
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:
TIDAK TERSEDIA
atlas_blas_info:
TIDAK TERSEDIA
mkl_info:
TIDAK TERSEDIA
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:
TIDAK TERSEDIA
atlas_3_10_threads_info:
TIDAK TERSEDIA
openblas_info:
TIDAK TERSEDIA
openblas_lapack_info:
TIDAK TERSEDIA
atlas_blas_threads_info:
TIDAK TERSEDIA

Ya, jadi itu adalah masalah umum yang tidak dapat saya temukan di pelacak masalah. Mempercepat tidak berfungsi dengan multiprosesing.

Saya sedikit bingung. Backend threading hanya melakukan sesuatu saat GIL dilepaskan, bukan?

Gotcha, apakah kamu tahu bagaimana aku harus membangun kembali numpy? Haruskah saya menginstal pip saja daripada menggunakan paket conda untuk itu? Atau akankah saya lebih baik membangun dari sumber dan memastikan argumen percepatan apel itu tidak ada?

Kedengarannya seperti ini adalah masalah nonstarter. Tutup jika hanya memukuli kuda mati.

jika Anda bisa mempercepat konda, itu akan berhasil;)

mungkin kita bisa mencoba menebus joblib ?

Ah bagus, kontinum pasti telah membayar apel untuk melakukan itu haha.

Punya saran $ 0? Dan terima kasih atas wawasannya.

Oh dan juga saya tahu ini telah ditanyakan sebelumnya, tetapi apakah fakta bahwa saya hanya mengalami masalah ini di platform saya saat ini ketika menggunakan fungsi penilaian khusus sesuatu untuk dilanjutkan? Untuk kehidupan saya, saya tidak dapat melihat apa yang mungkin menjadi masalah tentang yang diberikan kode sumber grid_search.py, tetapi mungkinkah itu ada hubungannya dengan pengawetan fungsi khusus?

Dan agak tidak terkait dengan itu, saya baru ingat bahwa saya juga mencoba mengatasi hal ini di masa lalu dengan membuat versi modifikasi dari GridSearchCV yang menggunakan backend paralel IPython, jadi dengan asumsi saya meninjau kembali solusi itu, apakah layak untuk dibagikan? Solusi itu bekerja dengan baik tetapi sedikit menyusahkan untuk digunakan karena setiap kelas dan fungsi khusus harus tersedia di pythonpath daripada di notebook itu sendiri tetapi jika tidak ada opsi lain yang lebih baik, mungkin yang satu memiliki beberapa kaki.

Anda dapat menautkan ke atlas, tapi itu akan menjadi [apple] lebih lambat, saya pikir.
Mungkin ada numpy terkait MKL gratis di luar sana untuk OS X? Ada satu untuk windows.

[Jika Anda seorang akademisi, percepatan kontinum gratis btw]

Saya cukup yakin ini sama sekali tidak terkait dengan penggunaan fungsi penilaian kustom.
Dapatkah Anda memberikan sniplet mandiri yang rusak dengan fungsi penilaian khusus tetapi bukan tanpa?

Mungkin fakta dari fungsi penilaian kustom relevan (misalnya masalah pengawetan atau paralelisme bersarang mungkin relevan). Bisakah kita melihat kodenya?

Atau apakah yang Anda maksud hanya metrik standar dengan make_scorer ?

Tentu saja, ini bagian yang relevan dan sepertinya semuanya baik-baik saja dengan make_scorer tetapi tidak dengan fungsi khusus:

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

Saya akan mengerjakan versi mandiri yang melibatkan beberapa versi data yang saya gunakan juga (tetapi akan memakan waktu lebih lama). Sementara itu, pengawetan fungsi khusus tersebut terdengar seperti petunjuk yang baik - saya sudah mencobanya beberapa kali lagi untuk memastikan dan itu hang 100% dari waktu dengan fungsi khusus dan 0% waktu saat menggunakan make_scorer dengan beberapa fungsi metrik yang diimpor dan diketahui.

Dan apakah itu di main (yaitu skrip tingkat atas sedang diinterpretasikan) atau file
modul yang diimpor?

Pada 15 Agustus 2015 pukul 23:37, Eric Czech [email protected] menulis:

Tentu saja, ini bagian yang relevan dan sepertinya semuanya baik-baik saja
dengan make_scorer tetapi tidak dengan fungsi khusus:

dari sklearn.linear_model import LogisticRegressiondari sklearn.grid_search import GridSearchCVdari sklearn.cross_validation import StratifiedKFolddari sklearn.metrics import average_precision_score, make_scorerimport functools

res = []
clfs = []
untuk tanggapan dalam tanggapan:
X, y = d_in [fitur], d_in [respon]
untuk i, (train, test) in enumerate (StratifiedKFold (y, 5)):
X_train, y_train, X_test, y_test = X.iloc [kereta], y.iloc [kereta], X.iloc [tes], y.iloc [tes]
clf = LogisticRegression (penalti = 'l1')
kisi = {
'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 ()

Saya akan mengerjakan versi mandiri yang melibatkan beberapa versi
data yang saya gunakan juga (tetapi akan memakan waktu lebih lama). Sementara itu,
pengawetan fungsi khusus itu terdengar seperti petunjuk yang bagus - saya sudah mencobanya
beberapa kali lagi untuk memastikan dan hang 100% dari waktu dengan kebiasaan
fungsi dan 0% dari waktu saat menggunakan make_scorer dengan beberapa yang diketahui,
fungsi metrik yang diimpor.

-
Balas email ini secara langsung atau lihat di GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298
.

Oh, ini ipynb. Hmmm menarik. Ya, pengawetan bisa menjadi masalah ..?

Pada 15 Agustus 2015 pukul 23:51, Joel Nothman joel. [email protected] menulis:

Dan apakah itu di main (yaitu skrip tingkat atas sedang ditafsirkan) atau
modul yang diimpor?

Pada 15 Agustus 2015 pukul 23:37, Eric Czech [email protected] menulis:

Tentu saja, ini bagian yang relevan dan sepertinya semuanya baik-baik saja
dengan make_scorer tetapi tidak dengan fungsi khusus:

dari sklearn.linear_model import LogisticRegressiondari sklearn.grid_search import GridSearchCVdari sklearn.cross_validation import StratifiedKFolddari sklearn.metrics import average_precision_score, make_scorerimport functools

res = []
clfs = []
untuk tanggapan dalam tanggapan:
X, y = d_in [fitur], d_in [respon]
untuk i, (train, test) in enumerate (StratifiedKFold (y, 5)):
X_train, y_train, X_test, y_test = X.iloc [kereta], y.iloc [kereta], X.iloc [tes], y.iloc [tes]
clf = LogisticRegression (penalti = 'l1')
kisi = {
'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 ()

Saya akan mengerjakan versi mandiri yang melibatkan beberapa versi
data yang saya gunakan juga (tetapi akan memakan waktu lebih lama). Sementara itu,
pengawetan fungsi khusus itu terdengar seperti petunjuk yang bagus - saya sudah mencobanya
beberapa kali lagi untuk memastikan dan hang 100% dari waktu dengan kebiasaan
fungsi dan 0% dari waktu saat menggunakan make_scorer dengan beberapa yang diketahui,
fungsi metrik yang diimpor.

-
Balas email ini secara langsung atau lihat di GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -131376298
.

Itu ada di buku catatan

Saya akan mencoba mengimpornya dari modul dan melihat bagaimana kelanjutannya

Hmm apa yang Anda ketahui, berfungsi dengan baik jika ditentukan di luar notebook.

Saya pada dasarnya memiliki kode yang sama yang berjalan di python 2.7 (saya membutuhkan lib yang lebih tua) serta kode ini di python 3.4 dan sementara saya memiliki masalah gantung di 2.7 terlepas dari apakah itu fungsi khusus atau sesuatu menggunakan make_scorer, saya pikir itu menyelesaikan semua masalah saya di versi yang lebih baru sehingga saya bisa hidup dengan solusi di versi lama.

Ada lagi yang bisa saya lakukan untuk melacak mengapa fungsi pengawetan yang didefinisikan di notebook mungkin menjadi masalah?

Nah, kami ingin memahami:

  • apakah pengawetan dan pembongkaran biasanya merupakan masalah untuk fungsi yang ditentukan secara lokal pada platform tersebut, atau apakah kita mengalami hambatan tertentu?
  • mengapa, jika pengawetan menjadi masalah, apakah itu menggantung daripada memunculkan pengecualian? Bisakah Anda mencoba menambal monyet atau yang serupa, untuk melihat apakah mengganti cek pickle.dumps(function) https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/externals/joblib/parallel. py # L150 dengan pickle.loads(pickle.dumps(function)) menghasilkan kesalahan? (Untuk menjelaskannya, ini adalah pemeriksaan keamanan untuk memastikan kemampuan pengambilan sebelum menjalankan multiprocessing.)

@ogrisel mungkin tertarik dengan ini.

Dari apa yang saya lihat di windows, notebook memiliki interaksi yang aneh dengan multiprosesing.

Sudahkah Anda mencoba hanya mengawetkan dan melepaskan fungsi yang ditentukan dalam notebook yang sama?

Hari ini saya secara tidak sengaja telah melihat https://pythonhosted.org/joblib/parallel.html#bad -interaction-of-multiprocessing-and-third-party-libraries, bukankah ini terkait?
Mungkin Anda sebaiknya meningkatkan ke python 3.4 atau yang lebih baru?

Maaf pergi liburan panjang. Untuk menjawab pertanyaan Anda:

  1. re @jnothman : Saya meletakkan pickle.loads(pickle.dumps(function)) di parallel.py dan pernyataan cetak setelahnya untuk memastikan itu dijalankan dengan bersih, dan tidak ada masalah di sana. Agar jelas, GridSearchCV.fit yang dipanggil dari notebook masih macet seperti sebelumnya tanpa perubahan (kecuali untuk pernyataan cetak yang saya tambahkan muncul 16 kali dengan n_jobs = -1).
  2. re @amueller : Jika saya memahami Anda dengan benar, maka saya menjalankan sesuatu seperti ini di buku catatan tanpa masalah:
def test_function(x):
    return x**2
pickle.loads(pickle.dumps(test_function))(3)
# 9
  1. re @olologin : Saya di 3.4.3. Atau lebih khusus lagi: '3.4.3 | Continuum Analytics, Inc. | (default, 6 Maret 2015, 12:07:41) n [GCC 4.2.1 (Apple Inc. build 5577)] '

Saya belum membaca percakapan di atas tetapi saya ingin mencatat bahwa tes minimal ini gagal di bawah build travis Python 2.6 tetapi lolos di bawah konfigurasi yang sama di PC saya ... (menyarankan itu gagal ketika n_jobs = -1 diatur di bawah mesin inti tunggal untuk versi python / joblib / scipy lama?)

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 untuk mengalami masalah ini, dengan senang hati memberikan detail jika itu akan membantu

@ eric-czech Jika Anda menggunakan Python 3.4 atau 3.5, coba setel variabel lingkungan berikut dan kemudian mulai ulang program python Anda:

export JOBLIB_START_METHOD="forkserver"

seperti yang dijelaskan di dokumen joblib . Forkserver is mode tidak diaktifkan secara default karena merusak fungsi yang ditentukan secara interaktif.

Memiliki masalah yang sama pada OS X 10.11.4 dan Ubuntu 14.04 dengan perangkat lunak terbaru yang diinstal.

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

Sebenarnya, kode ini tidak hanya membeku jika n_jobs=1 .

Ini sekarang harus bekerja secara default pada python 3 dan menjadi wontfix pada python 2, benar @ogrisel ? Haruskah kita tutup?

Jika hang diam-diam pada Python 2 tanpa memberikan peringatan atau kesalahan ("n_jobs> 1 tidak didukung pada Python 2"), itu tidak dapat diterima; bisakah kita membuat kesalahan?

@amueller pada Python 3 Anda dapat mengikuti https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment -187683383 untuk mengatasi masalah, yaitu tidak akan berfungsi secara default bahkan pada Python 3.

Tidak yakin apakah kita harus menutupnya karena OP asli sepertinya mengatakan bahwa pengaturan joblib start_method ke forkserver tidak selalu berfungsi ...

BTW yang xgboost adalah yang dikenal, lihat https://github.com/scikit-learn/scikit-learn/issues/6627#issuecomment -206351138.

Sunting: Perubahan di bawah ini mungkin tidak benar-benar memperbaiki banyak hal. Ada perubahan yang tidak terkait yang saya buat juga pada cara saya menangani multiprosesing dengan Pathos yang mungkin merupakan perbaikan saya yang sebenarnya.

Perbaikan Cepat:
np.random.seed(0)

Penjelasan:
Saya telah mengalami masalah ini juga, paling akut di rangkaian pengujian untuk auto_ml . Pertama kali (2?) Kali saya menjalankan GridSearchCV, tidak apa-apa, tetapi proses selanjutnya akan hang tanpa error.

Saya baru saja menetapkan np.random.seed(0) di dalam setiap pengujian saya, untuk memastikan reproduktifitas sambil tetap memberikan diri saya fleksibilitas untuk menyusun ulang pengujian dari waktu ke waktu tanpa mengotak-atik keacakan. Segera setelah saya melakukannya, semua tes yang tergantung pada kesalahan GSCV mulai bekerja kembali.

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

harap ini membantu dalam proses debug!

Lingkungan pengembang:
Mac OS X (Sierra)
Python 2.7
Versi perpustakaan terbaru.

@ ClimbsRocks baik itu mungkin beberapa kesalahan dalam estimator Anda. Beri tahu kami jika Anda memiliki contoh yang dapat direproduksi;)

@amueller : panggilan bagus. Aku buru-buru memotong cabang agar kalian bisa mereproduksi ini, tapi kali ini semuanya berjalan dengan benar.

Saya pikir itu mungkin masalah menggunakan paralelisasi GSCV, ketika saya juga menggunakan paralelisasi Pathos di bagian lain dari program. Itulah satu-satunya hal terkait lainnya yang telah saya ubah dalam seminggu terakhir ini.

Sejak itu saya telah merefaktor untuk lebih menutup dan membuka kolam multiprosesing mereka.

Apa yang membuat saya berpikir bahwa ini bukan hanya bug di salah satu estimator adalah ketika membangun rangkaian pengujian, setiap pengujian dijalankan dan dilewati secara individual. Hanya ketika saya menjalankan beberapa tes dalam lintasan yang sama yang semuanya bergantung pada GSCV yang mulai menggantung.

Diedit sebelumnya komentar untuk mencatat ketidakpastian ini.

jika Anda menggabungkan joblib dengan paralelisasi lain, kemungkinan besar itu akan macet dan Anda tidak boleh mencobanya.

Maaf untuk memperbaiki utas ini, tetapi saya juga mengalami masalah ini.
Saya membuat kernel Python 3.5 dan mendefinisikan metode job lib start ke forkserver tetapi saya masih memiliki masalah.

Sebenarnya itu bahkan tidak bekerja dengan n_jobs = 1. Saya melihatnya menghitung kecuali untuk parameter terakhir.

Apakah ada kabar?

Sebenarnya itu bahkan tidak bekerja dengan n_jobs = 1. Saya melihatnya menghitung kecuali untuk parameter terakhir.

Ini aneh dan kemungkinan besar tidak terkait dengan masalah ini (yaitu sekitar n_jobs != 1 ). Cara terbaik untuk mendapatkan umpan balik yang baik adalah dengan membuka masalah terpisah dengan cuplikan berdiri sendiri yang mereproduksi masalah tersebut.

Saya cukup yakin saya menemukan masalah ini sendiri. Setelah mencoba banyak kombinasi, semua yang saya lakukan dengan n_jobs> 1 langsung membeku setelah beberapa kali lipat. Saya menggunakan Laptop Linux Ubuntu dengan sklearn = 0.19.0, jadi ini adalah konfigurasi yang berbeda dari yang lain yang telah saya baca. Berikut adalah kode yang "menyinggung":

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

Salah satu hal yang menarik adalah ketika saya mengimpor xgboost, saya mendapatkan peringatan penghentian di GridSearchCV seolah-olah tidak mengimpor dari model_selection. Namun, saya menggunakan xgboost 0.62 dan dalam melihat repositori mereka sepertinya mereka mengimpor GridSearchCV yang benar. Untuk lebih jelasnya, peringatan penghentian bukanlah masalah yang menjadi perhatian saya, melainkan masalah yang ada: eksekusi dibekukan dengan n_jobs> 1. Hanya menunjukkan jika itu bisa membantu.

dapatkah Anda memberikan data untuk membantu mereplikasi masalah tersebut?

Pada 24 Agustus 2017 pukul 20:29, Xavier Amatriain [email protected]
menulis:

Saya cukup yakin saya menemukan masalah ini sendiri. Setelah mencoba banyak
kombinasi, semua yang saya lakukan dengan n_jobs> 1 hanya membeku setelah beberapa
lipatan. Saya menggunakan Laptop Linux Ubuntu dengan sklearn = 0.19.0, jadi ini adalah file
konfigurasi yang berbeda dari yang lain yang telah saya baca. Ini dia
kode "menyinggung":

`impor xgboost sebagai xgb
dari sklearn.model_selection impor 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, 'objektif': ' binary: logistik '}
dioptimalkan_XGB = GridSearchCV (xgb.XGBClassifier (** ind_params),
cv_params, penilaian = 'roc_auc', cv = 5, n_jobs = 1, verbose = 2)
dioptimalkan_XGB.fit (xgboost_train, label_train, eval_metric = 'auc') `

Salah satu hal yang menarik adalah saat saya mengimpor xgboost, saya mendapatkan file
peringatan penghentian di GridSearchCV seolah-olah tidak diimpor dari
model_selection. Namun, saya menggunakan xgboost 0,62 dan melihat mereka
repositori sepertinya mereka mengimpor GridSearchCV yang benar. Menjadi
jelas, peringatan penghentian bukanlah masalah yang menjadi perhatian saya, melainkan
satu di tangan: eksekusi beku dengan n_jobs> 1. Hanya menunjukkan
kasus itu bisa membantu.

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-324597686 ,
atau nonaktifkan utasnya
https://github.com/notifications/unsubscribe-auth/AAEz66DbfTlnU_-dcxLKa5zkrcZ-0qVOks5sbVCmgaJpZM4FqYlN
.

Tentu, Anda dapat mengunduh file persis yang saya gunakan dari:
https://xamat.github.io/xgboost_train.csv
https://xamat.github.io/label_train.csv

HTTP404

Maaf, ada kesalahan pada tautan pertama, sekarang seharusnya sudah diperbaiki. Yang ke-2 juga harus oke, baru saya cek.

Masalah umum dengan xgboost, lihat https://github.com/scikit-learn/scikit-learn/issues/6627#issuecomment -206351138 misalnya.

FYI, loky backend di joblib akan menghilangkan masalah seperti ini, tetapi ini hanya akan tersedia di scikit-learn 0.20.

Apakah ini masih bug? Saya mengalami masalah yang sama dengan default (n_jobs = 1) serta dengan pre_dispatch = 1, menggunakan RandomForestClassifier , dengan 80 kombinasi parameter dan CV ShuffleSplit (n = 20).

Itu juga tergantung pada Pipeline ( SelectKBest(score_func=mutual_info_classif, k=10) diikuti oleh RandomForestClassifier ), baik di bawah rilis terbaru maupun versi pengembangan.

Beri tahu saya jika Anda menemukan solusi, atau metode pemilihan model lain yang berfungsi dengan andal. Berpikir untuk mencoba scikit-optimize .

Apakah maksud Anda n_jobs = 1 atau itu salah ketik? Masalah ini tentang n_jobs! = 1.

Cara terbaik untuk mendapatkan umpan balik yang berkualitas adalah dengan menyediakan cara untuk mereproduksi masalah. Silakan buka masalah terpisah dalam kasus ini jika masalah yang Anda lihat memang dengan n_jobs = 1.

Saya menulis apa yang saya maksud, yaitu "multithreading diaktifkan"
n_jobs! = 1 seperti pada 'tidak sama dengan 1'. Sama halnya, n_jobs> 1. Misalnya, n_jobs = 4

Apakah Anda mengatakan Anda tidak dapat melakukan repro pembekuan untuk n_jobs = 4?

Jika demikian, saya akan memberikan testcase dalam waktu satu bulan (saya mengganti ke mesin baru.)

Pada 12 Sep 2017, pukul 7:10, Loïc Estève < [email protected] [email protected] > menulis:

Apakah maksud Anda n_jobs = 1 atau itu salah ketik? Masalah ini tentang n_jobs! = 1.

Cara terbaik untuk mendapatkan umpan balik yang berkualitas adalah dengan menyediakan cara untuk mereproduksi masalah. Silakan buka masalah terpisah dalam kasus ini jika masalah yang Anda lihat memang dengan n_jobs = 1.

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328864498 , atau nonaktifkan utas https://github.com/notifications/unsubscribe- auth / ABH-rd7wgU5lcS6oD5VMl0YOB8CXfSTJks5shpDZgaJpZM4FqYlN .

@cinerney apakah Anda @raamana? Saya pikir @lesteve membalas @raamana yang menulis n_jobs=1 , yang tampaknya tidak terkait dengan masalah ini.

Oh maaf, tidak, saya bukan @raamana. Ya, masalah @ raamana berbeda (tetapi mungkin karena kode yang sama)

Pada 12 Sep 2017, pukul 09.23, Andreas Mueller < [email protected] [email protected] > menulis:

@smcinerney https://github.com/smcinerney apakah Anda @raamana https://github.com/raamana ? Saya pikir @lesteve https://github.com/lesteve membalas @raamana https://github.com/raamana yang menulis n_jobs = 1, yang tampaknya tidak terkait dengan masalah ini.

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-328905819 , atau nonaktifkan utas https://github.com/notifications/unsubscribe- auth / ABH-rYKQA3L5ifINBX6enrk5oDIsf1Lqks5shrASgaJpZM4FqYlN .

Saya buruk, saya tidak bermaksud mencampuradukkan. Saya akan membuka masalah lain (dengan kode minimal untuk mereproduksinya), tetapi GridSearchCV tidak tergantung bahkan dengan default n_jobs = 1 adalah masalah yang lebih besar (mengingat ini adalah default dan seharusnya berfungsi) daripada n_jobs> 1.

@raamana ya itu masalah yang lebih besar tetapi juga tidak mungkin disebabkan oleh masalah terkait.

@ eric-czech @joth
Jadi jika Anda memutuskan untuk menggunakan backend = 'threading'. Salah satu metode mudah tanpa mengubah kode sklearn adalah dengan menggunakan manajer konteks parallel_backend dan tidak mengubah metode fit GSV.

from sklearn.externals.joblib import parallel_backend

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

PS: Saya tidak yakin apakah "threading" berfungsi untuk semua estimator. Tetapi saya mengalami masalah yang sama dengan estimator saya dengan GSV njob> 1 dan menggunakan ini berfungsi seperti yang diharapkan untuk saya tanpa mengubah perpustakaan.

Sistem mencoba:
MAC OS: 10.12.6
Python: 3.6
numpy == 1.13.3
panda == 0.21.0
scikit-learn == 0.19.1

Hmm ... Mungkin ada beberapa masalah konkurensi dengan penggunaan threading backend
pencarian grid, misalnya bug di # 10329 menciptakan kondisi balapan ...

Pada 22 Desember 2017 pukul 03:59, Trideep Rath [email protected] menulis:

@ eric-czech https://github.com/eric-czech @jnothman
https://github.com/jnothman
Jadi jika Anda memutuskan untuk menggunakan backend = 'threading'. Satu cara mudah tanpa
mengubah kode sklearn akan menggunakan manajer konteks parallel_backend
dan tidak mengubah metode fit GSV.

dari sklearn.externals.joblib impor parallel_backend

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

PS: Saya tidak yakin apakah "threading" berfungsi untuk semua estimator. Tetapi saya
mengalami masalah yang sama dengan estimator saya dengan GSV njob> 1 dan menggunakan ini
berfungsi seperti yang diharapkan untuk saya tanpa mengubah perpustakaan.

Sistem mencoba:
MAC OS: 10.12.6
Python: 3.6
numpy == 1.13.3
panda == 0.21.0
scikit-learn == 0.19.1

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/scikit-learn/scikit-learn/issues/5115#issuecomment-353402474 ,
atau nonaktifkan utasnya
https://github.com/notifications/unsubscribe-auth/AAEz64SfwYpjLU1JK0vukBRXJvWYs3LKks5tCo51gaJpZM4FqYlN
.

Kasus: Menggunakan backend sebagai "threading" dan menggunakan Estimator yang memperluas BaseEstimator dan ClassifierMixin. Saya tidak yakin di mana kondisi balapan itu terjadi. Bisakah Anda menjelaskan lebih lanjut.

Sesuai pemahaman dan eksperimen saya, saya tidak mengamati kondisi balapan apa pun.

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 dipanggil pada klon (base_estimator). Ini melakukan deep_copy dan memiliki salinan datanya sendiri.

out adalah output dari metode _fit_and_score. Jadi setelah ini, semua utas telah selesai mengeksekusi metode fit dari estimator dan melaporkan hasilnya.

Hasilnya adalah apa yang Anda dapatkan dari GCV_clf.cv_results_

Bisakah Anda menjelaskan dalam kasus khusus ini mengapa hal itu menyebabkan kondisi balapan?

Kondisi balapan terjadi jika Anda menyetel parameter bersarang, yaitu kapan
satu parameter yang diubah adalah estimator dan parameter lainnya adalah
penduga.

Saya mengalami masalah yang sama menggunakan make_scorer dalam kombinasi dengan GridSearchCv dan n_jobs=-1 bawah Win 7 dengan versi terbaru:

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 terima kasih telah memposting versi dan platform Anda! Kesempatan terbaik untuk mendapatkan umpan balik berkualitas baik adalah dengan memberikan cuplikan yang berdiri sendiri untuk mereproduksi masalah. Harap baca https://stackoverflow.com/help/mcve untuk detail selengkapnya.

Mengalami masalah yang sama di bawah Win7 dengan langkah praproses kustom apa pun.
Toolchain:

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

apakah Anda tahu bahwa multiprosesor python tidak akan berfungsi di windows tanpa if __name__ == '__main__' ?

Ya, benar. Maaf, lupa memberi tahu saya menggunakan Jupyter.
Skrip mandiri dengan if __name__ == '__main__' mencetak jejak berikut dan kemudian masih membeku:

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 Menarik. Karena kemalasan saya menempatkan seluruh skrip di bawah if __name__ == '__main__' dan mendapatkan hasil dari komentar sebelumnya.

Sekarang saya hanya menempatkan pipeline = make_pipeline... , dan berhasil dieksekusi. Mungkinkah penyebabnya di Jupyter?

Bagaimanapun, saya tidak tahu apakah perilaku dalam komentar sebelumnya valid dan disebabkan oleh penggunaan if __name__ == '__main__' , atau apakah itu kesalahan SkLearn.

sepertinya itu bukan masalah dengan perpustakaan kami, tetapi tentang eksekusi
konteks untuk multiprocessing di windows ...

Jelek sekali. Dan memang, saya tidak dapat mereproduksi masalah apa pun di Ubuntu dengan versi yang sama dari semuanya. Terimakasih atas bantuannya!

Dapat mengonfirmasi bug ini masih hidup dan sehat.

Berjalan di Windows 10 di notebook jupyter, Python3, Sklearn 0.19.1

Masalah yang sama di Linux Mint (Ubuntu 16.10) Python 3.5

Semuanya macet di Epoch pertama di setiap inti, dan CPU sedang sibuk, jadi tidak ada pekerjaan yang dilakukan.

@MrLobs kedengarannya seperti kesalahan pengawetan, bukan? letakkan CustomTransformer di file python terpisah.

@ Chrisjw42 @avatsaev tanpa konteks lebih lanjut, kami tidak dapat berbuat banyak.
@avatsaev terdengar seperti Anda mungkin menggunakan tensorflow?

@amueller ya itu tensorflow

@avatsaev itu masih belum cukup informasi. Apakah Anda memiliki contoh minimum untuk direproduksi? blas apa yang Anda gunakan, apakah Anda menggunakan GPU, versi scikit-learn apa yang Anda gunakan ....

Ok ternyata karena saya menggunakan GPU TF jadi setting n_jobs ke> 1 tidak terlalu berfungsi, yang normal karena saya hanya punya satu GPU lol

ya, Anda sebaiknya tidak menggunakan n_jobs dengan TF.

kenapa tidak?

@amueller , ya, menempatkan trafo khusus ke dalam file terpisah akan menyelesaikannya

Apakah mungkin bagi n_jobs! = 1 untuk membuat kesalahan (atau setidaknya peringatan) di lingkungan yang akan membuatnya bertahan? Saya baru saja mengalami masalah ini di notebook jupyter, dan jika saya adalah pengguna yang lebih pemula (seperti anggota kelas saya lainnya), saya tidak akan pernah tahu mengapa gridsearchcv terus menggantung, bahkan, guru kami bahkan menyarankan kami untuk menggunakan n_jobs = - 1. Jika masalah di sini diketahui, dapatkah paket (keras, atau sklearn, mana saja) memperingatkan bahwa hal itu akan terjadi dan mencegah hang?

Saya tidak berpikir ada orang yang tahu lingkungan apa ini akan bertahan ... Saya tidak percaya ada yang berhasil mereproduksi bug ini dengan cara yang dapat diandalkan.

tetapi kami berupaya meningkatkan infrastruktur multiprosesing kami.
tidak jelas bagi saya apakah itu akan menyelesaikan semua masalah seperti itu.

@jnothman 👍

Senang mendengarnya!

Saya tidak yakin mengapa ini diberi tag 0.21. Ini diselesaikan dalam 0.20 dalam banyak kasus. Saya pikir kita harus menutup ini dan membuat orang membuka masalah baru. Yang ini terlalu panjang dan tidak spesifik.

Saya baru saja menemukan hal yang sama di AWS Ubuntu dengan jupyter ...

Menggunakan parallel_backend sepertinya berhasil ...


from sklearn.externals.joblib import parallel_backend

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

@morienor jika Anda dapat mereproduksi masalah ini dengan scikit-learn 0.20.1, buka masalah baru dengan semua detail yang diperlukan agar orang lain dapat mereproduksi masalah (skrip lengkap dengan pernyataan impor pada kumpulan data acak palsu) bersama dengan semua nomor versi untuk python, scikit-learn, numpy, scipy dan sistem operasi.

Saya baru saja menemukan hal yang sama di AWS Ubuntu dengan jupyter ...

Menggunakan parallel_backend sepertinya berhasil ...


from sklearn.externals.joblib import parallel_backend

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

Itu berhasil untuk saya! Terima kasih banyak!

@ jmq19950824 @morienor ya, tetapi tidak ada gunanya menggunakan threading backend karena GIL.

Saya baru saja menemukan hal yang sama di AWS Ubuntu dengan jupyter ...

Menggunakan parallel_backend sepertinya berhasil ...


from sklearn.externals.joblib import parallel_backend

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

jenius bekerja untuk saya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat