-
[기계학습] 로지스틱 회귀(분류 Classification)(Logistic Regression) (Part 2/2)코딩(Coding)/기계학습 2022. 1. 25. 22:17728x90
이전 포스팅의 개념적인 부분을 python의 pytorch 패키지를 통해 구현하는 포스팅입니다.
이전 포스팅을 보고오세요~ :D (https://jsy-coding-blog.tistory.com/47)
포스팅에서 사용하는 PPT 자료는 제 Github에서 pdf 형식으로 받을 수 있습니다.(https://github.com/JoSangYeon/Machine_Learning_Project/blob/master/PPT/01.%20Machine%20Learning.pdf)
Logistic Regression
분류 문제
지난 포스팅 복습
코드 실습(With Pytorch)
패키지 Import
import numpy as np import pandas as pd import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import Dataset, DataLoader print(torch.__version__)
1.10.1
예제 Data 생성
# 예제 x_data = [[0],[2],[1],[9],[10]] y_data = [[0],[0],[0],[1],[1]] X = torch.tensor(np.array(x_data)).float() Y = torch.tensor(np.array(y_data)).float() print(X) print(Y)
tensor([[ 0.], [ 2.], [ 1.], [ 9.], [10.]]) tensor([[0.], [0.], [0.], [1.], [1.]])
예제로 사용할 데이터는 간단하게 PPT에서 봤던 데이터이다.
x가 05이면 Y는 0이고 510이면 Y는 1이다.
Model 정의(가설 정의)
class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc1 = nn.Linear(1, 1) self.act_fn = nn.Sigmoid() def forward(self, input): x = self.fc1(input) x = self.act_fn(x) return x model = MyModel() opt = optim.Adam(model.parameters()) loss_fn = nn.BCELoss() print(model)
MyModel( (fc1): Linear(in_features=1, out_features=1, bias=True) (act_fn): Sigmoid() )
모델은 간단하게 nn.Module로 sub-Classing하였다.
모델의 연산은 다음과 같다.(forward() 메소드 참고)- input_Node : 1, output_Node : 1인 Linear Layer를 정의한다.
- 해당 Linear Layer의 output을 Sigmoid 함수에 대입한다.
모델 학습
# 학습 model.train() for epoch in range(1, 1001): x, y = X, Y opt.zero_grad() output = model(x) loss = loss_fn(output, y) loss.backward() opt.step() if epoch % 25 == 0: print("EPOCH {} >>> Loss : {:.5f}".format(epoch, loss))
EPOCH 25 >>> Loss : 0.96217 EPOCH 50 >>> Loss : 0.93793 EPOCH 75 >>> Loss : 0.91404 EPOCH 100 >>> Loss : 0.89053 EPOCH 125 >>> Loss : 0.86741 EPOCH 150 >>> Loss : 0.84471 EPOCH 175 >>> Loss : 0.82245 EPOCH 200 >>> Loss : 0.80066 EPOCH 225 >>> Loss : 0.77935 EPOCH 250 >>> Loss : 0.75858 EPOCH 275 >>> Loss : 0.73837 EPOCH 300 >>> Loss : 0.71877 EPOCH 325 >>> Loss : 0.69983 EPOCH 350 >>> Loss : 0.68159 EPOCH 375 >>> Loss : 0.66413 EPOCH 400 >>> Loss : 0.64750 EPOCH 425 >>> Loss : 0.63176 EPOCH 450 >>> Loss : 0.61699 EPOCH 475 >>> Loss : 0.60323 EPOCH 500 >>> Loss : 0.59052 EPOCH 525 >>> Loss : 0.57887 EPOCH 550 >>> Loss : 0.56828 EPOCH 575 >>> Loss : 0.55868 EPOCH 600 >>> Loss : 0.55000 EPOCH 625 >>> Loss : 0.54213 EPOCH 650 >>> Loss : 0.53493 EPOCH 675 >>> Loss : 0.52826 EPOCH 700 >>> Loss : 0.52201 EPOCH 725 >>> Loss : 0.51606 EPOCH 750 >>> Loss : 0.51033 EPOCH 775 >>> Loss : 0.50475 EPOCH 800 >>> Loss : 0.49927 EPOCH 825 >>> Loss : 0.49388 EPOCH 850 >>> Loss : 0.48854 EPOCH 875 >>> Loss : 0.48325 EPOCH 900 >>> Loss : 0.47801 EPOCH 925 >>> Loss : 0.47280 EPOCH 950 >>> Loss : 0.46764 EPOCH 975 >>> Loss : 0.46251 EPOCH 1000 >>> Loss : 0.45743
Loss가 순차적으로 줄어든 것을 볼 수 있다.
성능 검증
# 성능 검증 # X, Y를 그대로 넣어서 제대로 분류하는 확인 def decision_boundary(output): return (output >= torch.tensor([0.5])).float() model.eval() output = model(X) output = decision_boundary(output) print("모델이 예측한 값 :",output.view(-1)) print("실제 값 : ", Y.view(-1)) print("정확도 : {}%".format(((output == Y).view(-1).sum() / 5. * 100.).item()))
모델이 예측한 값 : tensor([0., 1., 0., 1., 1.]) 실제 값 : tensor([0., 0., 0., 1., 1.]) 정확도 : 80.0%
1000번을 학습하고 기존의 X,Y를 대입해보았다.
Train 데이터에 대해서 정확도는 80%(5개중 4개 맞았다.)새로운 데이터가 추가 되었다.
데이터 정의
# 예제 x_data = [[0],[2],[1],[9],[10],[20],[5]] y_data = [[0],[0],[0],[1],[1], [1], [0]] X = torch.tensor(np.array(x_data)).float() Y = torch.tensor(np.array(y_data)).float() print(X) print(Y)
tensor([[ 0.], [ 2.], [ 1.], [ 9.], [10.], [20.], [ 5.]]) tensor([[0.], [0.], [0.], [1.], [1.], [1.], [0.]])
모델 정의
class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc1 = nn.Linear(1, 1) self.act_fn = nn.Sigmoid() def forward(self, input): x = self.fc1(input) x = self.act_fn(x) return x model = MyModel() opt = optim.Adam(model.parameters()) loss_fn = nn.BCELoss() print(model)
MyModel( (fc1): Linear(in_features=1, out_features=1, bias=True) (act_fn): Sigmoid() )
학습
# 학습 model.train() for epoch in range(1, 1001): x, y = X, Y opt.zero_grad() output = model(x) loss = loss_fn(output, y) loss.backward() opt.step() if epoch % 25 == 0: print("EPOCH {} >>> Loss : {:.5f}".format(epoch, loss))
EPOCH 25 >>> Loss : 0.87950 EPOCH 50 >>> Loss : 0.80764 EPOCH 75 >>> Loss : 0.74866 EPOCH 100 >>> Loss : 0.70152 EPOCH 125 >>> Loss : 0.66421 EPOCH 150 >>> Loss : 0.63451 EPOCH 175 >>> Loss : 0.61047 EPOCH 200 >>> Loss : 0.59060 EPOCH 225 >>> Loss : 0.57378 EPOCH 250 >>> Loss : 0.55923 EPOCH 275 >>> Loss : 0.54639 EPOCH 300 >>> Loss : 0.53487 EPOCH 325 >>> Loss : 0.52439 EPOCH 350 >>> Loss : 0.51474 EPOCH 375 >>> Loss : 0.50575 EPOCH 400 >>> Loss : 0.49733 EPOCH 425 >>> Loss : 0.48937 EPOCH 450 >>> Loss : 0.48181 EPOCH 475 >>> Loss : 0.47461 EPOCH 500 >>> Loss : 0.46770 EPOCH 525 >>> Loss : 0.46107 EPOCH 550 >>> Loss : 0.45468 EPOCH 575 >>> Loss : 0.44851 EPOCH 600 >>> Loss : 0.44254 EPOCH 625 >>> Loss : 0.43676 EPOCH 650 >>> Loss : 0.43114 EPOCH 675 >>> Loss : 0.42569 EPOCH 700 >>> Loss : 0.42038 EPOCH 725 >>> Loss : 0.41521 EPOCH 750 >>> Loss : 0.41017 EPOCH 775 >>> Loss : 0.40525 EPOCH 800 >>> Loss : 0.40046 EPOCH 825 >>> Loss : 0.39577 EPOCH 850 >>> Loss : 0.39119 EPOCH 875 >>> Loss : 0.38672 EPOCH 900 >>> Loss : 0.38234 EPOCH 925 >>> Loss : 0.37805 EPOCH 950 >>> Loss : 0.37385 EPOCH 975 >>> Loss : 0.36974 EPOCH 1000 >>> Loss : 0.36571
성능 검증
# 성능 검증 # X, Y를 그대로 넣어서 제대로 분류하는 확인 def decision_boundary(output): return (output >= torch.tensor([0.5])).float() model.eval() output = model(X) output = decision_boundary(output) print("모델이 예측한 값 :",output.view(-1)) print("실제 값 : ", Y.view(-1)) print("정확도 : {:.2f}%".format(((output == Y).view(-1).sum() / 7. * 100.).item()))
모델이 예측한 값 : tensor([0., 0., 0., 1., 1., 1., 1.]) 실제 값 : tensor([0., 0., 0., 1., 1., 1., 0.]) 정확도 : 85.71%
다변수 회귀 분류
PPT 복습
학습 데이터 정의
# 예제 x_data = [[1.2, 3.4],[1.1, 3.2],[1.5, 3.7], [5.2, 0.7],[4.7, 0.6],[5.6, 0.9], [7.7, 6.6],[7.5, 7.2],[8.1, 6.2]] y_data = [0,0,0, 1,1,1, 2,2,2] X = torch.tensor(x_data) Y = torch.tensor(y_data) print(X) print(Y)
tensor([[1.2000, 3.4000], [1.1000, 3.2000], [1.5000, 3.7000], [5.2000, 0.7000], [4.7000, 0.6000], [5.6000, 0.9000], [7.7000, 6.6000], [7.5000, 7.2000], [8.1000, 6.2000]]) tensor([0, 0, 0, 1, 1, 1, 2, 2, 2])
Feature는 2개이고 Label은 1이다.
Label : One-Hot Encoding
# Label을 3개의 클래스를 가지도록 one-hot encoding 해줌 Y = F.one_hot(Y, num_classes=3).float() Y
tensor([[1., 0., 0.], [1., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 0., 1.], [0., 0., 1.], [0., 0., 1.]])
3개의 Y값을 가지기 때문에, One-Hot Encoding을 통해 label값을 변경해준다.
모델 정의
class MyModel(nn.Module): def __init__(self): super(MyModel, self).__init__() self.fc1 = nn.Linear(2, 3) self.act_fn = nn.Softmax(dim=1) def forward(self, input): x = self.fc1(input) x = self.act_fn(x) return x model = MyModel() opt = optim.Adam(model.parameters()) loss_fn = nn.CrossEntropyLoss() print(model)
MyModel( (fc1): Linear(in_features=2, out_features=3, bias=True) (act_fn): Softmax(dim=1) )
모델은 다음과 같다.
- input_Node : 2, output_Node 3을 가지는 Linear Layer를 정의한다.
- Linear Layer의 결과값을 softmax함수에 대입하여 확률값으로 변환한다.
- 각 노드의 값은 해당 input이 해당 Label일 확률을 의미한다.
- 최적화 알고리즘은 Adam을 사용했고, 오차함수는 Cross-Entropy이다.
학습
# 학습 model.train() for epoch in range(1, 1501): x, y = X, Y opt.zero_grad() output = model(x) loss = loss_fn(output, y) loss.backward() opt.step() if epoch % 25 == 0: print("EPOCH {} >>> Loss : {:.5f}".format(epoch, loss))
EPOCH 25 >>> Loss : 1.02031 EPOCH 50 >>> Loss : 1.00895 EPOCH 75 >>> Loss : 0.99802 EPOCH 100 >>> Loss : 0.98769 EPOCH 125 >>> Loss : 0.97803 EPOCH 150 >>> Loss : 0.96896 EPOCH 175 >>> Loss : 0.96031 EPOCH 200 >>> Loss : 0.95159 EPOCH 225 >>> Loss : 0.94148 EPOCH 250 >>> Loss : 0.92642 EPOCH 275 >>> Loss : 0.90064 EPOCH 300 >>> Loss : 0.86479 EPOCH 325 >>> Loss : 0.82898 EPOCH 350 >>> Loss : 0.79900 EPOCH 375 >>> Loss : 0.77486 EPOCH 400 >>> Loss : 0.75522 EPOCH 425 >>> Loss : 0.73892 EPOCH 450 >>> Loss : 0.72510 EPOCH 475 >>> Loss : 0.71318 EPOCH 500 >>> Loss : 0.70275 EPOCH 525 >>> Loss : 0.69351 EPOCH 550 >>> Loss : 0.68525 EPOCH 575 >>> Loss : 0.67780 EPOCH 600 >>> Loss : 0.67103 EPOCH 625 >>> Loss : 0.66486 EPOCH 650 >>> Loss : 0.65920 EPOCH 675 >>> Loss : 0.65399 EPOCH 700 >>> Loss : 0.64917 EPOCH 725 >>> Loss : 0.64471 EPOCH 750 >>> Loss : 0.64056 EPOCH 775 >>> Loss : 0.63669 EPOCH 800 >>> Loss : 0.63309 EPOCH 825 >>> Loss : 0.62971 EPOCH 850 >>> Loss : 0.62654 EPOCH 875 >>> Loss : 0.62357 EPOCH 900 >>> Loss : 0.62078 EPOCH 925 >>> Loss : 0.61815 EPOCH 950 >>> Loss : 0.61567 EPOCH 975 >>> Loss : 0.61332 EPOCH 1000 >>> Loss : 0.61111 EPOCH 1025 >>> Loss : 0.60901 EPOCH 1050 >>> Loss : 0.60702 EPOCH 1075 >>> Loss : 0.60513 EPOCH 1100 >>> Loss : 0.60334 EPOCH 1125 >>> Loss : 0.60164 EPOCH 1150 >>> Loss : 0.60002 EPOCH 1175 >>> Loss : 0.59847 EPOCH 1200 >>> Loss : 0.59700 EPOCH 1225 >>> Loss : 0.59560 EPOCH 1250 >>> Loss : 0.59426 EPOCH 1275 >>> Loss : 0.59298 EPOCH 1300 >>> Loss : 0.59175 EPOCH 1325 >>> Loss : 0.59058 EPOCH 1350 >>> Loss : 0.58946 EPOCH 1375 >>> Loss : 0.58838 EPOCH 1400 >>> Loss : 0.58735 EPOCH 1425 >>> Loss : 0.58636 EPOCH 1450 >>> Loss : 0.58541 EPOCH 1475 >>> Loss : 0.58449 EPOCH 1500 >>> Loss : 0.58361
1500번 학습을 하였고, Loss는 순차적으로 잘 줄어든 것을 볼 수 있다.
성능 검증
# 성능 검증 # X, Y를 그대로 넣어서 제대로 분류하는 확인 def calc_acc(output, y): p_m_val, p_m_idx = torch.max(output, dim=1) y_m_val, y_m_idx = torch.max(y, dim=1) return (p_m_idx == y_m_idx).sum() model.eval() output = model(X) acc = calc_acc(output, Y) print("모델이 예측한 값 :",output) print("실제 값 : ", Y) print("정확도 : {:.2f}%".format(acc / 9. * 100.))
모델이 예측한 값 : tensor([[9.4259e-01, 2.4447e-03, 5.4970e-02], [9.4027e-01, 3.1480e-03, 5.6586e-02], [9.3180e-01, 2.2921e-03, 6.5911e-02], [9.0985e-05, 9.5731e-01, 4.2603e-02], [2.1392e-04, 9.5028e-01, 4.9503e-02], [6.0590e-05, 9.5549e-01, 4.4447e-02], [1.0728e-02, 2.2483e-02, 9.6679e-01], [2.6211e-02, 8.5016e-03, 9.6529e-01], [3.7751e-03, 4.9346e-02, 9.4688e-01]], grad_fn=<SoftmaxBackward0>) 실제 값 : tensor([[1., 0., 0.], [1., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 1., 0.], [0., 1., 0.], [0., 0., 1.], [0., 0., 1.], [0., 0., 1.]]) 정확도 : 100.00%
학습했던 데이터에 대해서 정확도는 100%가 나왔다.
물론 과적합일 수도 있지만, 이는 코드 실습에 의의를 두고 싶다.다음 포스팅에서는 흔한 IRIS 데이터를 통한 실습 프로젝트를 진행하고자 한다.
728x90'코딩(Coding) > 기계학습' 카테고리의 다른 글
[기계학습] 합성곱 신경망(CNN : Convolutional Nerual Network) (Part 1/2) (0) 2022.02.09 [기계학습] IRIS 데이터를 분류하는 분류기를 만들어보자(코드 실습) (0) 2022.02.08 [기계학습] 로지스틱 회귀(분류 Classification)(Logistic Regression) (Part 1/2) (0) 2022.01.21 [기계학습] 선형회귀(Linear Regression) (Part 2/2) (0) 2022.01.18 [기계학습] 선형회귀(Linear Regression) (Part 1/2) (0) 2022.01.11