벡터의 원소별 계산과 내적, 행렬 곱의 shape 규칙을 사용해 여러 샘플의 가중합을 한 번에 계산합니다.
결과물 · 배치 가중합 계산기
◷ 약 4~6시간
✓ 벡터의 원소별 연산과 내적 결과의 차이를 설명한다
✓ 행렬의 전치가 shape와 축을 어떻게 바꾸는지 확인한다
✓ 행렬 곱이 가능한 shape 조건과 결과 shape를 판단한다
✓ 샘플 행렬과 가중치로 배치 가중합을 계산한다
01 · 3~7분 개념 블록
01
벡터는 방향을 가진 숫자 묶음
벡터는 순서가 있는 숫자 배열입니다. AI에서는 한 샘플의 키·몸무게·나이처럼 여러 특성을 한 벡터로 표현합니다. 같은 shape의 벡터끼리는 위치별로 더하고 곱할 수 있습니다.
일상에서 보면한 사람의 여러 측정값을 정해진 순서의 한 줄 기록표에 적는 것과 같습니다.
import numpy as np
a = np.array([1, 2, 3])
b = np.array([10, 20, 30])
print((a + b).tolist())
print((a * b).tolist())
실행 결과
[11, 22, 33]
[10, 40, 90]
한 줄씩 보기
같은 길이의 두 벡터를 만듭니다.
같은 위치의 값끼리 더합니다.
같은 위치의 값끼리 곱합니다.
직접 값 바꾸기b 대신 숫자 2를 곱해 모든 원소가 어떻게 바뀌는지 확인하세요.
흔한 실수*는 행렬 곱이 아니라 같은 위치 원소끼리의 곱입니다.
짧은 확인길이 3인 두 벡터를 *로 곱하면 결과 원소는 몇 개일까요?
02
내적은 두 벡터를 하나의 가중합으로 줄인다
내적은 같은 위치의 값을 곱한 뒤 모두 더합니다. 특성 벡터와 가중치 벡터의 내적은 각 특성의 중요도를 반영한 하나의 점수가 됩니다.
일상에서 보면상품별 수량과 가격을 위치별로 곱한 뒤 모두 더해 총액을 구하는 것과 같습니다.
import numpy as np
features = np.array([2, 3, 4])
weights = np.array([0.5, 1.0, 1.5])
print(features * weights)
print(np.dot(features, weights))
실행 결과
[1. 3. 6.]
10.0
한 줄씩 보기
특성과 가중치를 같은 길이로 만듭니다.
원소별 곱은 벡터로 남습니다.
내적은 곱들을 더해 스칼라 하나를 만듭니다.
직접 값 바꾸기두 번째 가중치를 0으로 바꿔 해당 특성이 결과에 주는 영향을 확인하세요.
흔한 실수내적할 두 벡터의 길이가 다르면 shape가 맞지 않아 오류가 발생합니다.
짧은 확인[1, 2]와 [3, 4]의 내적은 얼마일까요?
03
행렬은 여러 벡터를 행과 열로 묶는다
행렬은 2차원 배열입니다. 데이터 행렬에서는 보통 각 행이 샘플, 각 열이 특성입니다. 전치 .T는 행과 열 축을 바꾸어 shape (samples, features)를 (features, samples)로 만듭니다.
일상에서 보면학생별 성적표를 과목별 성적표로 돌려 보는 것과 같습니다.
import numpy as np
data = np.array([[1, 2, 3], [4, 5, 6]])
print(data.shape)
print(data.T.shape)
print(data.T.tolist())
실행 결과
(2, 3)
(3, 2)
[[1, 4], [2, 5], [3, 6]]
한 줄씩 보기
2개 샘플과 3개 특성의 행렬입니다.
전치하면 두 축의 길이가 바뀝니다.
각 특성의 값들이 한 행에 모입니다.
직접 값 바꾸기data.T.T가 원래 data와 같은지 확인하세요.
흔한 실수전치는 값 자체를 정렬하지 않고 축과 위치 관계를 바꿉니다.
짧은 확인shape (4, 2) 행렬을 전치한 shape는 무엇일까요?
04
행렬 곱은 안쪽 shape가 같아야 한다
(m, n) @ (n, p)는 가능하며 결과는 (m, p)입니다. 첫 행렬의 열 수와 두 번째 행렬의 행 수가 같아야 각 행과 열의 내적을 계산할 수 있습니다.
일상에서 보면앞 부품의 출력 단자 수와 뒤 부품의 입력 단자 수가 같아야 연결할 수 있는 것과 같습니다.
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([[1, 0], [0, 1], [1, 1]])
result = a @ b
print(result.shape)
print(result.tolist())
실행 결과
(2, 2)
[[4, 5], [10, 11]]
한 줄씩 보기
a의 shape는 (2, 3)입니다.
b의 shape는 (3, 2)입니다.
안쪽 크기 3이 같아 곱할 수 있습니다.
바깥 크기 (2, 2)가 결과 shape입니다.
직접 값 바꾸기b를 전치하면 왜 a @ b.T가 실패하는지 shape로 설명해 보세요.
흔한 실수행렬 곱 @와 원소별 곱 *는 계산 규칙과 결과 shape가 다릅니다.
짧은 확인(5, 3) @ (3, 2)의 결과 shape는 무엇일까요?
05
행렬과 벡터의 곱은 배치 내적
샘플 행렬 (samples, features)에 가중치 벡터 (features,)를 곱하면 각 샘플 행과 가중치의 내적이 계산되어 (samples,) 점수 벡터가 됩니다. 반복문 없이 여러 샘플을 한 번에 처리합니다.
일상에서 보면같은 채점 기준표를 모든 학생 답안에 한 번에 적용해 학생별 총점을 만드는 것과 같습니다.
import numpy as np
data = np.array([[1, 10], [2, 20], [3, 30]])
weights = np.array([0.5, 0.1])
scores = data @ weights + 1
print(scores.shape)
print(scores.tolist())