Ho un set di 2000 alberi di regressione randomizzati addestrati (da Regolatore forestale casuale di scikit learn con n_estimators=1
). Addestrando gli alberi in parallelo (50 core) su un set di dati di grandi dimensioni (~ 100000 * 700000 = 70 GB a 8 bit) utilizzando multiprocessing
e la memoria condivisa funziona come un incantesimo. Nota, non sto utilizzando il supporto multicore integrato di RF poiché sto facendo la selezione delle funzioni in anticipo.Scikit di comprensione impara i requisiti di memoria di Foresta casuale per la previsione
Il problema: durante il test di una matrice di grandi dimensioni (~ 20000 * 700000) in parallelo, ho sempre esaurito la memoria (ho accesso a un server con 500 GB di RAM).
La mia strategia è di avere la matrice di test in memoria e condividerla tra tutti i processi. Secondo uno statement by one of the developers il requisito di memoria per il test è 2 * n_jobs * sizeof (X), e nel mio caso un altro fattore di * 4 è rilevante, dal momento che le voci della matrice a 8 bit sono trasmesse a float32 internamente in RF.
dai numeri, Credo per la prova ho bisogno:
14GB per tenere la matrice di test in memoria + 50 (= n_jobs) * 20000 (N_SAMPLES) * 700 (= n_features) * 4 (upcasting galleggiare) * 2 byte = 14 GB + 5,6 GB = ~ 21 GB di memoria.
Tuttavia, si verificano sempre diverse centinaia di GB. Cosa mi manca qui? (sono sulla nuova versione di scikit-learn, in modo che i vecchi problemi di memoria dovrebbero essere appianate)
Un'osservazione:
esecuzione su un core solo l'utilizzo della memoria per i test oscilla tra 30 e 100 GB (come misurato da free
)
il mio codice:
#----------------
#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: un'altra osservazione: Quando suddivisione in blocchi i dati di test viene eseguito il programma s moothly con un utilizzo della memoria molto ridotto. Questo è quello che usavo per far funzionare il programma.
Codice frammento per la funzione di aggiornamento 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
Quanta memoria occupano gli alberi di regressione casuale addestrati a 2000? Vengono copiati per ciascuno dei 50 core? –
@ BrianO'Donnell intendi le dimensioni del modello? Non ho più accesso al modello, ma era di dimensioni decisamente gestibili. – Dahlai
Sì, la dimensione del modello. –