8

मेरे पास 2000 प्रशिक्षित यादृच्छिक प्रतिगमन पेड़ का एक सेट है (n_estimators=1 के साथ विज्ञानकिट सीखने के यादृच्छिक वन रजिस्ट्रार से)। multiprocessing का उपयोग करके बड़े डेटासेट (~ 100000 * 700000 = 70GB @ 8-बिट) पर समानांतर (50 कोर) में पेड़ों को प्रशिक्षण देना और साझा स्मृति जैसे आकर्षण की तरह काम करता है। नोट, मैं आरएफ के इनबिल्ट मल्टीकोर समर्थन का उपयोग नहीं कर रहा हूं क्योंकि मैं पहले से ही सुविधा चयन कर रहा हूं।समझना विज्ञान सीखना भविष्यवाणी के लिए यादृच्छिक वन स्मृति आवश्यकता

समस्या: समानांतर में एक बड़े मैट्रिक्स (~ 20000 * 700000) का परीक्षण करते समय मैं हमेशा स्मृति से बाहर चला जाता हूं (मेरे पास 500 जीबी रैम वाले सर्वर तक पहुंच है)।

मेरी रणनीति मेमोरी में टेस्ट मैट्रिक्स रखना और इसे सभी प्रक्रियाओं में साझा करना है। statement by one of the developers के अनुसार परीक्षण के लिए स्मृति आवश्यकता 2 * n_jobs * sizeof (X) है, और मेरे मामले में * 4 का एक और कारक प्रासंगिक है, क्योंकि 8 बिट मैट्रिक्स प्रविष्टियां आरएफ में आंतरिक रूप से फ्लोट 32 तक पहुंच जाती हैं।

तक नंबर, मैं परीक्षण के लिए लगता है कि मैं की जरूरत है: स्मृति में परीक्षण मैट्रिक्स धारण करने के लिए
14GB + 50 (= n_jobs) * 20000 (N_SAMPLES) * 700 (= n_features) * 4 (upcasting फ्लोट करने के लिए) * 2 बाइट्स = 14 जीबी + 5.6 जीबी = ~ 21 जीबी मेमोरी।

फिर भी यह हमेशा कई सैकड़ों जीबी तक उड़ाता है। मुझे यहां क्या याद आ रही है? (मैं, की scikit सीखने नवीनतम संस्करण पर हूँ तो पुराने स्मृति मुद्दों बाहर इस्त्री किया जाना चाहिए)

एक अवलोकन:
एक कोर के परीक्षण के लिए केवल स्मृति उपयोग 30 और 100 जीबी के बीच उतार चढ़ाव होता रहता पर चल रहा है (के रूप में मापा जाता free द्वारा)

मेरे कोड:

#---------------- 
#helper functions 
def initializeRFtest(*args): 
    global df_test, pt_test #initialize test data and test labels as globals in shared memory 
    df_test, pt_test = args 


def star_testTree(model_featidx): 
    return predTree(*model_featidx) 

#end of helper functions 
#------------------- 

def RFtest(models, df_test, pt_test, features_idx, no_trees): 
    #test trees in parallel 
    ncores = 50 
    p = Pool(ncores, initializer=initializeRFtest, initargs=(df_test, pt_test)) 
    args = itertools.izip(models, features_idx) 
    out_list = p.map(star_testTree, args) 
    p.close() 
    p.join() 
    return out_list 

def predTree(model, feat_idx): 
    #get all indices of samples that meet feature subset requirement 
    nan_rows = np.unique(np.where(df_test.iloc[:,feat_idx] == settings.nan_enc)[0]) 
    all_rows = np.arange(df_test.shape[0]) 
    rows = all_rows[np.invert(np.in1d(all_rows, nan_rows))] #discard rows with missing values in the given features 

    #predict 
    pred = model.predict(df_test.iloc[rows,feat_idx]) 
    return predicted 

#main program 
out = RFtest(models, df_test, pt_test, features_idx, no_trees) 

संपादित करें: एक और अवलोकन: जब परीक्षण डाटा कार्यक्रम रन रों बेडौल बहुत कम स्मृति उपयोग के साथ धीरे-धीरे। यही वह प्रोग्राम है जिसे मैं प्रोग्राम चलाने के लिए उपयोग करता था।
अद्यतन predTree समारोह के लिए कोड स्निपेट:

def predTree(model, feat_idx): 
    # get all indices of samples that meet feature subset requirement 
    nan_rows = np.unique(np.where(test_df.iloc[:,feat_idx] == settings.nan_enc)[0]) 
    all_rows = np.arange(test_df.shape[0]) 
    rows = all_rows[np.invert(np.in1d(all_rows, nan_rows))] #discard rows with missing values in the given features 

    # predict height per valid sample 
    chunksize = 500 
    n_chunks = np.int(math.ceil(np.float(rows.shape[0])/chunksize)) 


    pred = [] 
    for i in range(n_chunks): 
     if n_chunks == 1: 
      pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:], feat_idx]) 
      pred.append(pred_chunked) 
      break 
     if i == n_chunks-1: 
      pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:], feat_idx]) 
     else: 
      pred_chunked = model.predict(test_df.iloc[rows[i*chunksize:(i+1)*chunksize], feat_idx]) 
     print pred_chunked.shape 
     pred.append(pred_chunked) 
    pred = np.concatenate(pred) 

    # populate matrix 
    predicted = np.empty(test_df.shape[0]) 
    predicted.fill(np.nan) 
    predicted[rows] = pred 
    return predicted 
+0

आपके 2000 प्रशिक्षित यादृच्छिक प्रतिगमन पेड़ कितनी मेमोरी लेते हैं? क्या उन्हें 50 कोरों में से प्रत्येक के लिए कॉपी किया जा रहा है? –

+0

@ ब्रायन ओ'डोनेल क्या आपका मतलब मॉडल का आकार है? मेरे पास अब मॉडल तक पहुंच नहीं है, लेकिन यह आकार में निश्चित रूप से प्रबंधनीय था। – Dahlai

+0

हां, मॉडल का आकार। –

उत्तर

0

मैं अगर स्मृति मुद्दा args = itertools.izip(models, features_idx) में itertools.izip के उपयोग से संबंधित नहीं है जो सभी धागे भर में अपने तर्कों सहित इटरेटर की प्रतियां के निर्माण गति प्रदान कर सकते यकीन नहीं है । क्या आपने अभी zip का उपयोग करने की कोशिश की है?

एक और परिकल्पना अक्षम कचरा संग्रह हो सकती है - जब आपको इसकी आवश्यकता होती है तो ट्रिगर नहीं किया जाता है। predTree में model.predict से पहले gc.collect() चलने पर मैं जांच करूंगा कि predTree मदद नहीं करता है।

एक तीसरा संभावित कारण भी है (शायद सबसे विश्वसनीय)। मुझे का हवाला देते Python FAQ on How does Python manage memory? करते हैं:

CPython की वर्तमान विज्ञप्ति में, पाश पहले से आवंटित संसाधन जारी करेंगे अंदर एक्स के लिए प्रत्येक नया असाइनमेंट।

आपके चुने हुए फ़ंक्शन में आप ठीक से ऐसा करते हैं - दोबारा pred_chunked पर असाइन करें।

संबंधित मुद्दे