2014-12-27 2 views
3

크기가 각각 2 개 (162225, 10000)와 (10000, 100) 인 numpy 배열의 내적을 계산하려고합니다. 그러나 numpy.dot (A, B)를 호출하면 MemoryError가 발생합니다. 난 후, 내 구현을 작성하는 시도 :numpy.dot -> MemoryError, my_dot -> 매우 느리지 만 작동합니다. 왜?

def slower_dot (A, B): 
    """Low-memory implementation of dot product""" 
    #Assuming A and B are of the right type and size 
    R = np.empty([A.shape[0], B.shape[1]]) 
    for i in range(A.shape[0]): 
     for j in range(B.shape[1]): 
      R[i,j] = np.dot(A[i,:], B[:,j]) 
    return R 

을하고 그냥 잘 작동하지만 물론 매우 느립니다. 1)이 행동의 배경은 무엇이고 2) 어떻게 문제를 회피/해결할 수 있습니까?

나는 16bit RAM이 장착 된 64bit 컴퓨터에 Python 3.4.2 (64bit)와 Numpy 1.9.1을 사용하고 있습니다.

+0

파이썬을 64 비트 버전으로 실행하고 있습니까? – filmor

+0

'np.einsum'을 시도해보십시오. 나는'np.dot'가 메모리 오류를 반환하거나 메모리 스와핑 (memory swapping)으로 다운되는 경우에 사용했습니다. – hpaulj

+0

예, 64 비트 버전입니다. – marcotama

답변

1

각 요소가 배정 밀도 부동 소수점 숫자 인 경우 16225 * 10000 크기의 매트릭스가 이미 약 12GB의 메모리를 차지하므로이 문제는 매트릭스 A 자체에서 시작한다고 생각합니다. numpy가 도트 작업을 수행하기 위해 임시 복사본을 만드는 방법과 함께 오류가 발생합니다. NumPy와 연속 된 C의 순서로 저장되는 행렬을 필요 점에 대한 기본 BLAS 작업을 사용하기 때문에 여분의 복사본입니다

체크 아웃이 링크를 당신이 점 성능을 향상시키는 방법에 대한 자세한 논의를 원하는 경우

http://wiki.scipy.org/PerformanceTips

Speeding up numpy.dot

https://github.com/numpy/numpy/pull/2730

+0

문제점을 발견했습니다. A는 uint8 유형이었고 B는 float64 유형이었습니다. 저는 믿습니다. np.dot가 A 사본을 만들었고, 여러분이 말한 것처럼 많은 공간이 필요했습니다. "솔루션"은 봇 A와 B가 float16을 입력하도록 강요하는 것이 었습니다. 제 목적에 충분히 적합해야합니다 - 아니면 적어도 그렇게되기를 바랍니다 :) – marcotama

2

NumPy와이 경찰에 노력하고 있기 때문에 당신은 메모리 오류를 얻고있는 이유는 아마도 y dot 호출 내 하나 또는 양쪽 배열. 중소 배열의 경우이 옵션이 가장 효율적인 옵션이지만 대용량 배열의 경우 메모리 오류를 방지하기 위해 numpy를 미세 관리해야합니다. slower_dot 함수는 파이썬 함수 호출 오버 헤드 때문에 느린 속도입니다. 162225 x 100 번 고통받습니다. 메모리 및 성능 제한의 균형을 유지하려는 경우 이러한 상황을 처리하는 일반적인 방법 중 하나가 있습니다.

import numpy as np 

def chunking_dot(big_matrix, small_matrix, chunk_size=100): 
    # Make a copy if the array is not already contiguous 
    small_matrix = np.ascontiguousarray(small_matrix) 
    R = np.empty((big_matrix.shape[0], small_matrix.shape[1])) 
    for i in range(0, R.shape[0], chunk_size): 
     end = i + chunk_size 
     R[i:end] = np.dot(big_matrix[i:end], small_matrix) 
    return R 

특정 배열 크기에 가장 적합한 chunk_size를 선택하는 것이 좋습니다. 일반적으로 큰 덩어리 크기는 모든 것이 메모리에 들어 맞는 한 더 빠릅니다.

+0

코드를 주셔서 감사합니다. 문제가 해결되지 않았지만 희망이 있습니다. 다른 사람들에게 도움이 될 것입니다. – marcotama

관련 문제