<Pytorch>
: 딥러닝을 위한 framework
- Pytorch - regression
1. data set을 setting
-> train set과 validation set. test set을 설정한 후, numpy로 값을 한번 살펴본다.
대게 비율이 8:1:1, 7:2:1로 설정
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
# ====== Generating Dataset ====== #
num_data = 2400
x1 = np.random.rand(num_data) * 10
x2 = np.random.rand(num_data) * 10
e = np.random.normal(0, 0.5, num_data)
X = np.array([x1, x2]).T
y = 2*np.sin(x1) + np.log(0.5*x2**2) + e
# ====== Split Dataset into Train, Validation, Test ======#
train_X, train_y = X[:1600, :], y[:1600]
val_X, val_y = X[1600:2000, :], y[1600:2000]
test_X, test_y = X[2000:, :], y[2000:]
# ====== Visualize Each Dataset ====== #
fig = plt.figure(figsize=(12,5))
ax1 = fig.add_subplot(1, 3, 1, projection='3d')
ax1.scatter(train_X[:, 0], train_X[:, 1], train_y, c=train_y, cmap='jet')
ax1.set_xlabel('x1')
ax1.set_ylabel('x2')
ax1.set_zlabel('y')
ax1.set_title('Train Set Distribution')
ax1.set_zlim(-10, 6)
ax1.view_init(40, -60)
ax1.invert_xaxis()
ax2 = fig.add_subplot(1, 3, 2, projection='3d')
ax2.scatter(val_X[:, 0], val_X[:, 1], val_y, c=val_y, cmap='jet')
ax2.set_xlabel('x1')
ax2.set_ylabel('x2')
ax2.set_zlabel('y')
ax2.set_title('Validation Set Distribution')
ax2.set_zlim(-10, 6)
ax2.view_init(40, -60)
ax2.invert_xaxis()
ax3 = fig.add_subplot(1, 3, 3, projection='3d')
ax3.scatter(test_X[:, 0], test_X[:, 1], test_y, c=test_y, cmap='jet')
ax3.set_xlabel('x1')
ax3.set_ylabel('x2')
ax3.set_zlabel('y')
ax3.set_title('Test Set Distribution')
ax3.set_zlim(-10, 6)
ax3.view_init(40, -60)
ax3.invert_xaxis()
plt.show()
2. Model define
:내가 사용하고자하는 Model을 정의한다. Model class의 init 단에서 model의 input features와 output features를 설정한다. -> 각각 얼마의 node인가를 설정, 현재 input의 값이 2차원이므로 x1과 x2 feature이 2이다.
후에 input값이 들어왔을 때 output 값은 무엇인가
import torch
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=1, bias=True)
def forward(self, x):
# 인스턴스(샘플) x가 인풋으로 들어왔을 때 모델이 예측하는 y값을 리턴합니다.
return self.linear(x)
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=1)
self.relu = nn.ReLU()
def forward(self, x):
# 인스턴스(샘플) x가 인풋으로 들어왔을 때 모델이 예측하는 y값을 리턴합니다.
x = self.linear1(x)
x = self.relu(x)
x = self.linear2(x)
return x
3. Loss function 정의
reg_loss = nn.MSELoss()
4. Train & Evaluation
:model을 생성한 후, learining rate과 optimizer를 생성한다. epoch 횟수 또한 정해준 후, 학습을 진행한다.
** 이때 모든 data를 torch.Tensor로 바꿔줘야한다.
import torch.optim as optim
from sklearn.metrics import mean_absolute_error
# ====== Construct Model ====== #
# model = LinearModel()
# print(model.linear.weight)
# print(model.linear.bias)
model = MLPModel() # Model을 생성해줍니다.
print('{} parameters'.format(sum(p.numel() for p in model.parameters() if p.requires_grad))) # 복잡해보이지만 간단히 모델 내에 학습을 당할 파라미터 수를 카운팅하는 코드입니다.
# ===== Construct Optimizer ====== #
lr = 0.005 # Learning Rate를 하나 정해줍니다. (원할한 학습을 위해 손을 많이 탑니다)
optimizer = optim.SGD(model.parameters(), lr=lr) # Optimizer를 생성해줍니다.
# 매 학습 단계에서의 epoch값과 그 때의 loss 값을 저장할 리스트를 만들어줍시다.
list_epoch = []
list_train_loss = []
list_val_loss = []
list_mae = []
list_mae_epoch = []
epoch = 4000 # 학습 횟수(epoch)을 지정해줍시다.
for i in range(epoch):
# ====== Train ====== #
model.train() # model을 train 모드로 세팅합니다. 반대로 향후 모델을 평가할 때는 eval() 모드로 변경할 겁니다 (나중 실습에서 쓸 겁니다)
optimizer.zero_grad() # optimizer에 남아있을 수도 있는 잔여 그라디언트를 0으로 다 초기화해줍니다.
input_x = torch.Tensor(train_X)
true_y = torch.Tensor(train_y)
pred_y = model(input_x)
#print(input_x.shape, true_y.shape, pred_y.shape) # 각 인풋과 아웃풋의 차원을 체크해봅니다.
loss = reg_loss(pred_y.squeeze(), true_y)
loss.backward() # backward()를 통해서 그라디언트를 구해줍니다.
optimizer.step() # step()을 통해서 그라디언틀르 바탕으로 파라미터를 업데이트 해줍니다.
list_epoch.append(i)
list_train_loss.append(loss.detach().numpy())
# ====== Validation ====== #
model.eval()
optimizer.zero_grad()
input_x = torch.Tensor(val_X)
true_y = torch.Tensor(val_y)
pred_y = model(input_x)
loss = reg_loss(pred_y.squeeze(), true_y)
list_val_loss.append(loss.detach().numpy())
# ====== Evaluation ======= #
if i % 200 == 0: # 200회의 학습마다 실제 데이터 분포와 모델이 예측한 분포를 그려봅니다.
# ====== Calculate MAE ====== #
model.eval()
optimizer.zero_grad()
input_x = torch.Tensor(test_X)
true_y = torch.Tensor(test_y)
pred_y = model(input_x).detach().numpy()
mae = mean_absolute_error(true_y, pred_y) # sklearn 쪽 함수들은 true_y 가 먼저, pred_y가 나중에 인자로 들어가는 것에 주의합시다
list_mae.append(mae)
list_mae_epoch.append(i)
fig = plt.figure(figsize=(15,5))
# ====== True Y Scattering ====== #
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()
# ====== Predicted Y Scattering ====== #
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()
# ====== Just for Visualizaing with High Resolution ====== #
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)
4. report
fig = plt.figure(figsize=(15,5))
# ====== Loss Fluctuation ====== #
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(list_epoch, list_train_loss, label='train_loss')
ax1.plot(list_epoch, list_val_loss, '--', label='val_loss')
ax1.set_xlabel('epoch')
ax1.set_ylabel('loss')
ax1.set_ylim(0, 5)
ax1.grid()
ax1.legend()
ax1.set_title('epoch vs loss')
# ====== Metric Fluctuation ====== #
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(list_mae_epoch, list_mae, marker='x', label='mae metric')
ax2.set_xlabel('epoch')
ax2.set_ylabel('mae')
ax2.grid()
ax2.legend()
ax2.set_title('epoch vs mae')
plt.show()
<pytorch GPU 사용>
GPU를 보게되면 작은 ALU가 굉장히 많다. => 산술 연산 속도가 굉장히 빠르다.
model = MLPModel(784, 10, [1000])
## cuda를 사용할 수 있으면 cuda를 사용하고 없으면 cpu를 사용하라.
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
model.to(device)
## data들도 cuda로 보내야함
input_X = input_X.to(device)
true_y = true_y.to(device)
input_X = input_X.squeeze()
input_X = input_X.view(-1, 784)
'Project > NFT 블록체인을 활용한 딥러닝 기반 사진 거래 웹 애플리케이션 구축' 카테고리의 다른 글
이미지 특징 정보 추출 (0) | 2021.08.03 |
---|---|
[연구실] 프로젝트 정리 (0) | 2021.07.27 |
[연구실] 1. YOLO 논문 (0) | 2021.07.19 |
인공지능 되짚어보기 (0) | 2021.07.18 |
[1주차] 파이썬을 활용한 데이터 분석 (0) | 2021.06.30 |