1. binary prediction and sigmoid

추론값의 결과가 0 또는 1로 나타나는, 이진 모델binary classification 모델에 쓰이는 sigmoid함수에 대해 알아보자.

sigmoid

정의역이 실수 전체이고, 치역이 0 과 1 사이인 sigmoid 함수는 답이 True / False 형태로 나오는 문제에 적용하기 좋다.

정의역에서 -4 또는 4 밖으로 벗어나는 값을 가지면 함숫값이 0 또는 1에 근사하는 모습을 볼 수 있다.

 

또한 해당 함수는 값이 0~1 사이의 값으로 나온다는 점에서, 추론값이 확률로 필요할 때 쓰이기도 한다.

 

2. Logistic Regression(로지스틱 회귀)

로지스틱 회귀란, 선형 모델에 simoid함수를 결합하여 사용한 모델이라고 볼 수 있다.

사건의 발생 여부 (이진 분류)를 단순 선형 모델로 표현하는 경우, 새로운 값의 추가가 기존 분류 모델에 큰 영향을 미칠 수 있다.

기존의 선형 모델을 분류에 더 적합하게 완만한 곡선으로 나타내여, 이를 방지하는 것이다. 

로지스틱 회귀의 이진 분류

 

치역에서 0.5를 기준으로 TURE / FALSE를 결정한다. 아래에 로지스틱 회귀와 관련한 설명 블로그를 추가한다.

https://itstory1592.tistory.com/8

 

2. Binary Cross Entropy Loss(이진 교차 엔트로피 loss)

모델의 출력이 0~1인 확률값으로 나오므로 기존에 쓰던 MSE Loss 의 대안인 Binary Cross Entropy Loss를 사용한다.

\[
\mathcal{L}(y, \hat{y}) = - \left[ y \cdot \log(\hat{y}) + (1 - y) \cdot \log(1 - \hat{y}) \right]
\]

 

loss의 기본적인 원리는 모델의 예측값이 참에 가깝다면 loss가 작고, 참에서 멀어질 수록 loss가 큰 것을 이용한 것이다.

dataset에서 y의 값이 0 또는 1 인 점에 주목해며, 해당 식을 봐보자. 해당 식에서 y가 0또는1임에 따라 덧셈 기준 좌항과 우항이 활성화 되고, 나머지 항은 없어지는 것을 볼 수 있다.

 

  • y (참값) - 1인 경우 > -log(?)안에 y_pred 가 들어감 > log(y_pred) > y_pred가 1에 가까울 수록 loss 작음
  • y (참값) - 0인 경우 > log(1-?)안에 y_pred 가 들어감 > log(y_pred) > y_pred가 0에 가까울 수록 loss 작음

 

Binary Cross Entropy Loss
log 함수 - 해당 loss계산시에는 정의역이 sigmoid의 치역이므로 0~1인점을 고려해야 한다.

 

3. Code 

sigmoid 모델을 사용한 로지스틱 회귀 torch 구현 코드이다.

기존 선형 회귀 모델에서 model class 정의, loss function 의 종류만 다르다.

import torch

x_data = torch.tensor([[1.0],[2.0],[3.0],[4.0]])
y_data = torch.tensor([[0.],[0.],[1.],[1.]])


class Model(torch.nn.Module):
   def __init__(self):
      super().__init__()
      self.linear = torch.nn.Linear(1,1)

   def forward(self,x):
      y_pred = torch.nn.functional.sigmoid(self.linear(x))
      return y_pred

model = Model()
criterion = torch.nn.BCELoss(reduction='mean')
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)

with torch.no_grad():
   hour_var = torch.tensor([[7.0]])
   temp = model(hour_var)
   print(" 학습 전 7.0에 대한 추론값 ", temp.item())
   print(f'Prediction before 7.0 hours of training: {hour_var.item():.4f} | Above 50%: { temp.item() > 0.5}')

for epoch in range(100):

   y_pred = model(x_data)
   loss = criterion(y_pred,y_data)
   print("epoch loss",epoch, loss.item())
 
   optimizer.zero_grad()
   loss.backward() 
   optimizer.step()
 

with torch.no_grad():
   hour_var = torch.tensor([[7.0]])
   temp = model(hour_var)
   print(" 학습 후 7.0에 대한 추론값 ", temp.item())
   print(f'Prediction after 7.0 hours of training: {hour_var.item():.4f} | Above 50%: { temp.item() > 0.5}')







+ Recent posts