2016-06-01 3 views
0

포인트 쌍 사이의 거리 행렬로 생성 된 큰 (200000x200000) 행렬로 표시되는 네트워크의 기능 축소를 계산하는 데 문제가 있습니다. 신속 초과 가입하고 시스템 중단 갈기 CPU에서 실행Tensorflow 메모리 관리 - 청킹?

x = tf.constant(X[:,0], shape=[X.shape[0],1]) 
y = tf.constant(X[:,1], shape=[X.shape[0],1]) 
dx = x - tf.transpose(x) 
dy = y - tf.transpose(y) 
D = tf.sqrt(dx*dx + dy*dy) 
M = 0.1 * 5.0/tf.pow(4.0 + D, 1.5) 
res = tf.reduce_sum(betaM) 

메모리 (내 MBP에 16기가바이트)

최소한의 예는, 입력 직교 좌표 200000x2 NumPy와 배열하기 x. 아마도 tf는 D (및 M?) 전체를 메모리에 저장하려고 시도하고있을 것입니다.

C/C++로이 글을 쓰고 있다면 행렬 전체를 루프 처리하고 전체 행렬을 저장하지 않으므로 각 행을 합산하는 것이 좋습니다. GPU와 동등한 - (가상) 행렬을 세분화하고 청크 감소를 수행합니다.

tf가 메모리를 절약하면서 더 많은 청크와 같은 동작을 수행하는 속임수가 있습니까?

건배

크리스

EDIT :

메모리 문제를 대처하는 다른 방법은

tf.map_fn 사용 :

rowsums = tf.map_fn(lambda i: tf.reduce_sum(tf.sqrt(tf.reduce_sum(tf.pow(i - x,2),1))) , x) 
res = tf.reduce_sum(rowsums) 

따라서 만 rowsums가 저장된다 텐서이고, 전체 거리 행렬이 아닙니다. 그러나이 접근법은 CPU에서 잘 작동하지만 GPU에서 중단됩니다.

답변

1

여기에 실제로 필요한 것은 (아직 구현되지 않은) cwise fusion입니다. 지금은 2*sqrt(a+b)a+b에 대해 새 Tensor를 할당 한 다음 sqrt에 대해 새 텐서를 할당 한 다음 2*sqrt으로 또 다른 텐서를 할당합니다. 메모리가 메모리 할당 messages을 검사하여 어디로 PS, 당신은

당신은 점차적으로 많은 중간 텐서를 만들지 않고 일을 업데이트 할 변수와 assign_add를 사용하여 일 더 많은 메모리를 효율적으로 만들 수 (verbose logging 필요) 팔 수 있습니다. "모든 쌍 거리 (pairwise distances)"를 계산하기위한 다른 공식이 있습니다.이 형식으로 변환하기가 더 쉬울 수도 있습니다.

+0

안녕하세요 야로 슬라브, 메모리 사용량을 어떻게 추정 할 수 있습니까? 나는 D가 최대로 8 * 200000^2 ~ 300GB의 저장 공간을 필요로하고, 삼각형 행렬의 약 절반 (대각선을 무시함)이 필요합니다. 감사! –

+0

Doh, 나는 1000을 벗어났다. 그렇다. 기억에 남는 것은 불가능한 것처럼 보인다. TF가 훈련 중 데이터 세트를 취급하는 것과 동일한 방식으로 데이터를 처리 할 수 ​​있으며, 단지 청크로만로드합니다. 두 개의'SliceInputProducer' +'batch' 세트를 사용하여 청크를 생성하고, 이중 반복 루프를 사용하여 반복 할 수 있습니다. –

+0

더 자세히 설명하기 위해,'SliceInputProducer' +'batch' +'assign'을 사용하여 각 실행 호출 (run1)에서 변수'subset1'을 가리킨다면 각 실행 호출 (run2)에서 점들의 서브셋을 변수'subset2'에 저장하기 위해 별도의'SliceInputProducer' +'batch' +'assign'을 가질 수 있습니다. 당신은 외부 루프에서 run1을, 내부 루프에서 run2를 수행합니다. 마지막으로 당신은'subset1'과'subset2' 변수를 취하고 그것들 사이의 모든 쌍 방향 거리를 계산하고 합계에 추가하는 로직을 가지고 있습니다. 이것은 세 번째 실행 명령 (run3)입니다. –