MacOS에서 동일한 문제가 발생하지 않는 동안 Ubuntu 18에서 numpy에 거대한 배열을 할당하는 데 문제가 있습니다.
모양 (156816, 36, 53806)
이 있는 numpy 배열에 메모리를 할당하려고합니다.
np.zeros((156816, 36, 53806), dtype='uint8')
Ubuntu OS에서 오류가 발생하는 동안
>>> 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
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)
np.zeros
배열에 필요한 전체 메모리를 실제로 할당해서는 안되는 어딘가에서 읽었 지만 0이 아닌 요소에만 해당됩니다. Ubuntu 컴퓨터에는 64GB의 메모리가 있지만 MacBook Pro에는 16GB 만 있습니다.
버전 :
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
추신 : Google Colab에서도 실패했습니다.
답변
이는 시스템의 오버 커밋 처리 모드 때문일 수 있습니다 .
기본 모드에서는 0
,
휴리스틱 오버 커밋 처리. 주소 공간의 명백한 오버 커밋은 거부됩니다. 일반적인 시스템에 사용됩니다. 이는 스왑 사용량을 줄이기 위해 오버 커밋을 허용하면서 심각한 와일드 할당 실패를 보장합니다. 루트는이 모드에서 약간 더 많은 메모리를 할당 할 수 있습니다. 이것이 기본값입니다.
사용되는 정확한 추론이 잘되지 않습니다 여기에서 설명하지만,이 더에 대한 설명 리눅스 이상 발견 커밋 과 이 페이지에 .
다음을 실행하여 현재 오버 커밋 모드를 확인할 수 있습니다.
$ cat /proc/sys/vm/overcommit_memory
0
이 경우에는
>>> 156816 * 36 * 53806 / 1024.0**3
282.8939827680588
~ 282GB이며 커널은 분명히 많은 물리적 페이지를 여기에 커밋 할 수있는 방법이 없으며 할당을 거부합니다.
(루트로) 실행하는 경우 :
$ echo 1 > /proc/sys/vm/overcommit_memory
이렇게하면 “항상 오버 커밋”모드가 활성화되고 실제로 시스템은 크기에 관계없이 할당을 수행 할 수 있습니다 (적어도 64 비트 메모리 주소 지정 내에서).
32GB RAM이 장착 된 컴퓨터에서 직접 테스트했습니다. overcommit 모드를 사용하면 0
을 얻었 MemoryError
지만 다시 변경 1
하면 작동합니다.
>>> import numpy as np
>>> a = np.zeros((156816, 36, 53806), dtype='uint8')
>>> a.nbytes
303755101056
그런 다음 계속 진행하여 어레이 내의 임의의 위치에 쓸 수 있으며 시스템은 해당 페이지에 명시 적으로 쓸 때만 물리적 페이지를 할당합니다. 따라서 희소 배열에주의해서 사용할 수 있습니다.
답변
나는 Window에서 이와 동일한 문제가 있었고이 솔루션을 발견했습니다. 따라서 누군가가 Windows 에서이 문제를 발견하면 나에게도 메모리 초과 할당 문제이기 때문에 페이지 파일 크기 를 늘리는 것이 해결책이었습니다 .
윈도우 8
- 키보드에서 WindowsKey + X를 누른 다음 팝업 메뉴에서 시스템을 클릭합니다.
- 고급 시스템 설정을 탭하거나 클릭합니다. 관리자 암호를 입력하거나 선택을 확인하라는 메시지가 표시 될 수 있습니다.
- 고급 탭의 성능에서 설정을 탭하거나 클릭합니다.
- 고급 탭을 탭하거나 클릭 한 다음 가상 메모리에서 변경을 탭하거나 클릭합니다.
- 모든 드라이브의 페이징 파일 크기 자동 관리 확인란을 선택 취소합니다.
- 드라이브 [볼륨 레이블]에서 변경할 페이징 파일이있는 드라이브를 탭하거나 클릭합니다.
- 사용자 지정 크기를 탭하거나 클릭하고 초기 크기 (MB) 또는 최대 크기 (MB) 상자에 새 크기 (MB)를 입력하고 설정을 탭하거나 클릭 한 다음 확인을 탭하거나 클릭합니다.
- 시스템 재부팅
윈도우 10
- Windows 키 누르기
- 유형 SystemPropertiesAdvanced
- 관리자 권한으로 실행을 클릭하십시오.
- 성능에서 설정을 클릭합니다.
- 고급 탭을 선택하십시오.
- 변경 선택 …
- 모든 드라이브의 페이징 파일 크기 자동 관리를 선택 취소하십시오.
- 그런 다음 사용자 정의 크기를 선택하고 적절한 크기를 입력하십시오.
- 설정을 누른 다음 확인을 누른 다음 가상 메모리, 성능 옵션 및 시스템 속성 대화 상자를 종료합니다.
- 시스템 재부팅
참고 :이 예제에서는 ~ 282GB에 대해 시스템에 충분한 메모리가 없었지만 특정 경우에는 작동했습니다.
편집하다
에서 여기 페이지 파일 크기에 대한 권장 사항을 제안 :
올바른 페이지 파일 크기를 계산하는 공식이 있습니다. 초기 크기는 1.5 x 전체 시스템 메모리 양입니다. 최대 크기는 초기 크기의 3 배입니다. 따라서 4GB (1GB = 1,024MB x 4 = 4,096MB)의 메모리가 있다고 가정 해 보겠습니다. 초기 크기는 1.5 x 4,096 = 6,144MB이고 최대 크기는 3 x 6,144 = 18,432MB입니다.
그러나 이것은 컴퓨터에 고유 할 수있는 다른 중요한 요소 및 시스템 설정을 고려하지 않습니다. 다시 말하지만, Windows가 다른 컴퓨터에서 작동하는 임의의 공식에 의존하는 대신 사용할 것을 선택하도록합니다.
또한:
페이지 파일 크기를 늘리면 Windows에서 불안정성과 충돌을 방지하는 데 도움이 될 수 있습니다. 그러나 하드 드라이브 읽기 / 쓰기 시간은 데이터가 컴퓨터 메모리에있을 때보 다 훨씬 느립니다. 더 큰 페이지 파일이 있으면 하드 드라이브에 추가 작업이 추가되어 다른 모든 작업이 느려집니다. 페이지 파일 크기는 메모리 부족 오류가 발생한 경우에만 일시적으로 수정해야합니다. 더 나은 해결책은 컴퓨터에 더 많은 메모리를 추가하는 것입니다.
답변
나는 Windows 에서도이 문제를 발견했습니다. 나를위한 해결책 은 32 비트에서 64 비트 버전의 Python 으로 전환 하는 것이 었습니다 . 실제로 32 비트 CPU와 같은 32 비트 소프트웨어는 최대 4GB 의 RAM (2 ^ 32)을 처리 할 수 있습니다. 따라서 4GB 이상의 RAM이있는 경우 32 비트 버전은이를 활용할 수 없습니다.
64 비트 버전의 Python ( 다운로드 페이지에서 x86-64 로 표시된 버전 )에서는 문제가 사라졌습니다.
통역사를 입력하여 사용중인 버전을 확인할 수 있습니다. I, 64 비트 버전에서는 이제 다음이 있습니다.
Python 3.7.5rc1 (tags/v3.7.5rc1:4082f600a5, Oct 1 2019, 20:28:14) [MSC v.1916 64 bit (AMD64)]
여기서 [MSC v.1916 64 비트 (AMD64)]는 “64 비트 Python”을 의미합니다.
참고 :이 글을 쓰는 시점 (2020 년 5 월) 현재 matplotlib는python39에서 사용할 수 없으므로 python37, 64 비트 설치를 권장합니다.
출처 :
답변
필자의 경우 dtype 속성을 추가하면 배열의 dtype이 더 작은 유형 (float64에서 uint8으로)으로 변경되어 Windows (64 비트)에서 MemoryError를 발생시키지 않을만큼 배열 크기를 줄였습니다.
…에서
mask = np.zeros(edges.shape)
…에
mask = np.zeros(edges.shape,dtype='uint8')
답변
때로는 커널이 한계에 도달했기 때문에이 오류가 나타납니다. 커널을 다시 시작하여 필요한 단계를 다시 실행하십시오.
답변
데이터 유형을 더 적은 메모리 작업을 사용하는 다른 유형으로 변경하십시오. 나를 위해 데이터 유형을 numpy.uint8로 변경합니다.
data['label'] = data['label'].astype(np.uint8)