관리 메뉴

ComputerVision Jack

PyTorch Lecture 06 : Logistic Regression 본문

DeepLearning/Pytorch_ZeroToAll

PyTorch Lecture 06 : Logistic Regression

JackYoon 2020. 10. 12. 18:08
반응형

Linear model

logistic regression을 학습하기에 앞서, 앞에서 배운 선형 모델에 대해 우선적으로 복습을 해주셨습니다.

x_data -> Linear Model -> y_data 경우

Hours(x) Points
1 2
2 4
3 6
4 ?

우리는 쉽게 8로 예측을 할수 있습니다. 선형 모델이기 때문이죠.

Binary prediction (0 or 1) is very useful!

이번엔 문제 접근 방식을 조금 바꿔보겠습니다. 결과가 특정한 value로 수렴하지 않고 0과 1의 두가지 결과만 초래 한다고 생각해 봅시다. 때때로 이런식의 이분법적인 결론은 우리 사회에서 많이 직면할 수 있습니다. 이렇게 이분법적인 결과를 도출하기 위해선 우리는 선형 함수 결과에 활성화 함수(Sigmoid)를 더해 결과를 출력할 수 있습니다.

x_data -> Linear Model -> Sigmoid -> y^ 경우가 됩니다.

 

Sigmoid 함수

sigmoid 활성화 함수 그래프

위 sigmoid 활성화 함수를 보시면 linear를 통과한 값이 0.5 이상이면 결과값은 1에 근사하게 측정이되고, 0.5 이하이면 결과값은 0에 근사하게 도출됩니다. 즉 우리가 원하는 이진 결과값이 나오게 됩니다.

value z 값에 w * x + b의 값이 들어간다고 볼 수 있습니다.

 

Cross Entropy Loss 함수

Cross Entropy Loss 손실 함수

이제 우리가 제작한 가설의 모양이 변경되었기 때문에 손실 함수도 이에 맞게 수정해야합니다.

sigmoid의 손실 함수로는 cross entropy 함수가 있습니다.

y y_pred loss
1 0.2 대략 0.7
1 0.8 대략 0.1
0 0.1 대략 0.05
0 0.9 대략 1

y = 1, y_pred = 0.2 경우

y가 1인데 실제 예측을 0.2로 하면 잘못 예측한 경우입니다. 아래의 loss 도출을 보면 이해할 수 있습니다.

loss = -1 * log 0.2  + (1 - 1) log (1 - 0.2) = -1 * log 0.2 가 됩니다. 즉 log 그래프를 통해 결과를 출력하면 0.7정도가 됩니다. 손실이 높게 측정된 것을 알 수 있습니다.

 

이제 sigmoid 활성화 함수와 cross entropy 손실 함수를 토대로 Binary Logistic regression을 진행해보겠습니다.

[06.Logistic_regression.py]

from torch import tensor

from torch import nn

from torch import sigmoid

import torch.nn.functional as F

import torch.optim as optim

# torch tensor와 nn을 사용하기 위해 import 하고, sigmoid 함수를 사용하기 위해 import를 진행합니다.

 

x_data = tensor([[1.0], [2.0], [3.0], [4.0]])

y_data = tensor([[0. ], [0. ], [1. ], [1. ]])

# 학습에 필요한 데이터 셋을 준비합니다. 이번 데이터셋 또한 1대1로 각각 매칭됩니다.

 

class Model(nn.Module):

    def __init__(self):

        super(Model, self).__init__()

        self.linear = nn.Linear(1, 1)

 

    def forward(self, x):

        y_pred = sigmoid(self.linear(x))

        return y_pred

# 선형 모델과 다른 점은 forward(self, x) 함수 내에서 y_pred가 self.linear(x) 출력되는데 이 부분을 sigmoid 활성화 함수에 넣어 주는 부분입니다.

 

model = Model()

# 만든 모델에 대하나 객체를 인스턴스화 합니다.

 

criterion = nn.BCELoss(reduction = 'mean')

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

# sigmoid의 활성함수에 맞게 손실함수도 새롭게 변경합니다. BCELoss 즉 Binary Cross Entropy Loss 함수를 사용합니다. 또한 그 함수를 자세히 살펴보면 우리가 원하는 2차 함수 모양인 것을 확인할 수 있습니다.

따라서 전처럼 SGD 알고리즘을 사용하여 경사 하강을 진행하고 learning_rate은 0.01로 설정합니다.

 

for epoch in range(1000):

    y_pred = model(x_data)

 

    loss = criterion(y_pred, y_data)

    print(f'Epoch {epoch + 1} / 1000 | Loss : {loss.item():.4f}')

 

    optimizer.zero_grad()

    loss.backward()

    optimizer.step()

# 학습을 반복 횟수 1000으로 학습 시킵니다. 우리가 만든 모델 클래스에 x_data를 넣고 결과 값을 실제 y값과 비교하여 나온 손실에 대해 경사하강법을 통해 최적화를 진행합니다.

 

print(f'\nLet\'s predict the hours need to score above 50%\n={"=" * 50}')

 

hour_var = model(tensor([[1.0]]))

print(f'Prediction after 1 hour of training : {hour_var.item():.4f} | Above 50% : {hour_var.item() > 0.5}')

 

hour_var = model(tensor([[7.0]]))

print(f'Prediction after 1 hour of training : {hour_var.item():.4f} | Above 50% : {hour_var.item() > 0.5}')

# 이제 hour_var 값을 우리가 학습한 모델에 대입합니다. 결과 값이 0.5 이상이면 True를 출력하고 0.5 미만이면 False를 출력합니다.

결과 화면

 

반응형
Comments