이 모듈의 도달 목표

벡터와 행렬로 여러 값 계산하기

벡터의 원소별 계산과 내적, 행렬 곱의 shape 규칙을 사용해 여러 샘플의 가중합을 한 번에 계산합니다.

결과물 · 배치 가중합 계산기
약 4~6시간
  • 벡터의 원소별 연산과 내적 결과의 차이를 설명한다
  • 행렬의 전치가 shape와 축을 어떻게 바꾸는지 확인한다
  • 행렬 곱이 가능한 shape 조건과 결과 shape를 판단한다
  • 샘플 행렬과 가중치로 배치 가중합을 계산한다
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]
한 줄씩 보기
  1. 같은 길이의 두 벡터를 만듭니다.
  2. 같은 위치의 값끼리 더합니다.
  3. 같은 위치의 값끼리 곱합니다.
직접 값 바꾸기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
한 줄씩 보기
  1. 특성과 가중치를 같은 길이로 만듭니다.
  2. 원소별 곱은 벡터로 남습니다.
  3. 내적은 곱들을 더해 스칼라 하나를 만듭니다.
직접 값 바꾸기두 번째 가중치를 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]]
한 줄씩 보기
  1. 2개 샘플과 3개 특성의 행렬입니다.
  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]]
한 줄씩 보기
  1. a의 shape는 (2, 3)입니다.
  2. b의 shape는 (3, 2)입니다.
  3. 안쪽 크기 3이 같아 곱할 수 있습니다.
  4. 바깥 크기 (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())
실행 결과
(3,)
[2.5, 4.0, 5.5]
한 줄씩 보기
  1. 3개 샘플과 2개 특성을 준비합니다.
  2. 2개 특성에 대응하는 가중치입니다.
  3. 각 행의 내적에 편향 1을 더합니다.
  4. 샘플마다 점수 하나가 나옵니다.
직접 값 바꾸기편향을 0으로 바꾸면 모든 점수가 얼마나 변하는지 확인하세요.
흔한 실수가중치 길이는 샘플 수가 아니라 특성 수와 같아야 합니다.

짧은 확인shape (10, 4) 데이터에 곱할 가중치 벡터의 shape는 무엇이어야 할까요?

특성과 가중치 내적

  1. 특성과 가중치의 길이가 같은지 확인합니다.
  2. 같은 위치 원소끼리 곱합니다.
  3. 원소별 곱의 합을 내적으로 계산합니다.
  4. 음수가 포함된 사례도 확인합니다.
import numpy as np

features = np.array(input().split(), dtype=np.float64)
weights = np.array(input().split(), dtype=np.float64)
products = features * weights
score = np.dot(features, weights)
print(f'원소별 곱: {np.round(products, 2).tolist()}')
print(f'내적: {score:.2f}')

핵심을 확인해 볼까요?

5문항 중 4문항 이상 정답이면 완료됩니다. 오답 후에도 다시 제출할 수 있습니다.

1벡터 a * b의 NumPy 기본 동작은?
2[1, 2, 3]과 [2, 0, 1]의 내적은?
3shape (2, 5) 행렬을 전치한 shape는?
4계산 가능한 행렬 곱은?
5shape (8, 3) 데이터와 shape (3,) 가중치를 곱한 결과 shape는?