MNIST 한번 풀어보려고 오랜만에 Kaggle에 들어가서
Digit Recognizer
Learn computer vision fundamentals with the famous MNIST data
www.kaggle.com
이걸 풀어보려고 했는데 CNN으로 풀려고 했는데 데이터를 1D로 받아서 2D로 만드는 과정이 안돼서 일단 DNN으로 풀었다.
- DNN (Deep Neural Network)
입력층과 출력층 사이에 은닉층이 2개 이상 지닌 학습방법을 뜻한다. DNN은 MLP ( multilayer perceptron) 다층 퍼셉트론 레이어라고도 볼 수 있다. 입력층 사이에 너무 많은 레이어가 들어가도 좋지 않고 적당한 레이어를 넣어야 한다.
간단하게 DNN을 설명하자면 저렇게 볼 수 있고, 바로 문제를 풀면 일단
⭐️중요⭐️ 런타임에 들어가서 잊지 말고 런타임 유형을 GPU로 바꿔줘야한다. 아니면 정말,, 생각보다 코드 돌리는 게 오래 걸린다.
google에 있는 colaboratory를 사용하기 할 것이기 때문에 아래의 코드를 써주고
!pip uninstall -y kaggle
!pip install --upgrade pip
!pip install kaggle
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle
!chmod 600 ~/.kaggle/kaggle.json
데이터를 불러 오기 위해서 data탭에 들어가서 API를 복사해서
코드를 작성하면 아래처럼 나온다
[ Import 라이브러리 ]
import torch
import torch.optim as optim
import torch.nn.functional as F
import pandas as pd
import numpy as np
import random
from sklearn.preprocessing import MinMaxScaler
device = 'cuda' if torch.cuda.is_available() else 'cpu'
random.seed(777)
torch.manual_seed(777)
if device == 'cuda':
torch.cuda.manual_seed_all(777)
[ 데이터 불러오기 ]
원래 train 데이터가 저렇게 생겼기 때문에 .loc으로 필요한 부분만 뽑아와 준다.
train = pd.read_csv('train.csv',header = None)
test = pd.read_csv('test.csv',header = None)
x_train = train.loc[1:,1:]
y_train = train.loc[1:,0]
x_train = np.array(x_train,dtype=float)
y_train = np.array(y_train,dtype=float)
x_train = torch.FloatTensor(x_train)
y_train = torch.LongTensor(y_train)
train_dataset = torch.utils.data.TensorDataset(x_train,y_train)
data_loader = torch.utils.data.DataLoader(dataset=train_dataset,
batch_size = batch_size,
shuffle = True,
drop_last = True)
데이터 셋을 만들어주고 data_loader는 batch size만큼 데이터를 잘라서 꺼내 준다고 보면 된다.
shuffle - 데이터를 섞어주는 역할
drop_last - 만약에 데이터가 30이고 batch size가 4면 마지막 batch는 2개가 될 텐데 이것을 버릴 건지 아니면 사용할 건지 결정하는 것인데 True면 버리고 False면 그냥 사용한다.
[ 모델 정의 ]
linear1 = torch.nn.Linear(784,512,bias = True)
linear2 = torch.nn.Linear(512,512,bias = True)
linear3 = torch.nn.Linear(512,512,bias = True)
linear4 = torch.nn.Linear(512,512,bias = True)
linear5 = torch.nn.Linear(512,10,bias = True)
relu = torch.nn.ReLU()
dropout = torch.nn.Dropout(p = 0.3)
torch.nn.init.xavier_uniform_(linear1.weight)
torch.nn.init.xavier_uniform_(linear2.weight)
torch.nn.init.xavier_uniform_(linear3.weight)
torch.nn.init.xavier_uniform_(linear4.weight)
torch.nn.init.xavier_uniform_(linear5.weight)
Linear 하나하나가 레이어가 되는데 1번과 5번은 각각 입력층과 출력층이 된다.
입력이 28*28이지만 1D로 들어가기 때문에 784로 설정하고 나갈 때는 0 - 9까지의 숫자가 되기 때문에 마지막은 10이 된다.
중간 은닉층의 숫자는 바꿔도 상관없다.
초기화 방법은 xavier_uniform을 사용하였고
relu와 dropout은 다음 게시물로 설명해야겠다.
relu는 activation function인데 종류가 엄청 여러 가지이다.
model = torch.nn.Sequential(linear1,relu,dropout,
linear2,relu,dropout,
linear3,relu,dropout,
linear4,relu,dropout,
linear5).to(device)
학습을 위해 차례차례 쌓아주는데 마지막 relu와 dropout을 사용하면 성능이 많이 떨어지기 때문에 빼준다.
loss = torch.nn.CrossEntropyLoss().to(device)
optimzier = optim.Adam(model.parameters(),lr = lr)
결국 이 문제도 분류 문제이기 때문에 loss함수는 CrossEntropyLoss를 사용하고
optimizer는 Adam을 사용하였다.
opimizer의 종류도 다양하기 때문에 다음에 다루도록 해야겠다.
[ 모델 학습 ]
total_batch = len(data_loader)
for epoch in range(epochs):
avg_cost = 0
for x,y in data_loader:
x = x.to(device)
y = y.to(device)
optimzier.zero_grad()
hypo = model(x)
cost = loss(hypo,y)
cost.backward()
optimzier.step()
avg_cost += cost / total_batch
print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.9f}'.format(avg_cost))
seed값을 바꿀 때마다 다를 수 있긴 하지만 이 정도 나왔고, 제출하고 나니까
95% 정도의 성능을 내는 것을 볼 수 있다.
CNN을 사용하면 더 높은 성능을 낼 수 있기 때문에 다음에는 CNN으로 돌아와야겠다 ㅎ,,,ㅎ,
'CODING > AI & ML & DL' 카테고리의 다른 글
[기계학습] Bias - Variance Decomposition (0) | 2020.09.29 |
---|---|
[기계학습] 다중선형회귀 & 경사하강법 | Multiple Linear Regression & Gradient Descent (0) | 2020.09.28 |
[기계학습] KNN | K - 최근접 이웃 알고리즘 (5) | 2020.09.21 |
[기계학습/데이터 전처리] 2 . 데이터 정제 & 통합 & 불균형 해결 (0) | 2020.09.14 |
[기계학습/데이터 전처리] 1. 데이터 실수화 & 데이터 변환 ( 표준화 / 정규화 ) (0) | 2020.09.12 |
댓글