2.1 선형 회귀와 자동 미분

유명곤·2026년 9월 12일

입력과 출력 사이의 관계를 데이터에서 찾으려면, 예측값을 만드는 모델과 그 예측이 얼마나 맞는지 평가할 기준이 필요하다. 선형 회귀를 통해 모델을 정하고, 손실을 계산하고, 매개변수를 갱신하는 학습의 기본 흐름을 살펴본다.

1. 선형 회귀는 어떤 관계를 표현하는가

선형 회귀(Linear Regression)는 입력과 출력의 관계를 매개변수에 대해 선형인 식으로 나타내고, 데이터에 맞도록 매개변수를 추정하는 방법이다. 여기서는 입력 변수가 하나인 단순 선형 회귀(Simple Linear Regression)를 다룬다.

입력 xx에 대한 예측값을 y^\hat{y}라고 하면 모델은 다음과 같다.

y^=H(x)=Wx+b\hat{y}=H(x)=Wx+b

H(x)H(x)는 예측에 사용하는 함수인 가설(Hypothesis)이다. 가중치(Weight) WW는 xx가 1만큼 증가할 때 예측값이 얼마나 변하는지를, 편향(Bias) bb는 x=0x=0일 때의 예측값을 나타낸다. 학습에서는 이 두 매개변수(Parameter)를 조정한다.

관측값 yy와 예측값 y^\hat{y}는 구분해야 한다. 모든 관측값이 하나의 직선 위에 놓이는 것은 아니므로, 학습의 목표는 선택한 기준에서 데이터를 가장 잘 설명하는 직선을 찾는 것이다.

2. 평균 제곱 오차로 예측을 평가하기

손실 함수(Loss Function)는 예측값과 관측값의 차이를 수치로 평가하는 함수이다. 이 글에서는 평균 제곱 오차(Mean Squared Error, MSE)를 사용한다.

데이터가 nn개이고 각 관측값에 대응하는 예측값이 y^i=Wxi+b\hat{y}_i=Wx_i+b라면, 평균 제곱 오차는 다음과 같다.

J(W,b)=1n∑i=1n(y^i−yi)2=1n∑i=1n(Wxi+b−yi)2J(W,b)=\frac{1}{n}\sum_{i=1}^{n}(\hat{y}_i-y_i)^2 =\frac{1}{n}\sum_{i=1}^{n}(Wx_i+b-y_i)^2

예측값과 관측값의 차이를 그대로 더하면 양수와 음수가 상쇄될 수 있다. 차이를 제곱하면 부호에 관계없이 오차가 반영되고, 큰 오차에는 더 큰 값이 부여된다. 그 합을 데이터 수로 나누어 관측값 하나당 평균적인 제곱 오차를 구한다.

따라서 J(W,b)J(W,b)는 항상 0 이상이며, 모든 예측값이 관측값과 같으면 0이다. 큰 오차에 더 민감하다는 성질 때문에 일부 관측값이 직선에서 크게 벗어나면 학습 결과에도 큰 영향을 줄 수 있다.

이제 학습의 목표를 J(W,b)J(W,b)를 작게 만드는 WW와 bb를 찾는 것으로 정할 수 있다. 이처럼 최적화하려는 함수를 목적 함수(Objective Function)라고 하며, 여기서는 MSE가 그 역할을 한다.

3. 경사 하강법으로 매개변수를 갱신하기

경사 하강법(Gradient Descent)은 현재 매개변수에서 목적 함수의 기울기를 구하고, 그 반대 방향으로 매개변수를 조금씩 이동시키는 최적화 방법이다.

먼저 손실을 WW와 bb에 대해 각각 미분하면 다음을 얻는다.

∂J∂W=2n∑i=1n(Wxi+b−yi)xi∂J∂b=2n∑i=1n(Wxi+b−yi)\begin{aligned} \frac{\partial J}{\partial W} &=\frac{2}{n}\sum_{i=1}^{n}(Wx_i+b-y_i)x_i \\ \frac{\partial J}{\partial b} &=\frac{2}{n}\sum_{i=1}^{n}(Wx_i+b-y_i) \end{aligned}

두 식의 차이는 xix_i가 곱해지는지에 있다. WW를 바꾸면 각 예측값이 xix_i에 비례해 변하지만, bb를 바꾸면 모든 예측값이 같은 크기만큼 변하기 때문이다.

