LLM 엔지니어링2장 · 신경망과 딥러닝의 기본 원리4 / 23← 이전목차다음 →MetaContents

2장. 신경망과 딥러닝의 기본 원리

인공 뉴런

배송 기사가 지연을 가늠하는 머릿속 점수표를 떠올려 보세요. 거리 점수, 비 점수, 저녁 점수가 있고, 기사는 점수마다 중요도를 다르게 둡니다. 거리는 아주 중요하고, 저녁 주문은 조금 중요합니다. 점수에 중요도를 곱해 모두 더한 뒤, 합이 어느 문턱을 넘으면 "늦겠다"고 판단합니다. 인공 뉴런 하나가 하는 일이 정확히 이것입니다.

입력 셋에 가중치를 곱해 더하고 편향을 더한 뒤 활성화 함수를 지나 출력이 나오는 인공 뉴런 그림

왼쪽 상자가 입력, 주황 선 위의 마젠타 글자가 가중치, 가운데 원이 가중합, 청록 상자가 활성화 함수입니다. 여기서 점수가 입력, 중요도가 가중치, 문턱을 옮기는 값이 편향입니다. 아래 줄의 식처럼 0.8×2.0 + 1.0×1.5 + 0.0×0.7 에 편향 -1.0 을 더해 2.1 이 나오고, ReLU 를 지나도 양수라 2.1 이 그대로 나갑니다.

인공 뉴런은 무엇을 본뜬 것인가

이름의 "뉴런"은 뇌의 신경세포에서 왔습니다. 신경세포는 여러 가닥의 가지로 옆 세포들의 신호를 받습니다. 받은 신호가 충분히 쌓이면 자기도 신호를 내어 다음 세포에 전합니다. 약한 신호만 오면 아무것도 전하지 않습니다.

뇌의 신경세포와 인공 뉴런이 신호를 받아 넘기는 방식을 나란히 견준 그림

왼쪽 카드가 신경세포, 오른쪽 카드가 인공 뉴런입니다. 위 줄이 "받는 법", 아래 줄이 "넘기는 법"이니 같은 줄끼리 견주어 읽습니다. 여기서 여러 가닥의 신호가 입력이고, 신호마다 세기가 다른 것이 가중치이며, "충분히 쌓였나"를 가르는 선이 편향과 활성화 함수입니다. 다만 실제 신경세포는 훨씬 복잡하게 움직입니다. 인공 뉴런은 생김새만 빌린 곱셈과 덧셈일 뿐, 뇌를 흉내 내어 생각하는 것은 아닙니다.

인공 뉴런 하나가 하는 일을 한 문장으로 줄이면 "여러 값을 받아, 값마다 중요도를 곱해 더하고, 문턱을 넘은 만큼 다음으로 넘긴다" 입니다.

뉴런의 부품

부품하는 일점수표로 치면학습으로 바뀌나
입력들어오는 값거리 점수, 비 점수아니다(데이터)
가중치입력마다 곱하는 수점수마다의 중요도바뀐다
편향가중합에 더하는 수문턱을 옮기는 값바뀐다
활성화 함수다음으로 넘길 값을 정한다문턱을 넘었는지 보기아니다(고른다)

한 걸음씩 따라가기

그림의 뉴런이 주문 하나(먼 곳, 비 오는 날, 낮 주문)를 받아 답을 내기까지를 세 걸음으로 나눠 봅니다.

걸음하는 일계산결과
1. 곱하기입력마다 가중치를 곱한다0.8×2.0, 1.0×1.5, 0.0×0.71.6, 1.5, 0
2. 더하기곱한 값을 모두 더하고 편향을 더한다(가중합)1.6 + 1.5 + 0 + (-1.0)2.1
3. 넘기기가중합을 활성화 함수에 넣는다ReLU(2.1)2.1

저녁 점수는 0 이라 가중치 0.7 을 곱해도 0 입니다. 낮 주문이니 저녁이라는 이유는 이 주문의 답에 보태지 않는다는 뜻입니다. 출력 2.1 은 "늦을 기미가 이만큼 있다"는 세기로 읽습니다. 이 값이 확률이 되거나 예측 주문량이 되는 것은 뉴런을 여럿 쌓고 출력층을 정한 뒤의 일입니다.

