1.1 Linear Regression
지훈이는 오늘도 싱글벙글 게임을 켰다. 슬라임을 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
로 표기한다.
모델은 다음과 같이 가정하자. 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