이 미분값들을 모은 벡터를 그래디언트(Gradient)라고 한다. 각 성분은 해당 매개변수가 조금 증가할 때 손실이 얼마나 변하는지를 나타낸다. 예측 직선의 기울기 WW와 손실의 변화율 ∂J/∂W\partial J/\partial W는 서로 다른 값이다.

학습률(Learning Rate) α>0\alpha>0을 사용해 매개변수를 다음과 같이 갱신한다.

Wt+1=Wt−α∂J∂W(Wt,bt)bt+1=bt−α∂J∂b(Wt,bt)\begin{aligned} W_{t+1}&=W_t-\alpha\frac{\partial J}{\partial W}(W_t,b_t) \\ b_{t+1}&=b_t-\alpha\frac{\partial J}{\partial b}(W_t,b_t) \end{aligned}

두 미분값은 모두 갱신 전의 같은 매개변수 (Wt,bt)(W_t,b_t)에서 계산한다. 미분값이 양수이면 해당 매개변수를 줄이고, 음수이면 늘리는 방향으로 이동한다.

학습률은 이동 크기를 조절한다. 너무 작으면 학습이 느려지고, 너무 크면 손실이 오히려 증가하거나 발산할 수 있다. 따라서 경사 하강법을 사용한다는 사실만으로 매 단계의 손실 감소가 보장되지는 않는다.

이 글에서는 전체 훈련 데이터를 사용해 한 번의 기울기를 계산한다. PyTorch의 SGD 옵티마이저(Optimizer)를 사용하더라도, 입력한 데이터가 전체 훈련 데이터라면 이러한 전체 배치 갱신이 이루어진다.

4. 자동 미분은 학습에서 무엇을 담당하는가

자동 미분(Automatic Differentiation)은 계산을 구성하는 연산들의 미분을 연쇄법칙으로 연결해 미분값을 구하는 방법이다. PyTorch의 autograd는 순전파(Forward Pass)에서 미분에 필요한 연산 관계를 계산 그래프(Computational Graph)로 기록한다.

선형 회귀의 손실은 예측값을 거쳐 매개변수에 연결된다. 각 관측값이 WW의 미분값에 기여하는 양을 합치면 다음 관계가 된다.

∂J∂W=∑i=1n∂J∂y^i∂y^i∂W\frac{\partial J}{\partial W} =\sum_{i=1}^{n} \frac{\partial J}{\partial\hat{y}_i} \frac{\partial\hat{y}_i}{\partial W}

여기서 ∂J/∂y^i=2(y^i−yi)/n\partial J/\partial\hat{y}_i=2(\hat{y}_i-y_i)/n이고, ∂y^i/∂W=xi\partial\hat{y}_i/\partial W=x_i이다. 이를 연결하면 앞에서 구한 ∂J/∂W\partial J/\partial W와 같은 식이 된다. 자동 미분은 이 연결을 계산 그래프를 따라 수행하므로, 모델이 복잡해져도 각 매개변수의 미분식을 직접 작성할 필요가 없다.

PyTorch에서 직접 만든 매개변수 텐서의 requires_grad=True는 미분을 추적하도록 설정한다. 손실에서 backward()를 호출하면 역전파(Backward Pass)를 통해 기울기가 계산되고, 해당 매개변수의 .grad에 누적된다. 이 과정만으로 매개변수 값이 바뀌지는 않는다.

학습에서 각 동작의 역할은 다음과 같다.

동작역할
예측값과 손실 계산현재 매개변수로 예측을 만들고 손실을 구한다.
optimizer.zero_grad()이전에 저장된 기울기를 비운다.
loss.backward()현재 손실의 매개변수별 기울기를 계산한다.
optimizer.step()저장된 기울기와 최적화 규칙을 이용해 매개변수를 갱신한다.

backward()는 기존 기울기를 자동으로 덮어쓰지 않는다. 현재 손실의 기울기만 사용하려면 이전 값을 비워야 한다. zero_grad()가 초기화하는 것은 기울기이며, 학습한 WW와 bb는 유지된다.

5. 학습을 반복하고 결과를 확인하기