코드로 계산하기

NumPy 로 그림의 뉴런을 그대로 계산해 봅니다.

Python
import numpy as np

x = np.array([0.8, 1.0, 0.0])    # 입력: 거리 점수, 비 점수, 저녁 점수
w = np.array([2.0, 1.5, 0.7])    # 가중치: 점수마다의 중요도
b = -1.0                         # 편향: 문턱을 옮기는 값

# 가중합: 입력과 가중치를 칸마다 곱해 모두 더하고 편향을 더한다
z = np.dot(x, w) + b
# 활성화 함수 ReLU: 음수면 0, 양수면 그대로
out = max(0.0, z)
print(round(z, 2), round(out, 2))

가중합 z 와 출력 out 이 모두 2.1 로 나옵니다. np.dot(x, w) 는 칸마다 곱해 더하는 계산으로, 신경망에서 가장 많이 하는 계산입니다.

np.dot 은 무엇을 하나

장바구니 계산을 떠올려 보세요. 사과 3개에 1,000원, 우유 2개에 1,500원이면 계산대에서는 품목마다 "개수 × 단가"를 구한 뒤 모두 더해 합계 하나를 냅니다. np.dot 이 하는 일이 이것입니다. 여기서 개수 목록이 입력 x, 단가 목록이 가중치 w, 영수증의 합계가 가중합입니다. dot 은 "점"이라는 뜻으로, 수학에서 이 계산을 점곱(내적)이라고 부르는 데서 온 이름입니다.

np.dot 이 같은 자리의 값끼리 짝지어 곱한 뒤 모두 더해 값 하나를 내는 흐름도

그림은 왼쪽에서 오른쪽으로 읽습니다. 같은 자리의 값끼리 짝을 짓고(0.8 과 2.0, 1.0 과 1.5, 0.0 과 0.7), 짝마다 곱한 뒤, 곱한 값을 모두 더해 숫자 하나 3.1 을 냅니다. 여기에 편향 -1.0 을 더한 것이 위 코드의 z 2.1 입니다.

쓰는 법하는 일위 예의 결과
x * w짝끼리 곱하기만 한다. 칸 수가 그대로 남는다[1.6 1.5 0. ]
(x * w).sum()곱한 뒤 모두 더한다3.1
np.dot(x, w)곱하고 더하기를 한 번에 한다3.1
x @ wnp.dot 과 같은 계산을 연산자로 쓴다3.1
Python
import numpy as np

x = np.array([0.8, 1.0, 0.0])    # 입력
w = np.array([2.0, 1.5, 0.7])    # 가중치

print(x * w)                     # 짝끼리 곱하기만 한 것: 칸 3개가 그대로 남는다
print((x * w).sum())             # 곱한 것을 모두 더한다
print(np.dot(x, w))              # 곱하고 더하기를 한 번에
print(x @ w)                     # @ 는 np.dot 과 같은 계산을 하는 연산자

실행하면 첫 줄은 [1.6 1.5 0. ] 이고, 나머지 세 줄은 모두 3.1 입니다. x * w 와 np.dot(x, w) 는 이름이 비슷해 헷갈리기 쉽습니다. 앞의 것은 칸이 여럿인 배열을, 뒤의 것은 숫자 하나를 냅니다.

주문이 여럿이면

입력이 2차원 표(주문 여러 건 × 특성 3개)이면 np.dot(표, w) 는 줄마다 점곱을 해서 주문 수만큼의 값을 돌려줍니다. 영수증 여러 장을 한꺼번에 계산하는 셈입니다. 아래 "가중치와 편향이 바꾸는 것" 소절의 orders @ w 가 이 계산입니다. 신경망의 층은 뉴런 여럿이 이 계산을 동시에 하는 것이라, 학습 시간 대부분이 점곱에 쓰입니다.

