Ich habe ein Problem mit der Zuweisung großer Arrays in numpy unter Ubuntu 18, während ich unter MacOS nicht mit demselben Problem konfrontiert bin.
Ich versuche, Speicher für ein numpy Array mit Form (156816, 36, 53806)
mit zuzuweisen
np.zeros((156816, 36, 53806), dtype='uint8')
und während ich einen Fehler unter Ubuntu OS bekomme
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
numpy.core._exceptions.MemoryError: Unable to allocate array with shape (156816, 36, 53806) and data type uint8
Ich bekomme es nicht unter MacOS:
>>> import numpy as np
>>> np.zeros((156816, 36, 53806), dtype='uint8')
array([[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
...,
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]],
[[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]]], dtype=uint8)
Ich habe irgendwo gelesen, dass np.zeros
nicht wirklich der gesamte für das Array benötigte Speicher zugewiesen werden sollte, sondern nur für die Nicht-Null-Elemente. Obwohl der Ubuntu-Computer 64 GB Speicher hat, hat mein MacBook Pro nur 16 GB.
Versionen:
Ubuntu
os -> ubuntu mate 18
python -> 3.6.8
numpy -> 1.17.0
mac
os -> 10.14.6
python -> 3.6.4
numpy -> 1.17.0
PS: Auch bei Google Colab fehlgeschlagen
python
numpy
data-science
Martin Brisiak
quelle
quelle
top
undfree -m
diese Befehle waren 60 GB Mem frei und mehrnp.zeros
erstellt keinesparse
Matrix. Es kann zu Verzögerungen beim Ausfüllen der Nullen kommen. Aber siehe stackoverflow.com/q/27464039Antworten:
Dies ist wahrscheinlich auf den Überlastungsmodus Ihres Systems zurückzuführen .
Im Standardmodus
0
,Die genaue verwendete Heuristik wird hier nicht gut erklärt, aber dies wird mehr unter Linux über Commit-Heuristik und auf dieser Seite diskutiert .
Sie können Ihren aktuellen Overcommit-Modus überprüfen, indem Sie ausführen
$ cat /proc/sys/vm/overcommit_memory 0
In diesem Fall weisen Sie zu
>>> 156816 * 36 * 53806 / 1024.0**3 282.8939827680588
~ 282 GB, und der Kernel sagt offensichtlich, dass ich auf keinen Fall so viele physische Seiten dafür festlegen kann, und er lehnt die Zuweisung ab.
Wenn Sie (als Root) ausführen:
$ echo 1 > /proc/sys/vm/overcommit_memory
Dadurch wird der Modus "Immer überbeanspruchen" aktiviert, und Sie werden feststellen, dass das System es Ihnen tatsächlich ermöglicht, die Zuordnung unabhängig von ihrer Größe vorzunehmen (mindestens innerhalb der 64-Bit-Speicheradressierung).
Ich habe dies selbst auf einem Computer mit 32 GB RAM getestet. Im Overcommit-Modus habe
0
ich auch einen bekommenMemoryError
, aber nachdem ich ihn wieder geändert1
habe, funktioniert er:>>> import numpy as np >>> a = np.zeros((156816, 36, 53806), dtype='uint8') >>> a.nbytes 303755101056
Sie können dann an eine beliebige Stelle innerhalb des Arrays schreiben, und das System weist physische Seiten nur zu, wenn Sie explizit auf diese Seite schreiben. Sie können dies also mit Vorsicht für spärliche Arrays verwenden.
quelle
/proc/sys
Einstellungen in Ihrer Distribution am besten beibehalten können.Ich hatte das gleiche Problem bei Windows und bin auf diese Lösung gestoßen. Wenn also jemand unter Windows auf dieses Problem stößt , besteht die Lösung für mich darin, die Auslagerungsdatei zu vergrößern, da dies auch für mich ein Problem mit einer Überlastung des Speichers war.
Windows 8
Windows 10
Hinweis: Ich hatte in diesem Beispiel nicht genügend Speicher auf meinem System für die ~ 282 GB, aber für meinen speziellen Fall hat dies funktioniert.
BEARBEITEN
Von hier aus die empfohlenen Empfehlungen für die Größe der Auslagerungsdatei:
Einige Dinge, die Sie von hier aus beachten sollten :
Ebenfalls:
quelle
Ich bin auch unter Windows auf dieses Problem gestoßen. Die Lösung für mich war, von einer 32-Bit- auf eine 64-Bit-Version von Python zu wechseln . In der Tat kann eine 32-Bit-Software wie eine 32-Bit-CPU maximal 4 GB RAM (2 ^ 32) adressieren. Wenn Sie also mehr als 4 GB RAM haben, kann eine 32-Bit-Version dies nicht nutzen.
Mit einer 64-Bit-Version von Python (die auf der Download-Seite mit x86-64 bezeichnete ) verschwand das Problem.
Sie können überprüfen, welche Version Sie haben, indem Sie den Interpreter eingeben. Ich habe jetzt mit einer 64-Bit-Version :
Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
, wobei [MSC v.1916 64-Bit (AMD64)] "64-Bit-Python" bedeutet.Hinweis : Zum Zeitpunkt dieses Schreibens (Mai 2020) ist matplotlibauf python39 nicht verfügbar. Ich empfehle daher, python37 mit 64 Bit zu installieren.
Quellen:
Quora - Speicherfehler, der durch ein großes numpy-Array generiert wird
Stackoverflow: 32- oder 64-Bit-Version von Python
quelle
In meinem Fall wurde durch Hinzufügen eines dtype-Attributs der dtype des Arrays in einen kleineren Typ geändert (von float64 auf uint8), wodurch die Arraygröße so weit verringert wurde, dass MemoryError in Windows (64 Bit) nicht ausgelöst wurde.
von
zu
mask = np.zeros(edges.shape,dtype='uint8')
quelle
Manchmal tritt dieser Fehler auf, weil der Kernel sein Limit erreicht hat. Versuchen Sie, den Kernel neu zu starten, und wiederholen Sie die erforderlichen Schritte.
quelle
Ändern Sie den Datentyp in einen anderen, der weniger Speicher benötigt. Für mich ändere ich den Datentyp in numpy.uint8:
data['label'] = data['label'].astype(np.uint8)
quelle