아래 내용들은 제가 혼자 학습하면서 정리한 내용들입니다.
'부족한 내용' 혹은 '잘못된 내용'이 있을 수 있습니다.
댓글 남겨주시면 더욱 공부하고 수정하도록 하겠습니다.
감사합니다.
간단한 분류 모델 구현 예제 : XOR 문제 풀이
PyTorch로 간단한 ANN을 구성하여 XOR 문제를 풀이하는 모델을 만들어보자!!
데이터셋 만들기
- Scikit-Learn의 make_blobs 모듈을 사용해서 XOR 문제의 데이터들을 생성하기
- Train 데이터는 80개, Test 데이터는 20개 생성
from sklearn.datasets import make_blobs
# Train : 80개
x_train, y_train = make_blobs(
random_state = 100,
n_samples = 80, # 생성할 데이터 수
n_features = 2, # 특성 갯수(차원)
centers = [[1, 1], [-1, -1],
[1, -1], [-1, 1]], # 중심점
shuffle = True,
cluster_std = 0.3 # 중심점으로부터의 표준편차
)
# Test : 20개
x_test, y_test = make_blobs(
random_state = 100,
n_samples = 20,
n_features = 2,
centers = [[1, 1], [-1, -1],
[1, -1], [-1, 1]],
shuffle = True,
cluster_std = 0.3
)
- XOR 문제로 풀 것이기 때문에 4개의 Label을 2개로 합쳐주었다.
import numpy as np
# 이진분류 모델 만들기 : 4개의 레이블 -> 2개로 합치기
def label_map(y_, from_, to_):
y = np.copy(y_)
for f in from_:
y[y_ == f] = to_
return y
y_train = label_map(y_train, [0, 1], 0)
y_train = label_map(y_train, [2, 3], 1)
y_test = label_map(y_test, [0, 1], 0)
y_test = label_map(y_test, [2, 3], 1)
데이터셋 확인
import matplotlib.pyplot as plt
plt.title('Train data')
plt.scatter(x_train[:, 0], x_train[:, 1], marker='o', c=y_train, s=100,
edgecolor='k', linewidth=2)
plt.xlabel('')
plt.ylabel('')
plt.show()
![](https://blog.kakaocdn.net/dn/bJtfH8/btrVVRgMcBC/6qyymdSQ5rHtKgD9ljJgK1/img.png)
인공신경망 모델 설계
- PyTorch는 TensorFlow와는 다르게 Class 형태로 모델을 설계한다. (Sequential 한 구현도 가능)
- 모델을 설계할 때는 nn.Module을 상속받는다.
- 이번 모델에서 활성화 함수는 ReLU와 Sigmoid를 사용
- 만들어둔 데이터셋은 PyTorch에서 사용하기 위해 Tensor로 변환
import torch
from torch import nn, optim
x_train = torch.FloatTensor(x_train)
y_train = torch.FloatTensor(y_train)
x_test = torch.FloatTensor(x_test)
y_test = torch.FloatTensor(y_test)
기본 신경망 구조 설계
- 입력층과 하나의 은닉층, 출력층으로 이루어져있는 인공신경망
- input_size와 hidden_size 는 입력값과 은닉층에서의 출력값의 수로 설정. 매개변수로 받아온다.
- Layer는 모두 Fully Connected된 Linear로 구성
- 만들어진 데이터가 이진분류 문제이므로 마지막은 Simoid로 출력한다.
# 신경망 Class 정의
class NeuralNet(torch.nn.Module):
# 생성자
def __init__(self, input_size, hidden_size):
super(NeuralNet, self).__init__()
self.input_size = input_size
self.hidden_size = hidden_size
# 인공신경망 레이어 정의
self.linear1 = nn.Linear(self.input_size, self.hidden_size) # (입력 size, 출력 size)
self.relu = nn.ReLU() # Activation Function
self.linear2 = nn.Linear(self.hidden_size, 1) # (앞 Layer의 출력값, Class수)
self.sigmoid = nn.Sigmoid() # Activation Function
# 순전파
def forward(self, input_tensor):
h1 = self.linear1(input_tensor)
h2 = self.relu(h1)
h3 = self.linear2(h2)
output = self.sigmoid(h3)
return output
변수 설정
- 모델링에 사용할 변수 설정
- lr : 학습률
- epochs : 반복 횟수
- Loss Function은 Binary Cross Entropy
# 변수 설정
lr = 0.03
epochs = 2000
criterion = nn.BCELoss() # Binary Cross Entropy
신경망 모델 생성
- 모델 객체를 생성하고 optimizer를 생성해주었다.
- optimizer 는 확률적 경사하강법(SGD)
# 신경망 객체 생성
model = NeuralNet(2, 5)
# optimizer 정의 : 확률적 경사하강법
# model.parameters() : 모델 내부의 가중치 추출
optimizer = optim.SGD(model.parameters(), lr = lr)
모델 학습하기
for epoch in range(epochs):
model.train()
optimizer.zero_grad()
# 학습 데이터 입력, 결과값 개선
train_output = model(x_train)
# 오차 계산
train_loss = criterion(train_output.squeeze(), y_train)
if epoch % 100 == 0:
print(f'train loss at {epoch} : {train_loss.item()}')
# 오차 역전파
train_loss.backward()
optimizer.step() # 호출할 때마다 가중치를 학습률만큼 갱신
train loss at 0 : 0.027139227837324142
train loss at 100 : 0.026356041431427002
train loss at 200 : 0.025614794343709946
train loss at 300 : 0.024913163855671883
train loss at 400 : 0.024248961359262466
train loss at 500 : 0.023618832230567932
train loss at 600 : 0.02301996573805809
train loss at 700 : 0.02245008945465088
train loss at 800 : 0.02190718613564968
train loss at 900 : 0.021389367058873177
train loss at 1000 : 0.02089502103626728
train loss at 1100 : 0.020422592759132385
train loss at 1200 : 0.019970588386058807
train loss at 1300 : 0.019537832587957382
train loss at 1400 : 0.019123094156384468
train loss at 1500 : 0.018725339323282242
train loss at 1600 : 0.01834356226027012
train loss at 1700 : 0.01797674223780632
train loss at 1800 : 0.01762394607067108
train loss at 1900 : 0.017284326255321503
모델 성능 측정
model.eval() # 평가 모드 바꾸기
test_loss = criterion(torch.squeeze(model(x_test)), y_test)
print(f'학습 후 loss는 {test_loss.item()}')
>>> 학습 후 loss는 0.017321284860372543
모델 저장 및 불러오기
- 마지막으로 만들어진 모델을 저장하고 불러와서 적용시키는 법을 알아보자
모델 저장
# model.state_dict() : 모델의 가중치 저장(딕셔너리)
torch.save(model.state_dict(), './model.pt')
모델 불러오기
# 학습된 모델의 가중치 적용
new_model = NeuralNet(2, 5)
new_model.load_state_dict(torch.load('./model.pt'))
>>> <All keys matched successfully>
새 모델로 성능 평가
new_model.eval()
test_data = torch.FloatTensor([-1, 1])
new_model(test_data ).item()
>>> 0.9995137453079224
Reference
GitHub - yellowjs0304/3-min-pytorch_study: 3분 딥러닝 파이토치맛 - 오픈소스 개인 스터디용
3분 딥러닝 파이토치맛 - 오픈소스 개인 스터디용. Contribute to yellowjs0304/3-min-pytorch_study development by creating an account on GitHub.
github.com
Module — PyTorch 1.13 documentation
Shortcuts
pytorch.org
... 끝!!
'ML & DL > Deep Learning' 카테고리의 다른 글
[DL] Keras fit vs fit_generator (0) | 2023.02.14 |
---|---|
[DL] Tensoflow.Keras ImageDataGenerator (0) | 2023.02.14 |
댓글