2022.06.23 - [Studying/Machine Learning] - [머신러닝] 파이썬 Numpy - Numpy의 유용한 기능들
저번 포스팅까지는 사실 numpy연산을 하기 위한 전처리라고 생각해도 무방하다고 생각한다.
이번 포스팅에서는 실제로 머신러닝의 모델쪽에 사용되는 행렬연산을 정리해보겠다.
Transpose
transpose는 행렬의 축을 바꾸는 연산이다.
예제를 통해 살펴보겠다.
a = np.arange(10).reshape(2, -1)
print(a, a.shape)
# (array([[0, 1, 2, 3, 4],
# [5, 6, 7, 8, 9]]), (2, 5))
a = np.transpose(a, (1, 0))
print(a, a.shape)
# (array([[0, 5],
# [1, 6],
# [2, 7],
# [3, 8],
# [4, 9]]), (5, 2))
print(a.T)
# array([[0, 1, 2, 3, 4],
# [5, 6, 7, 8, 9]])
위 예제와 같이 행렬의 축을 바꾸는 것이다.
T로 줄여서 써도 똑같이 동작한다.
위의 예제는 2D array 였고 3D array에서는 어떻게 동작하는지 예제를 통해 확인해보자
a = np.arange(24).reshape(2, 3, 4)
print(a, a.shape)
# (array([[[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]],
# [[12, 13, 14, 15],
# [16, 17, 18, 19],
# [20, 21, 22, 23]]]), (2, 3, 4))
b = np.transpose(a, (2,1,0))
print((b, b.shape))
# (array([[[ 0, 12],
# [ 4, 16],
# [ 8, 20]],
# [[ 1, 13],
# [ 5, 17],
# [ 9, 21]],
# [[ 2, 14],
# [ 6, 18],
# [10, 22]],
# [[ 3, 15],
# [ 7, 19],
# [11, 23]]]), (4, 3, 2))
b = np.transpose(a, (2,1,0)) 이 부분에서 뒤의 (2,1,0)은 각각 a의 축을 매핑한 것이다.
b의 0, 1, 2번째 축이 각각 a의 2번째축, a의 1번째 축, a의 0번째 축으로 매핑된다.
3차원일때 default값이 (2,1,0)이다.
4차원일때는 default가 (3,2,1,0) 이런식으로 된다.
이렇게 transpose로 축을 다양하게 변환할 수 있다.
Dot product
Dot product는 두 배열의 내적 곱이다. 행렬연산을 생각하면 쉽게 이해할 수 있다.
a = np.array([1,2])
print(a.shape)
# (2,)
b = np.array([3,4])
print(b.shape)
# (2,)
np.dot(a, b)
# 11
행렬연산과 같이 dot(a,b)는 a의 마지막 축과 b의 끝에서 두번째 축과 내적으로 계산된다.
3D array의 예를 들어보겠다.
a = np.ones((4,3, 2))
b = np.ones((3,2, 1))
print(np.dot(a,b).shape)
# (4, 3, 3, 1)
이렇게 연산이 된다.
이해가 되지 않는다면 여러 shape를 만들어 연산해보면서 이해를 하고 넘어가는 걸 추천한다.
Matrix multiplication
Matmul은 numpy에서 가장 자주 사용되는 연산이라고 볼 수 있다.
이전의 dot product가 고차원으로 확장된 것이고 dot product가 여러번 실행되는 것으로 생각할 수 있다.
하지만 3D 이상의 dimension에서 두 연산은 다르다.
a와 b의 shape가 각각 (a1, a2, a3), (b1, b2, b3)일 때
Matmul의 경우는 뒤의 두 축을 matmul하는 것으로 생각할 수 있다.
a1,b1이 같아야 하고 a3,b2가 같아야 한다.
결과의 shape는 (a1,a2,b3)가 된다.
dot의 경우는 a의 마지막 축과 b의 마지막에서 두번째 축을 곱한 후 더한다.
a3, b2가 같아야 한다.
결과의 shape는 (a1,a2,b1,b3)가 된다.
실제로 사용될 만한 예제로 확인해보겠다.
batch = np.ones((3, 32))
weight = np.ones((32, 10))
bias = np.ones((1, 10))
print(batch @ weight + bias) # np.matmul(batch, weight) + bias와 같다.
# array([[33., 33., 33., 33., 33., 33., 33., 33., 33., 33.],
# [33., 33., 33., 33., 33., 33., 33., 33., 33., 33.],
# [33., 33., 33., 33., 33., 33., 33., 33., 33., 33.]])
print((batch @ weight + bias).shape)
# (3, 10)
위와 같이 아주 유용하게 사용할 수 있다.
보통 matmul로 쓰기보다는 @로 쓰인다.
그냥 리스트를 돌며 검색해도 될 듯하지만
직접 테스트를 해본 결과 numpy의 연산을 사용하는 것이
리스트를 for문으로 돌면서 연산하는 것 보다 약 900배가 빠르다
여기까지 머신러닝을 할 때 많이 사용되는 numpy모듈에 대해 알아보았다.
다음 포스팅부터는 linear regression처럼 실제로 사용되는 기능들을 구현하고 정리해보려고 한다.
'Studying > Machine Learning' 카테고리의 다른 글
[머신러닝] Linear Regression - 지구 온도 변화 분석 (0) | 2022.07.05 |
---|---|
[머신러닝] Linear regression(선형 회귀) 구현 (0) | 2022.07.05 |
[머신러닝] 파이썬 Numpy - Numpy의 유용한 기능들 (0) | 2022.06.23 |
[머신러닝] 파이썬 Numpy - Numpy indexing과 slicing (0) | 2022.06.21 |
[머신러닝] 파이썬 Numpy - Numpy 모듈의 수학적 기능들 (0) | 2022.06.20 |
댓글