
이 블로그글은 2019년 조재영(Kevin Jo), 김승수(SeungSu Kim)님의 딥러닝 홀로서기 세미나를 수강하고 작성한 글임을 밝힙니다.
Github 링크 : 실습 코드 링크
→ 성능을 확인할려면 Test의 X데이터를 통해 Pred y를 예측하고 제출하여 채점하는 방법밖에 없음
→ Train 데이터를 다시 Train 데이터와 Valid 데이터 셋으로 나눠서 Train 데이터로 학습하고 Valid 데이터로 평가
💡 목표 : Classification Problem을 PyTorch로 해결해보기
Logistic Regression과 MLP를 둘 다 구현해보고 모델의 예측 데이터 분포를 시각화해서 MLP가 실제로 non-linear Decision-Boundary를 가질 수 있는지 살펴보자
# Pytorch 불러오기
import torch
print(torch.__version__)
# 나머지 모듈 불러오기
import numpy as np
import matplotlib.pyplot as plt

r = np.random.rand(10000) * 3
theta = np.random.rand(10000) * 2 * np.pi
y = r.astype(int)
r = r * (np.cos(theta) + 1)
x1 = r * np.cos(theta)
x2 = r * np.sin(theta)
X = np.array([x1, x2]).T
train_X, train_y = X[:8000, :], y[:8000]
val_X, val_y = X[8000:9000, :], y[8000:9000]
test_X, test_y = X[9000:, :], y[9000:]
💡 참고
pytorch에서 데이터 셋은 첫 번째 차원은 샘플의 개수를 나타내도록 설계되어 있음
# 데이터셋 시각화
fig = plt.figure(figsize=(12, 5))
ax1 = fig.add_subplot(1, 3, 1)
ax1.scatter(train_X[:, 0], train_X[:, 1], c=train_y, s=0.7)
ax1.set_xlabel('x1')
ax1.set_ylabel('x2')
ax1.set_title('Train set Distribution')
ax2 = fig.add_subplot(1, 3, 2)
ax2.scatter(val_X[:,0], val_X[:,1], c=val_y)
ax2.set_xlabel('x1')
ax2.set_ylabel('x2')
ax2.set_title('Validation set Distribution')
ax3 = fig.add_subplot(1, 3, 3)
ax3.scatter(test_X[:,0], test_X[:,1], c=test_y)
ax3.set_xlabel('x1')
ax3.set_ylabel('x2')
ax3.set_title('Test set Distribution')
plt.show()


nn.module을 상속받아 새로운 신경망 모델 클래스를 정의__init__은 클래스 초기화 메서드 (생성자)forward는 입력 x를 받아 선형 변환을 적용하는 출력값을 반환하는 메서드import torch.nn as nn
class LinearModel(nn.Module):
def __init__(self):
super(LinearModel, self).__init__()
self.linear = nn.Linear(in_features=2, out_features=3, bias=True)
def foward(self, x):
return self.linear(x)
nn.Module을 상속받아 다층 퍼셉트론 모델 클래스를 정의__init__은 클래스 초기화 메서드(생성자)forward는 입력 x를 받아 순전파(forward pass)를 수행하는 메서드class MLPModel(nn.Module):
def __init__(self):
super(MLPModel, self).__init__()
self.linear1 = nn.Linear(in_features=2, out_features=200)
self.linear2 = nn.Linear(in_features=200, out_features=3)
self.relu = nn.ReLU()
def forward(self, x):
x = self.linear1(x)
x = self.relu(x)
x = self.linear2(x)
return x
N X NumClass 차원을 가지는 float 형태여야하고 target은 N 차원을 가지고 각 엘리멘트의 i번째 클래스를 나타내는 int형이여야함cls_loss = nn.CrossEntropyLoss()

import torch.optim as optim
from sklearn.metrics import accuracy_score
#**model = LinearModel()
#print(model.linear.weight)
#print(model.linear.bias)**
model = MLPModel()
print(f'{sum(p.numel() for p in model.parameters() if p.requires_grad)} Parameters')
lr = 0.005
optimizer = optim.SGD(model.parameters(), lr=lr)
Train 부분
list_epoch = []
list_train_loss = []
list_val_loss = []
list_mae = []
list_mae_epoch = []
epoch = 4000
for i in range(epoch):
# Trian
model.train()
optimizer.zero_grad()
input_x = torch.Tensor(train_X)
true_y = torch.Tensor(train_y).long()
pred_y = model(input_x)
loss = cls_loss(pred_y.squeeze(), true_y)
loss.backward()
optimizer.step()
list_epoch.append(i)
list_train_loss.append(loss.detach().numpy())
# Validate
model.eval()
optimizer.zero_grad()
input_x = torch.Tensor(val_X)
true_y = torch.Tensor(val_y).long()
pred_y = model(input_x)
loss = cls_loss(pred_y.squeeze(), true_y)
list_val_loss.append(loss.detach().numpy())
if i % 200 == 0:
model.eval()
optimizer.zero_grad()
input_x = torch.Tensor(test_X)
true_y = torch.Tensor(test_y).long()
pred_y = model(input_x).detach().max(dim=1)[1].numpy()
mae = mean_absolute_error(true_y, pred_y)
list_mae.append(mae)
list_mae_epoch.append(i)
fig = plt.figure(figsize=(15,5))
ax1 = fig.add_subplot(1, 3, 1, projection='3d')
ax1.scatter(test_X[:, 0], test_X[:, 1], test_y, c=test_y, cmap='jet')
ax1.set_xlabel('x1')
ax1.set_ylabel('x2')
ax1.set_zlabel('y')
ax1.set_zlim(-10, 6)
ax1.view_init(40, -40)
ax1.set_title('True test y')
ax1.invert_xaxis()
ax2 = fig.add_subplot(1, 3, 2, projection='3d')
ax2.scatter(test_X[:, 0], test_X[:, 1], pred_y, c=pred_y[:,0], cmap='jet')
ax2.set_xlabel('x1')
ax2.set_ylabel('x2')
ax2.set_zlabel('y')
ax2.set_zlim(-10, 6)
ax2.view_init(40, -40)
ax2.set_title('Predicted test y')
ax2.invert_xaxis()
input_x = torch.Tensor(train_X)
pred_y = model(input_x).detach().numpy()
ax3 = fig.add_subplot(1, 3, 3, projection='3d')
ax3.scatter(train_X[:, 0], train_X[:, 1], pred_y, c=pred_y[:,0], cmap='jet')
ax3.set_xlabel('x1')
ax3.set_ylabel('x2')
ax3.set_zlabel('y')
ax3.set_zlim(-10, 6)
ax3.view_init(40, -40)
ax3.set_title('Predicted train y')
ax3.invert_xaxis()
plt.show()
print(i, loss)