매개변수를 갱신한 뒤에는 새 값으로 예측과 손실을 다시 계산한다. 이 과정을 반복하며 데이터에 맞는 값을 찾는다. 전체 훈련 데이터가 학습에 한 번 사용된 주기를 에포크(Epoch)라고 한다. 전체 데이터를 한 번에 사용하는 현재 구성에서는 한 에포크에 한 번 갱신하지만, 데이터를 여러 묶음으로 나누면 한 에포크에 여러 번 갱신할 수 있다.

훈련 데이터셋(Training Dataset)은 매개변수를 학습하는 데 쓰고, 테스트 데이터셋(Test Dataset)은 학습에 사용하지 않은 데이터에서 예측 성능을 최종 평가하는 데 쓴다. 훈련 손실이 작다는 사실만으로 새로운 데이터에서도 예측이 정확하다고 판단할 수는 없다.

난수 시드(Random Seed)는 실험 조건을 맞출 때 사용한다. torch.manual_seed()는 PyTorch의 난수 생성기를 설정하지만, 서로 다른 버전·장치·환경에서 모든 결과가 같아지는 것을 보장하지는 않는다.

6. 한 번의 갱신으로 손실이 줄어드는 과정

앞의 과정을 확인하기 위해 다음과 같은 세 관측값을 사용한다.

입력 xx관측값 yy
01
13
25

초기값을 W0=0W_0=0, b0=0b_0=0으로 두면 모든 예측값은 0이다. 초기 손실은 다음과 같다.

J(0,0)=(0−1)2+(0−3)2+(0−5)23=353≈11.6667J(0,0)=\frac{(0-1)^2+(0-3)^2+(0-5)^2}{3} =\frac{35}{3}\approx11.6667

이 위치에서의 미분값을 계산하면 다음을 얻는다.

∂J∂W=23{(−1)⋅0+(−3)⋅1+(−5)⋅2}=−263∂J∂b=23{(−1)+(−3)+(−5)}=−6\begin{aligned} \frac{\partial J}{\partial W} &=\frac{2}{3}\{(-1)\cdot0+(-3)\cdot1+(-5)\cdot2\} =-\frac{26}{3} \\ \frac{\partial J}{\partial b} &=\frac{2}{3}\{(-1)+(-3)+(-5)\}=-6 \end{aligned}

두 값이 모두 음수이므로 WW와 bb는 증가하는 방향으로 갱신된다. 학습률을 α=0.1\alpha=0.1로 두면 다음과 같다.

W1=0−0.1(−263)=1315≈0.8667b1=0−0.1(−6)=0.6\begin{aligned} W_1&=0-0.1\left(-\frac{26}{3}\right)=\frac{13}{15}\approx0.8667 \\ b_1&=0-0.1(-6)=0.6 \end{aligned}

갱신한 매개변수로 다시 계산한 예측값은 다음과 같다. 표의 값은 소수 넷째 자리까지 표시했다.

입력 xx관측값 yy갱신 후 예측값
010.6000
131.4667
252.3333

새 MSE는 약 3.2074로, 초기의 11.6667보다 작다. 이 예시의 미분값·갱신값·손실은 PyTorch 자동 미분과 SGD의 한 번 갱신으로도 확인했다.

한 번의 갱신으로 학습이 끝난 것은 아니다. 이 데이터에서는 W=2W=2, b=1b=1일 때 세 관측값을 모두 정확히 예측해 손실이 0이 된다. 위 갱신은 그 해를 향한 첫 이동이며, 일반적인 데이터에서는 하나의 직선으로 오차를 모두 없앨 수 없을 수도 있다.

요약과 활용

  • 선형 회귀는 예측의 형태를 정하고, MSE는 그 예측을 평가할 기준을 제공한다.
  • 자동 미분은 손실의 매개변수별 기울기를 계산하고, 옵티마이저는 그 값을 이용해 매개변수를 갱신한다.
  • 기울기 초기화 → 역전파 → 매개변수 갱신을 구분해야 학습 루프의 각 동작을 이해할 수 있다.

이 구조는 신경망에서도 이어진다. 모델과 손실 함수가 달라져도, 현재 예측을 평가하고 기울기를 구해 매개변수를 갱신한다는 흐름은 같다. 학습이 예상대로 진행되지 않을 때는 예측과 손실, 기울기의 계산·누적 여부, 실제 갱신과 학습률을 나누어 확인할 수 있다.

참고자료

profile
Werde, der du bist!

0개의 댓글