Scikit verstehen lernen Random Forest Speicherbedarf für die Vorhersage

8

Ich habe einen Satz von 2000 trainierten zufälligen Regressionsbäumen (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) mit multiprocessing und gemeinsamem Speicher funktioniert wie ein Zauber. Beachten Sie, dass ich die integrierte Multicore-Unterstützung von RF nicht verwende, da ich zuvor die Feature-Auswahl durchführe.

Das Problem: Wenn ich eine große Matrix (~ 20000 * 700000) parallel teste, habe ich immer keinen Speicher mehr (ich habe Zugriff auf einen Server mit 500 GB RAM).

Meine Strategie besteht darin, die Testmatrix im Speicher zu haben und sie unter allen Prozessen zu teilen. Laut einer Aussage eines der Entwickler der Speicherbedarf für das Testen ist 2 * n_jobs * sizeof (X), und in meinem Fall ist ein weiterer Faktor von * 4 relevant, da die 8-Bit-Matrixeinträge innerhalb von RF intern float32 sind.

Nach Zahlen, ich denke zum Testen brauche ich:
14GB, um die Testmatrix im Speicher zu halten + 50 (= n_jobs) * 20000 (n_samples) * 700 (= n_features) * 4 (Upcasting zu floaten) * 2 Bytes = 14 GB + 5.6 gb = ~ 21 GB Speicher.

Aber es geht immer um mehrere hundert GB. Was fehlt mir hier? (Ich bin auf der neuesten Version von scikit-learn, also sollten die alten Speicherprobleme ausgebügelt werden)

Eine Beobachtung:
Die Speicherauslastung eines einzelnen Kerns zum Testen schwankt zwischen 30 und 100 GB (gemessen in free )

Mein Code:

%Vor%

Bearbeiten: eine weitere Beobachtung: Beim Chunking der Testdaten läuft das Programm reibungslos mit stark reduzierter Speicherauslastung. Das habe ich benutzt, um das Programm laufen zu lassen.
Code-Snippet für die aktualisierte Funktion predTree :

%Vor%     
Dahlai 01.07.2016, 08:52
quelle

1 Antwort

0

Ich bin mir nicht sicher, ob das Speicherproblem nicht mit der Verwendung von itertools.izip in args = itertools.izip(models, features_idx) zusammenhängt, was die Erstellung von Kopien des Iterators zusammen mit seinen Argumenten über alle Threads hinweg auslösen könnte. Hast du versucht, einfach zip zu benutzen?

Eine andere Hypothese könnte eine ineffiziente Garbage Collection sein - nicht ausgelöst, wenn Sie sie benötigen. Ich würde prüfen, ob das Ausführen von gc.collect() vor model.predict in predTree nicht hilft.

Es gibt auch einen dritten möglichen Grund (wahrscheinlich der glaubwürdigste). Lassen Sie mich Python-FAQ zu Wie verwaltet Python den Speicher? :

nennen
  

In aktuellen Versionen von CPython wird jede neue Zuweisung zu x innerhalb der Schleife die zuvor zugewiesene Ressource freigeben.

In Ihrer Chunked-Funktion machen Sie genau das - weisen Sie sie wiederholt pred_chunked zu.

    
sophros 20.09.2017 21:15
quelle