자주 나는 오류

  • 두 배열의 길이가 같아야 짝을 지을 수 있습니다. 입력이 3개인데 가중치가 2개면 ValueError: shapes (3,) and (2,) not aligned 오류가 납니다. 이 오류가 나면 특성 수와 가중치 수부터 맞춰 봅니다.
  • 2차원끼리 곱할 때는 앞 배열의 열 수와 뒤 배열의 행 수가 같아야 합니다. 순서를 바꾸면 결과가 달라지거나 오류가 납니다.

가중치와 편향이 바꾸는 것

같은 뉴런에 주문 넷을 넣어 봅니다. 가중치와 편향은 그대로 두고 입력만 바꿉니다.

Python
import numpy as np

w = np.array([2.0, 1.5, 0.7])    # 가중치: 거리, 비, 저녁의 중요도
b = -1.0                         # 편향

# 주문 넷: [거리 점수, 비 점수, 저녁 점수]
orders = np.array([
    [0.8, 1.0, 0.0],   # 먼 곳, 비 오는 날
    [0.8, 0.0, 0.0],   # 먼 곳, 맑은 날
    [0.2, 0.0, 1.0],   # 가까운 곳, 저녁 주문
    [0.2, 0.0, 0.0],   # 가까운 곳, 맑은 낮
])
# 행렬 곱 @ 으로 네 주문의 가중합을 한 번에 구한다
z = orders @ w + b
out = np.maximum(0, z)           # ReLU
print(z.round(2))
print(out.round(2))

실행하면 가중합은 2.1, 0.6, 0.1, -0.6 이고, 출력은 2.1, 0.6, 0.1, 0 입니다.

주문가중합출력읽는 법
먼 곳, 비2.12.1무거운 두 이유가 겹쳐 가장 세게 넘긴다
먼 곳, 맑음0.60.6비 점수 1.5 가 빠진 만큼 약해진다
가까운 곳, 저녁0.10.1저녁 점수 덕에 문턱을 겨우 넘는다
가까운 곳, 맑은 낮-0.60문턱을 넘지 못해 아무것도 넘기지 않는다

표에서 가중치와 편향이 하는 일이 보입니다.

  • 가중치가 클수록 그 입력이 결과를 크게 흔듭니다. 거리(2.0)가 저녁(0.7)보다 세 배쯤 무겁습니다. 가중치가 0 이면 그 입력을 무시하고, 음수면 그 입력이 클수록 결과를 깎습니다.
  • 편향은 문턱의 높이입니다. 편향 -1.0 은 "점수 합이 1 을 넘어야 넘긴다"는 뜻입니다. 편향을 -2.0 으로 내리면 문턱이 높아져 가중합이 모두 1 씩 작아집니다. 그러면 먼 곳 맑은 날(0.6 → -0.4)과 가까운 저녁 주문(0.1 → -0.9)도 0 이 됩니다.
  • ReLU 는 문턱 아래를 0 으로 지웁니다. 마지막 주문의 -0.6 이 0 이 된 것이 이것입니다.

학습은 무엇을 바꾸나

처음 일을 시작한 배송 기사는 거리와 날씨 가운데 무엇이 더 중요한지 모릅니다. 배송을 여러 번 하며 "비 오는 날 많이 늦었네" 하고 중요도를 고쳐 갑니다. 여기서 기사의 경험이 학습용 데이터이고, 고쳐 가는 중요도가 가중치와 편향입니다.

인공 뉴런도 같습니다. 사람이 2.0, 1.5 같은 값을 정해 주지 않습니다. 데이터를 보며 예측이 정답에 가까워지도록 가중치와 편향을 조금씩 고칩니다. 얼마나 틀렸는지 재는 법은 "손실 함수" 절에서, 어느 쪽으로 고칠지 정하는 법은 "경사하강법" 절에서 다룹니다.

주의할 점

  • 학습 전의 가중치와 편향은 아무 뜻 없는 작은 난수로 시작합니다. 그림의 2.0, 1.5 같은 값은 설명을 위해 정한 것입니다.
  • 뉴런 하나는 입력을 직선으로 더하는 것뿐이라 할 수 있는 일이 적습니다. 여럿을 층으로 쌓아야 힘이 생깁니다.
← 이전 절2장 · 딥러닝이란다음 절 →2장 · 활성화 함수