인공지능을 위한 수학 2: 미분·Gradient Descent·Backpropagation 연결하기

반응형

신경망 학습을 읽을 때 미분, gradient descent, backpropagation이 같은 뜻처럼 섞이기 쉽다. 세 개념의 역할은 다르다. 미분은 변화율을 표현하고, backpropagation은 chain rule로 gradient를 계산하며, optimizer는 그 gradient를 이용해 parameter를 갱신한다.

인공지능 수학 교재의 미분 단원과 필기를 펼쳐 둔 학습 사진
미분·Gradient Descent·Backpropagation을 공부하며 남긴 기록

한 문장씩 구분하면

  • 미분: 입력이 조금 변할 때 출력이 얼마나 변하는지 나타낸다.
  • gradient: 여러 변수에 대한 편미분을 한 벡터로 모은 것이다.
  • backpropagation: computation graph를 뒤에서부터 따라가며 chain rule로 gradient를 계산한다.
  • gradient descent: 계산된 gradient의 반대 방향으로 parameter를 이동시키는 최적화 방법이다.

‘오차를 뒤로 전달한다’는 표현만 외우면 계산과 갱신을 혼동하기 쉽다. 실제로 뒤로 전파되는 것은 각 연산에 대한 derivative 정보이고, weight update는 optimizer가 수행한다.

상미분·편미분·전미분

한 변수 함수 y=f(x)의 derivative는 x의 국소 변화에 대한 y의 변화율이다.

dy/dx = lim(h→0) [f(x+h) - f(x)] / h

다변수 함수 f(x, y)에서는 다른 변수를 고정하고 하나의 변수만 바꾼 편미분을 쓴다.

∂f/∂x, ∂f/∂y

gradient는 이 편미분을 모은 벡터다.

∇f = [∂f/∂x, ∂f/∂y]

전미분은 여러 입력이 함께 조금 변할 때 함수값의 1차 변화를 나타낸다.

df = (∂f/∂x)dx + (∂f/∂y)dy

변수가 다른 변수에 의존해 경로를 따라 변한다면 total derivative와 chain rule이 그 의존성을 포함한다. 따라서 ‘전미분은 변수가 서로 의존할 때만 쓴다’고 단정하기보다는, 모든 입력 변화가 결과에 미치는 1차 효과를 합친다고 이해하는 편이 정확하다.

Leibniz 표기와 Lagrange 표기

dy/dx는 어떤 변수에 대해 미분하는지가 선명하다. f'(x)는 한 변수 함수의 derivative를 간결하게 쓸 수 있다. 신경망처럼 변수가 많은 계산에서는 ∂L/∂w 표기가 loss L이 weight w에 얼마나 민감한지를 읽기에 유리하다.

표기법이 계산 규칙을 바꾸지는 않는다. 문맥에서 독립변수, 종속변수, scalar와 vector를 먼저 확인해야 한다.

Chain rule이 backpropagation이 되는 과정

다음처럼 계산이 이어진다고 하자.

z = wx + b
y = σ(z)
L = loss(y, target)

weight에 대한 loss의 gradient는 중간 연산의 derivative를 곱해 구한다.

∂L/∂w = (∂L/∂y) · (∂y/∂z) · (∂z/∂w)

backpropagation은 이 국소 derivative를 computation graph의 역방향으로 재사용하는 효율적인 계산 절차다. PyTorch의 autograd도 tensor 연산으로 graph를 만들고 backward()를 호출할 때 gradient를 누적한다. 반복 학습에서는 이전 gradient를 비우는 단계가 필요한 이유다.

Gradient Descent의 update 식

가장 기본적인 update는 다음과 같다.

θ ← θ - α∇J(θ)
  • θ: 모델 parameter
  • J(θ): 줄이려는 objective 또는 loss
  • ∇J(θ): 현재 위치의 gradient
  • α: learning rate

gradient는 가장 빠르게 증가하는 국소 방향이므로 최소화할 때는 반대 방향으로 움직인다. 다만 이 한 번의 방향이 전역 최솟값을 보장하지는 않는다. learning rate가 너무 크면 발산하거나 진동할 수 있고 너무 작으면 학습이 느리다. 실제 학습에서는 mini-batch gradient, momentum, Adam 같은 optimizer와 learning-rate schedule도 함께 본다.

선형회귀에서 직접 확인하기

예측값을 ŷ = wx + b, 한 관측값의 squared error를 L=(ŷ-y)²라고 하면 다음과 같다.

∂L/∂w = 2(ŷ-y)x
∂L/∂b = 2(ŷ-y)

이 식은 prediction error, 입력 x, weight gradient가 어떻게 연결되는지 보여 준다. 여러 관측값을 쓸 때는 loss를 합하거나 평균내고, 그 정의에 맞춰 gradient scale도 달라진다. 이어지는 선형회귀 학습노트에서는 least squares와 regularization을 함께 볼 수 있다.

활성화 함수의 derivative에서 볼 것

함수 derivative의 특징 학습 시 관찰할 점
sigmoid 출력이 0 또는 1에 가까우면 derivative가 작다 깊은 층에서 vanishing gradient가 심해질 수 있다
tanh 0 중심이지만 큰 절댓값에서는 포화된다 입력 분포와 초기화의 영향을 받는다
ReLU 양수 구간은 1, 음수 구간은 0 계속 음수인 unit은 update 신호를 잃을 수 있다

ReLU는 x=0에서 수학적으로 미분 가능하지 않다. 라이브러리는 이 지점의 subgradient 값을 구현 규칙으로 정한다. 한 점의 선택보다 실제로 activation과 gradient가 어떤 분포를 보이는지가 더 중요하다.

수치 미분으로 gradient를 점검하기

analytic gradient가 의심되면 작은 입력에서 centered finite difference와 비교할 수 있다.

f'(x) ≈ [f(x+h) - f(x-h)] / (2h)

h를 지나치게 크게 두면 근사 오차가 커지고, 지나치게 작게 두면 floating-point cancellation이 커질 수 있다. gradient check는 작은 deterministic 예제의 디버깅 도구이지 대규모 학습의 update 방식이 아니다.

자주 묻는 질문

Backpropagation과 Gradient Descent는 같은가

아니다. backpropagation은 gradient를 계산하는 방법이고 gradient descent는 그 값을 사용해 parameter를 바꾸는 최적화 방법이다.

편미분할 때 정말 다른 변수는 변하지 않는가

편미분의 정의에서는 다른 독립변수를 고정한다. 변수가 서로 의존하는 경로의 전체 변화가 필요하면 chain rule과 total derivative를 적용한다.

Loss가 줄지 않으면 무엇부터 볼까

입력과 target의 shape, loss 정의, gradient가 None인지, gradient scale, learning rate, parameter update 여부를 작은 batch에서 먼저 확인한다. 모델을 키우기 전에 한 단계의 forward와 backward 계산을 재현하는 편이 빠르다.

참고 자료

반응형
KEEP READING
카테고리 전체 보기 →

댓글