[ML] Linear Regression 정리

학교 수업으로 타학과 전공인 ‘인공지능과 딥러닝’을 수강하게 되었다. 오일석 교수님의 [Machine Learning 기계학습] 을 기반으로 진행되는 강의이다.

Perceptron을 설명하면서 Linear regression을 직접 코딩을 통해 실습하는 시간을 가졌는데, 아래의 내용은 그 실습 내용을 정리한 것이다.

Linear regression

Author: Seungjae Lee(이승재)

모두를 위한 딥러닝을 참고하였습니다.

Theoretical Overview

$ H(x) = Wx + b $

$ cost(W, b) = \frac{1}{m} \sum^m_{i=1} \left( H(x^{(i)}) - y^{(i)} \right)^2 $

  • $H(x)$: 주어진 $x$ 값에 대해 예측을 어떻게 할 것인가
  • $cost(W, b)$: $H(x)$ 가 $y$ 를 얼마나 잘 예측했는가

Import

1
2
3
4
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

For reproducibility

1
torch.manual_seed(1)

Data

다음 예제를 위해 예시 데이터를 사용하여보자. (We will use fake data for this example.)

1
2
3
4
5
6
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[1], [2], [3]])
print(x_train)
print(x_train.shape)
print(y_train)
print(y_train.shape) 기본적으로 Pytorch는 NCHW 형태이다.

Weight Initialization

1
2
3
4
W = torch.zeros(1, requires_grad=True)
print(W)
b = torch.zeros(1, requires_grad=True)
print(b)

Hypothesis

$ H(x) = Wx + b $

1
2
hypothesis = x_train * W + b
print(hypothesis)

Cost

$ cost(W, b) = \frac{1}{m} \sum^m_{i=1} \left( H(x^{(i)}) - y^{(i)} \right)^2 $

1
2
3
4
5
6
print(hypothesis)
print(y_train)
print(hypothesis - y_train)
print((hypothesis - y_train) ** 2)
cost = torch.mean((hypothesis - y_train) ** 2)
print(cost)

Gradient Descent

1
2
3
4
5
6
optimizer = optim.SGD([W, b], lr = 0.01)
optimizer.zero_grad()
cost.backward()
optimizer.step()
print(W)
print(b)

가설이 잘 작동하는지 확인하여 보자. (Let’s check if the hypothesis is now better.)

1
2
3
4
hypothesis = x_train * W + b
print(hypothesis)
cost = torch.mean((hypothesis - y_train) ** 2)
print(cost)

Training with Full Code

In reality, we will be training on the dataset for multiple epochs. This can be done simply with loops.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 데이터
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[1], [2], [3]])

# 모델 초기화
W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)

# optimizer 설정
optimizer = optim.SGD([W, b], lr = 0.01)

nb_epochs = 1000
for epoch in range(nb_epochs + 1):
        
    # H(x) 계산
    hypothesis = x_train * W + b
        
    # cost 계산
    cost = torch.mean((hypothesis - y_train) ** 2)
        
    # cost로 H(x) 개선
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()
        
    # 100번마다 로그 출력
    if epoch % 100 == 0:
        print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format(
                epoch, nb_epochs, W.item(), b.item(), cost.item()
        ))

High-level implementaion with nn.Module

Remember that we had this fake data.

1
2
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[1], [2], [3]])

이제 linear regression 모델을 만들면 되는데, 기본적으로 Pytorch의 모든 모델은 제공되는 nn.Module을 inherit 해서 만들게 된다.

1
2
3
4
5
6
7
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(1, 1)
        
    def forward(self, x):
        return self.linear(x)

모델의 __init__에서는 사용할 레이어들을 정의하게 된다. 여기서 우리는 linear regression 모델을 만들기 때문에, nn.Linear를 이용할 것이다. 그리고 forward에서는 이 모델이 어떻게 입력값에서 출력값을 계산하는지 알려준다.

1
model = LinearRegressionModel()

Hypothesis

이제 모델을 생성해서 예측값 H(x) 를 구해보자

1
2
hypothesis = model(x_train)
print(hypothesis)

Cost

이제 mean squared error (MSE)로 cost를 구해보자. MSE 역시 PyTorch에서 기본적으로 제공한다.

1
2
3
4
print(hypothesis)
print(y_train)
cost = F.mse_loss(hypothesis, y_train)
print(cost)

Gradient Descent

마지막 주어진 cost를 이용해 H(x)W , b 를 바꾸어서 cost를 줄여봅시다. 이때 PyTorch의 torch.optim에 있는 optimizer들 중 하나를 사용할 수 있다.

1
2
3
4
optimizer = optim.SGD(model.parameters(), lr=0.01)
optimizer.zero_grad()
cost.backward()
optimizer.step()

Training with Full Code

이제 Linear Regression 코드를 이해했으니, 실제로 코드를 돌려 피팅하여보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 데이터
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[1], [2], [3]])

# 모델 초기화
model = LinearRegressionModel()

# optimizer 설정
optimizer = optim.SGD(model.parameters(), lr=0.01)

nb_epochs = 1000
for epoch in range(nb_epochs + 1):
    
    # H(x) 계산
    prediction = model(x_train)
        
    # cost 계산
    cost = F.mse_loss(prediction, y_train)
        
    # cost로 H(x) 개선
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()
        
    # 100번 마다 로그 출력
    if epoch % 100 == 0:
        params = list(model.parameters())
        W = params[0].item()
        b = params[1].item()
        print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format(
            epoch, nb_epochs, W, b, cost.item()
        ))

점점 H(x)Wb 를 조정해서 cost가 줄어드는 것을 볼 수 있다.

태그:

카테고리:

업데이트:

댓글남기기