Ich habe eine Reihe von 2000 trainierten Random Regression Bäume (von scikit lernen Random Forest Regressor mit n_estimators=1
). Das parallele Trainieren der Bäume (50 Kerne) auf einem großen Datensatz (~ 100000 * 700000 = 70 GB @ 8-Bit) unter Verwendung von multiprocessing
und Shared Memory funktioniert wie ein Zauber. Beachten Sie, dass ich die integrierte Multicore-Unterstützung von RF nicht verwende, da ich die Feature-Auswahl vorher mache.verstehen scikit lernen Random Forest Speicheranforderung für die Vorhersage
Das Problem: Beim parallelen Testen einer großen Matrix (~ 20000 * 700000) habe ich immer keinen Speicher mehr (ich habe Zugriff auf einen Server mit 500 GB RAM).
Meine Strategie ist es, die Testmatrix im Speicher zu haben und sie unter allen Prozessen zu teilen. Laut einem statement by one of the developers ist die Speicheranforderung für das Testen 2 * n_jobs * sizeof (X), und in meinem Fall ist ein weiterer Faktor von * 4 relevant, da die 8bit-Matrixeinträge in RF intern float32 sind.
durch Zahlen, glaube ich für die Prüfung ich brauche:
14GB die Testmatrix im Speicher + 50 (= n_jobs) * 20000 (N_SAMPLES) * 700 (= n_features) * 4 (Upcasting zu schweben) zu halten * 2 Bytes = 14 GB + 5,6 GB = ~ 21 GB Speicher.
Dennoch explodiert es immer auf mehrere hundert GB. Was fehlt mir hier? (Ich bin auf der neuesten Version von Scikit-Learn, so dass die alten Speicherprobleme ausgebügelt werden sollen)
Eine Beobachtung:
nur auf einem Kern Laufspeichernutzung für den Test zwischen 30 und 100 GB (gemessen schwankt von free
)
Mein Code:
#----------------
#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)
Edit: eine andere Beobachtung: Wenn Chunking die Testdaten das Programm ausgeführt wird s moothly mit viel reduziertem Speicherverbrauch. Dies ist, was ich benutzt habe, um das Programm laufen zu lassen.
-Code-Schnipsel für die aktualisierte predTree
Funktion:
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
Wie viel Speicher nehmen Ihre 2000 trainierten Zufallsregressionsbäume? Werden sie für jeden der 50 Kerne kopiert? –
@ BrianO'Donnell meinst du die Größe des Modells? Ich habe keinen Zugriff mehr auf das Modell, aber es war definitiv überschaubar. – Dahlai
Ja, die Größe des Modells. –