ndarray의 원소별 연산과 브로드캐스팅

김상윤·2023년 2월 27일
0

Element-wise operation

import numpy as np

a = np.random.randomint(-5,5,(5,))
b = np.random.randomint(-5,5,(5,))

a+b -> element-wise addition

Numpy를 사용하여 좋은 점

  • For문을 사용하지 않고 원소별로 더해주는 것이 가능하다
    For 문이 프로그램 속도를 저하시키는 주요 원인
  • For 문을 분석하는데 에너지가 많이 소모된다 -> 남의 코드 읽기 힘들다...

__add__ , __sub__ ,__mul__ 모두 원소별 연산이다

심지어 True False도 element-wise로 가능하다
a > b ---> [False, False, True, False, True]
대신 조심할 것은 비교하는 두 변수가 Type이 맞아야한다.

Masking

Array의 원하는 부분만 남기거나 제거하는 기술을 마스킹이라고 한다.
이 기능은 maxpooling을 딥러닝에서 할때 자주 쓰이게 된다.

import numpy as np

a = np.arange(5)
mask = np.array([0, 1, 0, 1, 0])

a -> [0 1 2 3 4]
a*b -> [0 1 0 3 0]

Broadcasting

서로 다른 shape의 array를 서로 연산할 수 있게 해준다. 원래라면 연산이 불가능한 상황에서 shape을 자동으로 맞춰줌으로써 연산을 가능하게 하는 것이다. 연산이 안되는 것을 가능하도록 만들어줌으로써 매우 편리하지만 의도치 않은 버그를 만들수 있다.

  1. a.ndim = b.ndim
    조건 : 연산에 참여하는 array중 하나의 차원값 하나가 1이어야 함

import numpy as np

A = np.arange(9).reshape(3,3)
B = 10 * np.arange(3).reshape((-1,1))
C = A + B

print("A: {}/{}\n{}".format(A.ndim, A.shape, A)) 
A: 2/(3,3)
[[0 1 2]
[3 4 5]
[6 7 8]]
print("B: {}/{}\n{}".format(B.ndim, B.shape, B))
B: 2/(3,1)
[[0]
[10]
[20]]
print("A + B: {}/{}\n".format(A.ndim, C.shape, C))
A + B: 2/(3,3)
[[0 1 2]
[13 14 15]
[26 27 28]]

column이 a에 맞게 copy되어 shape을 맞춘 후 연산이 된다.

(3,1) + (1,3)은 (3,1)의 column이 (1,3)에 맞춰지고 (1,3)의 row가 (3,1)에 맞춰진다. 꼭 하나만 broadcasting 되는 것이 아니다.

import numpy as np

A = np.arange(18).reshape((2,3,3))
B = 10 * np.arange(6).reshape((2,1,3))
C = A + B

A
[[0 1 2]
[3 4 5]
[6 7 8]]

[[9 10 11]
[12 13 14]
[15 16 17]]

B
[[0 10 20]]			[[0 10 20] [0 10 20] [0 10 20]]
				-> 
[[30 40 50]]  		[[30 40 50] [30 40 50] [30 40 50]]
  1. a.ndim != b.ndim
import numpy as np

a = np.array(3) shape:()
u = np.arange(5) shape:(5,)

a*u : [0 3 6 9 12]

작은 차원이 큰 차원에 맞춰진다. 또한 오른쪽부터 차원값이 맞춰진다.

a: 3 -> [3 3 3 3]
b: [1 2 3 4]
a + b: [4 5 6 7]
a > b: [True True False False]

(3,2)와 (2,)을 연산하기 위해서는 1차원 벡터가 2차원 벡터의 안쪽 차원/ 오른쪽 차원과 맞아야만 연산이 가능하다. 따라서 (2,)이 row를 따라 3번 복사되어 (3,2)가 만들어진다. 따라서 (3,)과는 연산이 이루어지지 않는다.

(2,3,4)는 안쪽 차원인 (3,4)와 맞는 모양에만 broadcasting이 된다.
ex) (3,4), (4,)

Tip:
텐서를 오른쪽 정렬하게 되면 실수를 줄일 수 있게 된다

profile
AI 대학원 지망생

0개의 댓글