카테고리 없음
[Keras]2.3신경망의 톱니바퀴:텐서연산(2.3.2브로드 캐스팅)
ML.chang
2019. 1. 14. 23:04
앞서 살펴본 단순한 덧셈 구현인 naive_add는 동일한 크기의 2D텐서만 지원합니다.
하지만 이전에 보았던 Dense 층에서는 2D텐서와 벡터를 더했다. 크기가 다른 두 텐서가 더해질 때 무슨 일이 일어날까?
모호하지 않고 실행 가능하다면 작은 텐서가 큰 텐서의 크기에 맞추어 브로드캐스팅 된다.
두단계로 이루어 지는데
1. 큰 텐서의 ndim에 맞도록 작은 텐서에 축이 추가 된다.
2. 작은 텐서가 새 축을 따라서 큰 텐서의 크기에 맞도록 반복된다.
구체적인 예?
X의 크기는 (32,10)이고 Y의 크기는 (10,)라고 가정하자. 먼저 y에 비어있는 첫 번째 축을 추가하여 크기를 (1,10)으로 만든다. 그런 다음 y를 이 축에 32번 반복하면 텐서 Y의 크기는 (32,10)이 된다. 여기에서 Y[i,:] == y for i range(0.32)입니다. 이제 X와 Y의 크기가 같으므로 더할 수 있습니다. 구현 입장에서는 새로운 텐서가 만들어지면 매우 비효율적이므로 어떤 2D 텐서도 만들어지지 않습니다. 반복된 연산은 완전히 가상적입니다. 이 과정은 메모리 수준이 아니라 알고리즘 수준에서 일어납니다. 하지만 새로운 축을 따라 벡터가 32번 반복된다고 생각하는 것이 이해하기 쉽다.
def naive_add_matrix_and_vector(x,y):assert len(x.shape) == 2 ------------x는 2D 넘파이 배열입니다.assert x.shape == y.shapex = x.copy() ----------------입력 텐서 자체를 바꾸지 않도록 복사합니다.for i in range(x.shape[0]):for j in range(x.shape[1):x[i,j] += y[i,j]return x(a,b, ...n, n+1, ...m)크기의 텐서와(n, n+1, ....m) 크기의 텐서 사이에 브로드캐스팅으로 원소별 연산을적용할 수 있습니다. 이때 브로드캐스팅은 a 부터 n-1까지의 축에 자동으로 일어납니다.크기가 다른 두 텐서에 브로드캐스팅으로 원소별 maximum 연산을 적용하는 예입니다.import numpy as npx = np.random.random((64,3,32,10))y = np.random.random((32,10)) -------------y는 (32,10)크기의 랜덤 텐서입니다.z = np.maximum(x,y)출력 z크기는 x와 동일하게 (64,3,32,10)입니다.