로지스틱 회귀(Logistic Regression)
- 말은 회귀지만 회귀 모델이 아닌 분류 모델
- 선형 방정식을 사용한 분류 알고리즘, 계산한 값을 0과 1사이로 압축
- 시그모이드 함수(이진 분류) 나 소프트맥스 함수(다중 분류)를 사용해 클래스 확율을 출력 가능
시그모이드 함수(Sigmoid fuction)
1. W가 1이고 b가 0인 그래프 생성
- x가 0일 때 0.5의 출력값을 가짐
- x가 매우 커지면 1에 수렴
- x가 매우 작아지면 0에 수렴
# Mtplotlib 과 Numpy 임포트
%matplotlib inline
import numpy as np # 넘파이 사용
import matplotlib.pyplot as plt # 맷플롯립사용
# Numpy를 사용해 시그모이드 함수 정의
def sigmoid(x): # 시그모이드 함수 정의
return 1/(1+np.exp(-x))
x = np.arange(-5.0, 5.0, 0.1)
y = sigmoid(x)
plt.plot(x, y, 'g')
plt.plot([0,0],[1.0,0.0], ':') # 가운데 점선 추가
plt.title('Sigmoid Function')
plt.show()
2. W값의 변화에 따른 경사도 변화
- W값이 0.5일 때 빨간색, W값이 1일 때 초록색, W의 값이 2일 때 파란색 선
- W값이 커지면 경사가 커지고 W 값이 작아지면 경사가 작아짐
x = np.arange(-5.0, 5.0, 0.1)
y1 = sigmoid(0.5*x)
y2 = sigmoid(x)
y3 = sigmoid(2*x)
plt.plot(x, y1, 'r', linestyle='--') # W의 값이 0.5일때
plt.plot(x, y2, 'g') # W의 값이 1일때
plt.plot(x, y3, 'b', linestyle='--') # W의 값이 2일때
plt.plot([0,0],[1.0,0.0], ':') # 가운데 점선 추가
plt.title('Sigmoid Function')
plt.show()
3. b값의 변화에 따른 좌, 우 이동
- b의 값에 따라서 그래프가 좌, 우로 이동한다.
x = np.arange(-5.0, 5.0, 0.1)
y1 = sigmoid(x+0.5)
y2 = sigmoid(x+1)
y3 = sigmoid(x+1.5)
plt.plot(x, y1, 'r', linestyle='--') # x + 0.5
plt.plot(x, y2, 'g') # x + 1
plt.plot(x, y3, 'b', linestyle='--') # x + 1.5
plt.plot([0,0],[1.0,0.0], ':') # 가운데 점선 추가
plt.title('Sigmoid Function')
plt.show()
4. 시그모이드 함수를 이용한 분류
- 시그모이드 함수는 입력값이 한없이 커지면 1에 수렴, 입력값이 작아지면 0에 수렴
- 시그모이드 함수의 출력값은 0과 1사이의 값을 가짐, 이를 이용해 분류 작업에 사용
5. 비용 함수(Cost function)
- 시그모이드 함수에서 최적의 W와 b를 찾을 수 있는 함수는 로그 함수
파이토치로 로지스틱 회귀 구현
1. 랜덤 시드 지정 후 데이터 로드, 모델 초기화, 옵티마이저 설정 후 학습 진행
# 도구 임포트
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# 랜덤 시드 지정
torch.manual_seed(1)
# 데이터셋 텐서로 선언
x_data = [[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]]
y_data = [[0], [0], [0], [1], [1], [1]]
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)
# 모델 초기화
W = torch.zeros((2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
# optimizer 설정
optimizer = optim.SGD([W, b], lr=1)
# 학습 실행
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
# Cost 계산
hypothesis = torch.sigmoid(x_train.matmul(W) + b)
# cost = -(y_train * torch.log(hypothesis) +
# (1 - y_train) * torch.log(1 - hypothesis)).mean()
cost = F.binary_cross_entropy(hypothesis, y_train) # 파이토치에서 제공하는 로지스틱 회귀 비용 함수
# cost로 H(x) 개선
optimizer.zero_grad()
cost.backward()
optimizer.step()
# 100번마다 로그 출력
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
2. 훈련 데이터를 그대로 입력으로 사용했을 때 예측 값 확인
# 훈련 데이터를 그대로 입력으로 사용했을 때 예측 값 확인
hypothesis = torch.sigmoid(x_train.matmul(W) + b)
print(hypothesis)
3. 0.5를 넘으면 True, 넘지 않으면 False로 값을 정하여 출력
# 0.5를 넘으면 True, 넘지 않으면 False로 값을 정하여 출력
prediction = hypothesis >= torch.FloatTensor([0.5])
print(prediction)
4. 훈련이 끝난 상태의 W와 b의 값 출력
# 훈련이 끝난 상태의 W와 b의 값 출력
print(W)
print(b)
nn.Module로 구현하는 로지스틱 회귀
1. 도구 임포트 및 훈련 데이터 선언
# 도구 임포트
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# 랜덤 시드 지정
torch.manual_seed(1)
# 훈련 데이터 텐서로 선언
x_data = [[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]]
y_data = [[0], [0], [0], [1], [1], [1]]
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)
2. nn.Sequential()을 사용해 로지스틱 회귀 구현
- nn.Sequential()dms nn.Module 층을 차례로 쌓을 수 있게 해줌
- 수식과 시그모이드 함수 등과 같은 여러 함수들을 연결해주는 역할
# nn.Sequential()을 사용해 로지스틱 회귀 구현
model = nn.Sequential(
nn.Linear(2, 1), # input_dim = 2, output_dim = 1
nn.Sigmoid() # 출력은 시그모이드 함수를 거친다
)
3. 모델 훈련
# 경사 하강법을 사용해 훈련
# optimizer 설정
optimizer = optim.SGD(model.parameters(), lr=1)
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
# H(x) 계산
hypothesis = model(x_train)
# cost 계산
cost = F.binary_cross_entropy(hypothesis, y_train)
# cost로 H(x) 개선
optimizer.zero_grad()
cost.backward()
optimizer.step()
# 20번마다 로그 출력
if epoch % 10 == 0:
prediction = hypothesis >= torch.FloatTensor([0.5]) # 예측값이 0.5를 넘으면 True로 간주
correct_prediction = prediction.float() == y_train # 실제값과 일치하는 경우만 True로 간주
accuracy = correct_prediction.sum().item() / len(correct_prediction) # 정확도를 계산
print('Epoch {:4d}/{} Cost: {:.6f} Accuracy {:2.2f}%'.format( # 각 에포크마다 정확도를 출력
epoch, nb_epochs, cost.item(), accuracy * 100,
))
4. 기존 훈련 데이터로 예측값 확인
# 기존 훈련 데이터를 입력해 예측값 확인
model(x_train)
5. 훈련 후의 W와 b값 출력
print(list(model.parameters()))
클래스로 파이토치 모델 구현
1. 기존 로지스틱 회귀 모델 형태
# 기존 로지스틱 회귀 모델
model = nn.Sequential(
nn.Linear(2, 1), # input_dim = 2, output_dim = 1
nn.Sigmoid() # 출력은 시그모이드 함수를 거친다
)
2. 위 내용을 클래스로 구현
# 위 내용을 클래스로 구현
class BinaryClassifier(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
return self.sigmoid(self.linear(x))
3. 로지스틱 회귀를 클래스로 구현
# 도구 임포트
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
# 랜덤 시드 지정
torch.manual_seed(1)
# 데이터 로딩
x_data = [[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]]
y_data = [[0], [0], [0], [1], [1], [1]]
x_train = torch.FloatTensor(x_data)
y_train = torch.FloatTensor(y_data)
# 클래스로 모델 생성
class BinaryClassifier(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
return self.sigmoid(self.linear(x))
# 모델 객체 생성
model = BinaryClassifier()
# optimizer 설정
optimizer = optim.SGD(model.parameters(), lr=1)
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
# H(x) 계산
hypothesis = model(x_train)
# cost 계산
cost = F.binary_cross_entropy(hypothesis, y_train)
# cost로 H(x) 개선
optimizer.zero_grad()
cost.backward()
optimizer.step()
# 20번마다 로그 출력
if epoch % 10 == 0:
prediction = hypothesis >= torch.FloatTensor([0.5]) # 예측값이 0.5를 넘으면 True로 간주
correct_prediction = prediction.float() == y_train # 실제값과 일치하는 경우만 True로 간주
accuracy = correct_prediction.sum().item() / len(correct_prediction) # 정확도를 계산
print('Epoch {:4d}/{} Cost: {:.6f} Accuracy {:2.2f}%'.format( # 각 에포크마다 정확도를 출력
epoch, nb_epochs, cost.item(), accuracy * 100,
))
참고:
https://wikidocs.net/book/2788
PyTorch로 시작하는 딥 러닝 입문
이 책은 딥 러닝 프레임워크 PyTorch를 사용하여 딥 러닝에 입문하는 것을 목표로 합니다. 이 책은 2019년에 작성된 책으로 비영리적 목적으로 작성되어 출판 ...
wikidocs.net
'AI > PyTorch' 카테고리의 다른 글
PyTorch #인공 신경망(ANN) (0) | 2022.03.30 |
---|---|
PyTorch #소프트맥스 회귀(Softmax Regression) (0) | 2022.03.24 |
PyTorch #선형 회귀(Linear Regression) (0) | 2022.03.23 |
PyTorch 텐서 조작 #뷰 #스퀴즈 #언스퀴즈 #타입 캐스팅 #텐서 연결 (0) | 2022.03.22 |
PyTorch 텐서 조작 #텐서 선언 #곱셈 #평균 #덧셈 #최대 #아그맥스 (0) | 2022.03.22 |