[python] 모양 및 데이터 유형으로 배열을 할당 할 수 없습니다.

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

  1. 키보드에서 WindowsKey + X를 누른 다음 팝업 메뉴에서 시스템을 클릭합니다.
  2. 고급 시스템 설정을 탭하거나 클릭합니다. 관리자 암호를 입력하거나 선택을 확인하라는 메시지가 표시 될 수 있습니다.
  3. 고급 탭의 성능에서 설정을 탭하거나 클릭합니다.
  4. 고급 탭을 탭하거나 클릭 한 다음 가상 메모리에서 변경을 탭하거나 클릭합니다.
  5. 모든 드라이브의 페이징 파일 크기 자동 관리 확인란을 선택 취소합니다.
  6. 드라이브 [볼륨 레이블]에서 변경할 페이징 파일이있는 드라이브를 탭하거나 클릭합니다.
  7. 사용자 지정 크기를 탭하거나 클릭하고 초기 크기 (MB) 또는 최대 크기 (MB) 상자에 새 크기 (MB)를 입력하고 설정을 탭하거나 클릭 한 다음 확인을 탭하거나 클릭합니다.
  8. 시스템 재부팅

윈도우 10

  1. Windows 키 누르기
  2. 유형 SystemPropertiesAdvanced
  3. 관리자 권한으로 실행을 클릭하십시오.
  4. 성능에서 설정을 클릭합니다.
  5. 고급 탭을 선택하십시오.
  6. 변경 선택 …
  7. 모든 드라이브의 페이징 파일 크기 자동 관리를 선택 취소하십시오.
  8. 그런 다음 사용자 정의 크기를 선택하고 적절한 크기를 입력하십시오.
  9. 설정을 누른 다음 확인을 누른 다음 가상 메모리, 성능 옵션 및 시스템 속성 대화 상자를 종료합니다.
  10. 시스템 재부팅

참고 :이 예제에서는 ~ 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)


답변