지난 블로그에서는 계단 함수와 함께 활성화 함수에 대하여 알아보았습니다.
2023.08.18 - [Programming/Deep Learning] - [Python/DeepLearning] #3. 활성화 함수의 기본
[Python/DeepLearning] #3. 활성화 함수의 기본
앞서 퍼셉트론에 대하여 알아보며, 단층 & 다층 퍼셉트론에 대한 이야기를 나눠 보았습니다. 2023.08.16 - [Programming/Deep Learning] - [Python/DeepLearning] #2. 퍼셉트론 (단층 & ) [Python/DeepLearning] #2. 퍼셉트론
yuja-k.tistory.com
이번 블로그에서는 차원의 수에 대하여 알아보도록 하겠습니다.
다차원 배열
차원수가 많아도 일단 배열은 숫자의 집합이라는 점이 가장 중요합니다!
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 |