지난 블로그에서는 계단 함수와 함께 활성화 함수에 대하여 알아보았습니다.
2023.08.18 - [Programming/Deep Learning] - [Python/DeepLearning] #3. 활성화 함수의 기본
이번 블로그에서는 차원의 수에 대하여 알아보도록 하겠습니다.
다차원 배열
차원수가 많아도 일단 배열은 숫자의 집합이라는 점이 가장 중요합니다!
Python을 활용한 차원 계산은 numpy 모듈을 이용하면 손쉽게 다차원 배열을 만들 수 있고, 계산할 수 있습니다.
먼저, 1차원 배열을 통해 여러 가지 배열 정보를 확인해 보겠습니다.
import numpy as np
A = np.array([1,2,3,4])
print("배열의 원소 : {}".format(A)) # [1,2,3,4] 출력
print("배열의 차원수 : {}".format(np.ndim(A))) # 1차원
print("배열의 모양 : {}".format(A.shape)) # (4,) 출력
다음은 2차원 배열 입니다.
# 2차원 배열
B = np.array([[1,2],[3,4],[5,6]])
print("배열의 원소 :\n{}".format(B))
# [[1 2]
# [3 4]
# [5 6]] 의 결과값 출력
print("배열의 차원수 : {}".format(np.ndim(B))) # 2차원
print("배열의 모양 : {}".format(B.shape)) # (3,2)
2차원 배열은 보통 행렬(matrix)라고 부르고, 가로 방향을 행(row), 세로 방향을 열(column)이라고 이야기합니다.
행렬의 내적 "행렬 곱"
2차원 배열인 행렬의 내적을 구하는 방법에 대해 알아보겠습니다. 예를 들어 2 x 2 행렬의 내적은 다음과 같이 구할 수 있습니다.
위의 수식처럼 행렬 내적은 왼쪽 행렬의 행(가로)과 오른쪽 행렬의 열(세로)을 원소별로 곱하고 그 값들을 더해서 계산합니다. 그리고 계산 결과가 새로운 다차원 배열의 원소가 되는 것이 확인됩니다. 파이썬에서의 변수 표기에서 행렬은 일반 변숫값(스칼라값 이라고도 합니다.)과는 다르게 대문자로 표기하는 것이 관례입니다.
A = np.array([[1,2],[3,4]])
print("행렬 A의 shape : {}".format(A.shape))
B = np.array([[5,6],[7,8]])
print("행렬 B의 shape : {}".format(B.shape))
위의 행렬에서 𝐴×𝐵 는 계산이 가능하다. WHY? A.shape [1]과 B.shape [0]이 같기 때문에 가능!
# numpy의 dot 함수를 이용해 행렬의 내적을 구할 수 있다
print("A X B = \n{}".format(np.dot(A, B)))
print("B X A = \n{}".format(np.dot(B ,A)))
여기서 중요한 점은 행렬의 내적은 교환법칙이 성립하지 않는다. (BUT 단위행렬 제외)
위와 같이 2 X 2 형태의 행렬을 곱하는 예를 확인해 보았습니다.
shape 가 다른 행렬끼리 곱할 수 있는데, 이때 주의 해야 할 것은 첫 번째 행렬(A)의 첫 번째 차원의 원소 수(열의 수)와 두 번째 행렬(B)의 0번째 차원의 원소 수(행의 수)가 같아야 한다는 점입니다.
그렇다면, double check를 위해 이번에는 원소 수가 일치하는 경우와,
A = np.array([[1, 2, 3],
[4, 5, 6]])
B = np.array([[1, 2],
[3, 4],
[5, 6]])
print("행렬 A의 shape : {}".format(A.shape))
print("행렬 B의 shape : {}".format(B.shape))
print(" A X B : \n{}\n".format( np.dot(A, B)))
print(" B X A : \n{}".format( np.dot(B, A)))
# 행렬 A의 1 번째 차원 원소 수 3,
# 행렬 B의 0 번째 차원 원소 수 3 => 행의 수가 같기 때문에 계산 가능!
다음처럼 원소 수가 일치하지 않을 때의 경우를 확인해 보도록 하겠습니다!
C = np.array([[1, 2],
[3, 4]])
print("행렬 C의 shape : {}".format(C.shape))
print("행렬 A의 shape : {}".format(A.shape))
print("A X C = \n{}".format(np.dot(A, C)))
# A의 1번째 차원의 원소 수가 3,
# C의 0번째 차원의 원소 수가 2 => #오류 계산 불가능!
이처럼, A X C의 계산에서 원소수가 맞지 않아서 계산이 되지 않고 오류가 나타나는 걸 볼 수 있습니다.
하지만! C X A의 형태의 계산은 가능합니다.
print(" C X A : \n{}".format(np.dot(C, A)))
# C의 1번째 원소수가 2,
# A의 0번째 원소수가 2 => 계산 가능!
다시 말해, 차원 수가 다른 경우의 계산도 가능합니다.
A = np.array([[1, 2],
[3, 4],
[5, 6]])
B = np.array([7, 8])
print("행렬 A의 shape : {}".format(A.shape))
print("행렬 B의 shape : {}".format(B.shape))
print(" A X B : \n{}".format(np.dot(A, B)))
# A와 B의 차원 수는 다르지만, 내적에서 대응되는 차원의 원소수가 같기 때문에 계산 가능
print(" B X A : \n{}".format(np.dot(B, A)))
즉, 뒤에 오는 행렬의 대응되는 차원의 원소의 수만 일치 시켜주면 상관 없다는 것을 알 수 있습니다!
원소의 수 == 행의 수를 잘 고려하여 다차원 계산을 하면 조금 더 쉬운 계산이 될 것 같습니다.
다음 블로그에서는 행렬과 신경망에 대하여 알아보도록 하겠습니다!
'Programming > Deep Learning' 카테고리의 다른 글
[Python/DeepLearning] #6. 출력층(output layer) 설계 (1) | 2023.10.11 |
---|---|
[Python/DeepLearning] #5. 행렬과 신경망 (0) | 2023.08.30 |
[Python/DeepLearning] #3. 활성화 함수의 기본 (0) | 2023.08.18 |
[Python/DeepLearning] #2. 퍼셉트론 (단층 & 다층) (0) | 2023.08.16 |
[Python/DeepLearning] #1. Numpy 기초 총 정리 (0) | 2023.06.20 |