2 minute read


지훈이는 오늘도 싱글벙글 게임을 켰다. 슬라임을 1시간 동안 사냥을 하면 30원을 번다. 2시간을 사냥하면 60원을, 3시간을 사냥하면 90원을 벌 수 있다. 이로부터 지훈이는 4시간 동안 사냥했을 때 얼마나 벌 수 있을까를 예측할 수 있다.

Hours ($x$) Money ($y$)
1 30
2 60
3 90
4 ?


모델을 학습시킬 때 우리는 기존에 알고 있는 데이터를 사용한다. 위 표에서 1시간, 2시간, 3시간 사냥 시 얻을 수 있는 금액을 나타낸 데이터를 Training dataset, 학습이 끝난 후 모델이 잘 작동하는지 확인하기 위해 집어넣는 데이터를 Test dataset이라고 한다.



1.1.1 Linear Regression

모델 학습을 위한 데이터는 torch.tensor 데이터 타입을 사용한다. 입력은 x, 출력은 y로 표기한다.

\[X_{train} = \begin{bmatrix} 1 \\ 2 \\ 3 \end{bmatrix} \qquad Y_{train} = \begin{bmatrix} 30 \\ 60 \\ 90 \end{bmatrix}\]


모델은 다음과 같이 가정하자. Linear regression은 학습 데이터와 가장 유사한 직선을 찾는 것이므로,

\[y = Wx + b\]

여기서 $W$를 weight, $b$를 bias라고 한다.

먼저 초기 weight와 bias를 0으로 초기화하자. 즉 항상 출력 0을 예측한다.

 - required_grad=True :  데이터를 학습할 것이라고 명시하는 의미


학습을 위해 이 모델이 실제와 얼마나 다른지를 확인해야 한다. 다음과 같은 loss를 정의하자.(Mean Squared Error, MSE)

\[cost(W, b) = \frac{1}{m} \sum_{i=1}^m (H(x^{(i)}) - y^{(i)})^2\]
 - torch.mean : 평균을 계산


이 loss function으로부터 모델을 개선시키자. torch.optim 라이브러리에서 Stochastic Gradient Descent, SGD optimizer 를 사용할 것이다. Loss가 최소가 되는 지점을 알고 싶으므로, gradient가 (-)가 되도록 값을 이동시키는 방법이다.

 - torch.optim.SGD(params, lr) : 학습할 텐서와 learning rate input으로 받아 모델을 학습
 - zero_grad() : gradient 초기화
 - backward() : gradient 계산
 - step() : 계산된 gradient 텐서 개선

학습할 tensor를 [W, b]로, learning rate를 lr = 0.01로 두자.


전체 코드는 다음과 같다. 데이터를 정의하고 hypothesis를 초기화한다. 어떤 Optimizer를 사용할 것인지 정의한다. 이 부분은 처음 한 번만 있으면 된다.

이후 hypothesis를 예측하고 cost를 계산해 optimizer로 학습하는 내용을 반복한다.

 - Result : [tensor([29.5617], requires_grad=True), tensor([0.9963], requires_grad=True)]


SGD는 어떤 방식으로 모델을 학습시킬까? 다시 linear regression model로 돌아가면,

\[cost(W) = \frac{1}{m} \sum_{i=1}^m (Wx^{(i)} + b - y^{(i)})^2\]

cost의 gradient를 구한다.

\[D_W = \frac{\partial cost}{\partial W} = \frac{2}{m} \sum_{i=1}^m (Wx^{(i)} + b - y^{(i)})x^{(i)}\]

Gradient가 양수이면 weight를 줄여야 하고, gradient가 음수이면 weight를 늘려야 한다. 따라서 weight는 다음과 같이 재정의된다.

\[W := W - \alpha D_W\]

여기서 $\alpha$가 learning rate, $D_W$가 weight에 대한 cost의 gradient이다.

마찬가지로 bias는

\[D_b = \frac{\partial cost}{\partial b} = \frac{2}{m} \sum_{i=1}^m (Wx^{(i)} + b - y^{(i)})\] \[b := b - \alpha D_b\]


이를 바탕으로 torch.optim 라이브러리 없이 구현한 코드가 다음과 같다.

 - Result:
  Epoch  100/1000 W: 26.1762, b: 8.6920, Cost: 10.890694
  Epoch  200/1000 W: 26.9943, b: 6.8328, Cost: 6.729773
  Epoch  300/1000 W: 27.6372, b: 5.3712, Cost: 4.158598
  Epoch  400/1000 W: 28.1426, b: 4.2222, Cost: 2.569760
  Epoch  500/1000 W: 28.5399, b: 3.3191, Cost: 1.587953
  Epoch  600/1000 W: 28.8523, b: 2.6091, Cost: 0.981258
  Epoch  700/1000 W: 29.0978, b: 2.0510, Cost: 0.606357
  Epoch  800/1000 W: 29.2908, b: 1.6123, Cost: 0.374696
  Epoch  900/1000 W: 29.4425, b: 1.2674, Cost: 0.231537
  Epoch 1000/1000 W: 29.5617, b: 0.9963, Cost: 0.143077