๋ฐ์ํ
์ฌ๋ฐ๋ฅธ ํ์ต์ ์ํด
Machine Learning์์ Overfitting์ด ๋๋ ์ผ์ด ๋ง์ต๋๋ค. Overiftting(์ค๋ฒํผํ )์ ์ ๊ฒฝ๋ง์ด Training data(ํ๋ จ ๋ฐ์ดํฐ)์๋ง ์ง๋์น๊ฒ ์ ์ฉ๋์ด์ ๊ทธ ์ธ์ ๋ฐ์ดํฐ์๋ ์ ๋๋ก ๋์ํ์ง ๋ชปํ๋ ์ํ์ ๋๋ค.
Overfitting (์ค๋ฒํผํ )
- ์ค๋ฒํผํ ์ ๋งค๊ฐ๋ณ์๊ฐ ๋ง๊ณ ํํ๋ ฅ์ด ๋์ ๋ชจ๋ธ์ธ ๊ฒฝ์ฐ, ํ๋ จ๋ฐ์ดํฐ๊ฐ ์ ์ ๊ฒฝ์ฐ์ ์ฃผ๋ก ์ผ์ด๋ฉ๋๋ค.
- ์ด ๋ ์๊ฑด์ ์ถฉ์กฑํ์ฌ Overiftting(์ค๋ฒํผํ )์ ์ผ์ผ์ผ ๋ณด๊ฒ ์ต๋๋ค.
- MNIST Dataset์ ํ๋ จ๋ฐ์ดํฐ์ค 300๊ฐ๋ง ์ฌ์ฉํ๊ณ , 7-Layer Network๋ฅผ ์ฌ์ฉํด์ Network์ ๋ณต์ก์ฑ์ ๋ํ๋ณด๊ฒ ์ต๋๋ค.
- ๊ฐ Layer์ Neuron์ 100๊ฐ, Activation Function(ํ์ฑํ ํจ์)๋ ReLU ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
# ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ์ฝ๋ (Data Loader)
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)
# ์ค๋ฒํผํ
์ ์ฌํํ๊ธฐ ์ํด ํ์ต ๋ฐ์ดํฐ ์๋ฅผ ์ค์
x_train = x_train[:300]
t_train = t_train[:300]
- ์๋๋ Training์ ์ํํ๋ ์ฝ๋ ์ ๋๋ค.
network = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100, 100, 100], output_size=10,
weight_decay_lambda=weight_decay_lambda)
optimizer = SGD(lr=0.01) # ํ์ต๋ฅ ์ด 0.01์ธ SGD๋ก ๋งค๊ฐ๋ณ์ ๊ฐฑ์
max_epochs = 201
train_size = x_train.shape[0]
batch_size = 100
train_loss_list = []
train_acc_list = []
test_acc_list = []
iter_per_epoch = max(train_size / batch_size, 1)
epoch_cnt = 0
for i in range(1000000000):
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
grads = network.gradient(x_batch, t_batch)
optimizer.update(network.params, grads)
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train)
test_acc = network.accuracy(x_test, t_test)
train_acc_list.append(train_acc)
test_acc_list.append(test_acc)
print("epoch:" + str(epoch_cnt) + ", train acc:" + str(train_acc) + ", test acc:" + str(test_acc))
epoch_cnt += 1
if epoch_cnt >= max_epochs:
break
- train_acc_list์ test_acc_list์๋ epoch๋จ์์ ์ ํ๋๋ฅผ ์ ์ฅํฉ๋๋ค. ๊ทธ๋ํ๋ก ๊ทธ๋ฆฌ๋ฉด ์๋์ ๊ทธ๋ํ ์ฒ๋ผ ๋์ต๋๋ค.
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
markers = {'train': 'o', 'test': 's'}
x = np.arange(max_epochs)
plt.plot(x, train_acc_list, marker='o', label='train', markevery=10)
plt.plot(x, test_acc_list, marker='s', label='test', markevery=10)
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
- Training data๋ฅผ ์ฌ์ฉํ์ฌ ์ธก์ ํ ์ ํ๋๋ 100 epoch๋ฅผ ์ง๋๋ ์์ ๋ถํฐ๋ ๊ฑฐ์ด 100%์ ๋๋ค.
- ๋ค๋ง Test ๋ฐ์ดํฐ์ ๋ํด์๋ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ ๋๋ค. ์ด๋ฌํ ํ์์ Training data์๋ง ์ ์ํด๋ฒ๋ฆฐ, ์ฆ fitting๋๋ฒ๋ฆฐ ๊ฒฐ๊ณผ์ ๋๋ค.
- Training ๋ ์ฌ์ฉ๋์ง ์์ Test data์ ์ ๋๋ก ๋์ํ์ง ๋ชปํ๋ ๊ฒ์ ์ด ๊ทธ๋ํ์์ ํ์ธํ ์ ์์ต๋๋ค.
Weight Decay (๊ฐ์ค์น ๊ฐ์)
Overiftting์ ์ต์ ํ๊ธฐ ์ํด์ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ผ๋ก Weight Decay(๊ฐ์ค์น ๊ฐ์)๋ผ๊ณ ์์ต๋๋ค.
- Training ๊ณผ์ ์์ ํฐ Weight(๊ฐ์ค์น)์ ๋ํด์๋ ๊ทธ์ ์์ํ๋ ํจ๋ํฐ๋ฅผ ๋ถ๊ณผํ์ฌ Overfitting์ ์ต์ ํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- ์๋ Overfitting์ Weight Parameter(๊ฐ์ค์น ๋งค๊ฐ๋ณ์)์ ๊ฐ์ด ์ปค์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ์ผ๋จ, ์ ๊ฒฝ๋ง ํ์ต์ ๋ชฉ์ ์ Loss Function(์์ค ํจ์)์ ๊ฐ์ ์ค์ด๋ ๊ฒ์ ๋๋ค.
- ์๋ฅผ ๋ค์ด๋ณด๋ฉด, ๊ฐ์ค์น ์ ๊ณฑ ๋ ธ๋ฆ(norm. L2 ๋ ธ๋ฆ)์ ์์คํจ์์ ๋ํด์ค๋๋ค.
- ๊ทธ๋ฌ๋ฉด ๊ฐ์ค์น๊ฐ ์ปค์ง๋ ๊ฒ์ ์ต์ ํ ์ ์์ต๋๋ค.
- ์ฌ๊ธฐ์ λ(๋๋ค)๋ ์ ๊ทํ์ ์ธ๊ธฐ๋ฅผ ์กฐ์ ํ๋ ํ์ดํผํ๋ผ๋ฏธํฐ์ด๋ฉฐ, ํฌ๊ฒ ์ค์ ํ ์๋ก ํฐ ๊ฐ์ค์น์ ๋ํ ํ๋ํฐ๊ฐ ์ปค์ง๋๋ค.
- ๋ 1/2λW**2 ์ ์์ชฝ์ 1/2์ 1/2λW**2์ ๋ฏธ๋ถ ๊ฒฐ๊ณผ์ธ λW๋ฅผ ์กฐ์ ํ๋ ์ญํ ์ ์์์ ๋๋ค.
- ํ๋ฒ λ = 0.1๋ก Weight Decay(๊ฐ์ค์น ๊ฐ์)๋ฅผ ์ ์ฉํด ๋ณด๊ฒ ์ต๋๋ค.
Weight Decay (๊ฐ์ค์น ๊ฐ์) Network code (by python)
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ํ์ผ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ค์
import numpy as np
from collections import OrderedDict
from common.layers import *
from common.gradient import numerical_gradient
class MultiLayerNet:
"""์์ ์ฐ๊ฒฐ ๋ค์ธต ์ ๊ฒฝ๋ง
Parameters
----------
input_size : ์
๋ ฅ ํฌ๊ธฐ๏ผMNIST์ ๊ฒฝ์ฐ์ 784๏ผ
hidden_size_list : ๊ฐ ์๋์ธต์ ๋ด๋ฐ ์๋ฅผ ๋ด์ ๋ฆฌ์คํธ๏ผe.g. [100, 100, 100]๏ผ
output_size : ์ถ๋ ฅ ํฌ๊ธฐ๏ผMNIST์ ๊ฒฝ์ฐ์ 10๏ผ
activation : ํ์ฑํ ํจ์ - 'relu' ํน์ 'sigmoid'
weight_init_std : ๊ฐ์ค์น์ ํ์คํธ์ฐจ ์ง์ ๏ผe.g. 0.01๏ผ
'relu'๋ 'he'๋ก ์ง์ ํ๋ฉด 'He ์ด๊น๊ฐ'์ผ๋ก ์ค์
'sigmoid'๋ 'xavier'๋ก ์ง์ ํ๋ฉด 'Xavier ์ด๊น๊ฐ'์ผ๋ก ์ค์
weight_decay_lambda : ๊ฐ์ค์น ๊ฐ์(L2 ๋ฒ์น)์ ์ธ๊ธฐ
"""
def __init__(self, input_size, hidden_size_list, output_size,
activation='relu', weight_init_std='relu', weight_decay_lambda=0):
self.input_size = input_size
self.output_size = output_size
self.hidden_size_list = hidden_size_list
self.hidden_layer_num = len(hidden_size_list)
self.weight_decay_lambda = weight_decay_lambda
self.params = {}
# ๊ฐ์ค์น ์ด๊ธฐํ
self.__init_weight(weight_init_std)
# ๊ณ์ธต ์์ฑ
activation_layer = {'sigmoid': Sigmoid, 'relu': Relu}
self.layers = OrderedDict()
for idx in range(1, self.hidden_layer_num+1):
self.layers['Affine' + str(idx)] = Affine(self.params['W' + str(idx)],
self.params['b' + str(idx)])
self.layers['Activation_function' + str(idx)] = activation_layer[activation]()
idx = self.hidden_layer_num + 1
self.layers['Affine' + str(idx)] = Affine(self.params['W' + str(idx)],
self.params['b' + str(idx)])
self.last_layer = SoftmaxWithLoss()
def __init_weight(self, weight_init_std):
"""๊ฐ์ค์น ์ด๊ธฐํ
Parameters
----------
weight_init_std : ๊ฐ์ค์น์ ํ์คํธ์ฐจ ์ง์ ๏ผe.g. 0.01๏ผ
'relu'๋ 'he'๋ก ์ง์ ํ๋ฉด 'He ์ด๊น๊ฐ'์ผ๋ก ์ค์
'sigmoid'๋ 'xavier'๋ก ์ง์ ํ๋ฉด 'Xavier ์ด๊น๊ฐ'์ผ๋ก ์ค์
"""
all_size_list = [self.input_size] + self.hidden_size_list + [self.output_size]
for idx in range(1, len(all_size_list)):
scale = weight_init_std
if str(weight_init_std).lower() in ('relu', 'he'):
scale = np.sqrt(2.0 / all_size_list[idx - 1]) # ReLU๋ฅผ ์ฌ์ฉํ ๋์ ๊ถ์ฅ ์ด๊น๊ฐ
elif str(weight_init_std).lower() in ('sigmoid', 'xavier'):
scale = np.sqrt(1.0 / all_size_list[idx - 1]) # sigmoid๋ฅผ ์ฌ์ฉํ ๋์ ๊ถ์ฅ ์ด๊น๊ฐ
self.params['W' + str(idx)] = scale * np.random.randn(all_size_list[idx-1], all_size_list[idx])
self.params['b' + str(idx)] = np.zeros(all_size_list[idx])
def predict(self, x):
for layer in self.layers.values():
x = layer.forward(x)
return x
def loss(self, x, t):
"""์์ค ํจ์๋ฅผ ๊ตฌํ๋ค.
Parameters
----------
x : ์
๋ ฅ ๋ฐ์ดํฐ
t : ์ ๋ต ๋ ์ด๋ธ
Returns
-------
์์ค ํจ์์ ๊ฐ
"""
y = self.predict(x)
weight_decay = 0
for idx in range(1, self.hidden_layer_num + 2):
W = self.params['W' + str(idx)]
weight_decay += 0.5 * self.weight_decay_lambda * np.sum(W ** 2)
return self.last_layer.forward(y, t) + weight_decay
def accuracy(self, x, t):
y = self.predict(x)
y = np.argmax(y, axis=1)
if t.ndim != 1 : t = np.argmax(t, axis=1)
accuracy = np.sum(y == t) / float(x.shape[0])
return accuracy
def numerical_gradient(self, x, t):
"""๊ธฐ์ธ๊ธฐ๋ฅผ ๊ตฌํ๋ค(์์น ๋ฏธ๋ถ).
Parameters
----------
x : ์
๋ ฅ ๋ฐ์ดํฐ
t : ์ ๋ต ๋ ์ด๋ธ
Returns
-------
๊ฐ ์ธต์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๋ด์ ๋์
๋๋ฆฌ(dictionary) ๋ณ์
grads['W1']ใgrads['W2']ใ... ๊ฐ ์ธต์ ๊ฐ์ค์น
grads['b1']ใgrads['b2']ใ... ๊ฐ ์ธต์ ํธํฅ
"""
loss_W = lambda W: self.loss(x, t)
grads = {}
for idx in range(1, self.hidden_layer_num+2):
grads['W' + str(idx)] = numerical_gradient(loss_W, self.params['W' + str(idx)])
grads['b' + str(idx)] = numerical_gradient(loss_W, self.params['b' + str(idx)])
return grads
def gradient(self, x, t):
"""๊ธฐ์ธ๊ธฐ๋ฅผ ๊ตฌํ๋ค(์ค์ฐจ์ญ์ ํ๋ฒ).
Parameters
----------
x : ์
๋ ฅ ๋ฐ์ดํฐ
t : ์ ๋ต ๋ ์ด๋ธ
Returns
-------
๊ฐ ์ธต์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๋ด์ ๋์
๋๋ฆฌ(dictionary) ๋ณ์
grads['W1']ใgrads['W2']ใ... ๊ฐ ์ธต์ ๊ฐ์ค์น
grads['b1']ใgrads['b2']ใ... ๊ฐ ์ธต์ ํธํฅ
"""
# forward
self.loss(x, t)
# backward
dout = 1
dout = self.last_layer.backward(dout)
layers = list(self.layers.values())
layers.reverse()
for layer in layers:
dout = layer.backward(dout)
# ๊ฒฐ๊ณผ ์ ์ฅ
grads = {}
for idx in range(1, self.hidden_layer_num+2):
grads['W' + str(idx)] = self.layers['Affine' + str(idx)].dW + self.weight_decay_lambda * self.layers['Affine' + str(idx)].W
grads['b' + str(idx)] = self.layers['Affine' + str(idx)].db
return grads
Test Code
# coding: utf-8
import os
import sys
sys.path.append(os.pardir) # ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ํ์ผ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ค์
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.multi_layer_net import MultiLayerNet
from common.optimizer import SGD
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)
# ์ค๋ฒํผํ
์ ์ฌํํ๊ธฐ ์ํด ํ์ต ๋ฐ์ดํฐ ์๋ฅผ ์ค์
x_train = x_train[:300]
t_train = t_train[:300]
# weight decay๏ผ๊ฐ์ค์น ๊ฐ์ ๏ผ ์ค์ =======================
#weight_decay_lambda = 0 # weight decay๋ฅผ ์ฌ์ฉํ์ง ์์ ๊ฒฝ์ฐ
weight_decay_lambda = 0.1
# ====================================================
network = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100, 100, 100], output_size=10,
weight_decay_lambda=weight_decay_lambda)
optimizer = SGD(lr=0.01) # ํ์ต๋ฅ ์ด 0.01์ธ SGD๋ก ๋งค๊ฐ๋ณ์ ๊ฐฑ์
max_epochs = 201
train_size = x_train.shape[0]
batch_size = 100
train_loss_list = []
train_acc_list = []
test_acc_list = []
iter_per_epoch = max(train_size / batch_size, 1)
epoch_cnt = 0
for i in range(1000000000):
batch_mask = np.random.choice(train_size, batch_size)
x_batch = x_train[batch_mask]
t_batch = t_train[batch_mask]
grads = network.gradient(x_batch, t_batch)
optimizer.update(network.params, grads)
if i % iter_per_epoch == 0:
train_acc = network.accuracy(x_train, t_train)
test_acc = network.accuracy(x_test, t_test)
train_acc_list.append(train_acc)
test_acc_list.append(test_acc)
print("epoch:" + str(epoch_cnt) + ", train acc:" + str(train_acc) + ", test acc:" + str(test_acc))
epoch_cnt += 1
if epoch_cnt >= max_epochs:
break
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ==========
markers = {'train': 'o', 'test': 's'}
x = np.arange(max_epochs)
plt.plot(x, train_acc_list, marker='o', label='train', markevery=10)
plt.plot(x, test_acc_list, marker='s', label='test', markevery=10)
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
- Training Data, Test Data์ ๋ํ ์ ํ๋ ์ฐจ์ด๋ ์ฌ์ ํ ์์ง๋ง, Weight Decay๋ฅผ ์ด์ฉํ์ง ์์ ๊ฒฐ๊ณผ๊ณผ ๋น๊ตํ๋ฉด ์ฐจ์ด๊ฐ ์ค์๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ฆ, Overfitting์ด ์ด๋์ ๋ ์ต์ ๋์๋ค๋ ์๋ฏธ๋ก ๋ณผ ์ ์์ต๋๋ค.
Dropout (๋๋กญ์์)
Weight Decay(๊ฐ์ค์น ๊ฐ์)๋ ๊ฐ๋จํ๊ฒ ๊ตฌํํ ์ ์๊ณ , ์ด๋์ ๋ ์ง๋์น ํ์ต(Overfitting)์ ์ต์ ํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋, ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ด ๋ณต์กํด์ง๋ฉด Weight Decay(๊ฐ์ค์น ๊ฐ์)๋ง์ผ๋ก๋ ๋์ํ๊ธฐ ์ด๋ ค์์ ๋๋ค. ์ด๋ด๋๋ ํํ Dropout(๋๋กญ์์)์ด๋ผ๋ ๊ธฐ๋ฒ์ ์ด์ฉํฉ๋๋ค.
- Dropout์ Neuron์ ์์๋ก ์ญ์ ํ๋ฉด์ ํ์ตํ๋ ๋ฐฉ๋ฒ์ ๋๋ค.
- Training๋, Hidden Layer(์๋์ธต)์ ๋ด๋ฐ์ ๋ฌด์์๋ก ๊ณจ๋ผ์ ์ญ์ ํฉ๋๋ค.
- ๋ฐ์ดํฐ๋ฅผ ํ๋ฆด ๋๋ง๋ค ์ญ์ ํ ๋ด๋ฐ์ ๋ฌด์์๋ก ์ ํํ๊ณ , ์ํ๋๋ ๋ชจ๋ ๋ด๋ฐ์ ์ ํธ๋ฅผ ์ ๋ฌํฉ๋๋ค.
- ๋จ Test๋์ ๊ฐ ๋ด๋ฐ์ ์ถ๋ ฅ์ ํ๋ จ ๋ ์ญ์ ์ํ ๋น์จ์ ๊ณฑํ์ฌ ์ถ๋ ฅํฉ๋๋ค.
- ํ๋ฒ Dropout์ ๊ตฌํํด ๋ณด๊ฒ ์ต๋๋ค. ์๋๋ Dropout์ ๊ตฌํํ ์ฝ๋ ์ ๋๋ค.
class Dropout:
def __init__(self, dropout_ratio=0.5):
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self, x, train_flg=True):
if train_flg:
self.mask = np.random.rand(*x.shape) > self.dropout_ratio
return x * self.mask
else:
return x * (1.0 - self.dropout_ratio)
def backward(self, dout):
return dout*self.mask
- ์ฌ๊ธฐ์ ์ค์ํ๊ฒ ๋ด์ผํ๋์ ์ Training์, Forward Propagation(์์ ํ)๋ ๋ง๋ค self.mask์ ์ญ์ ํ ๋ด๋ฐ์ False๋ก ํ์ํ๋ค๋ ์ ์ ๋๋ค.
- self.mask๋ x์ ํ์๊ณผ ๊ฐ์ ๋ฐฐ์ด์ ๋ฌด์์๋ก ์์ฑํ๊ณ , ๊ทธ ๊ฐ์ด dropout_ratio๋ณด๋ค ํฐ ์์๋ง True๋ก ์ค์ ํฉ๋๋ค.
- Backpropagation(์ญ์ ํ)๋์ ๋์์ ReLU์ ๊ฐ์ต๋๋ค.
- ์ด๋ง์, Forward Propagation(์์ ํ)๋ ์ ํธ๋ฅผ ํต๊ณผ์ํค๋ ๋ด๋ฐ์ Backpropagation(์ญ์ ํ)๋๋ ์ ํธ๋ฅผ ๊ทธ๋๋ก ํต๊ณผ์ํค๊ณ
- Forward Propagation(์์ ํ)๋ ์ ํธ๋ฅผ ํต๊ณผ์ํค์ง ์๋ ๋ด๋ฐ์Backpropagation(์ญ์ ํ)๋๋ ์ ํธ๋ฅผ ์ฐจ๋จํฉ๋๋ค.
- ๊ทธ๋ฌ๋ฉด ํ๋ฒ Dropout์ ํจ๊ณผ๋ฅผ MNIST ๋ฐ์ดํฐ์
์ผ๋ก ํ๋ฒ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
- 7-Layer Network. ๊ฐ Layer์ Neuron์ 100๊ฐ, Activation Function์ ReLU๋ฅผ ์จ์ ์งํํ์ต๋๋ค.
import os
import sys
sys.path.append(os.pardir) # ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ํ์ผ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ค์
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.multi_layer_net_extend import MultiLayerNetExtend
from common.trainer import Trainer
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)
# ์ค๋ฒํผํ
์ ์ฌํํ๊ธฐ ์ํด ํ์ต ๋ฐ์ดํฐ ์๋ฅผ ์ค์
x_train = x_train[:300]
t_train = t_train[:300]
# ๋๋กญ์์ ์ฌ์ฉ ์ ๋ฌด์ ๋น์ธ ์ค์
use_dropout = True # ๋๋กญ์์์ ์ฐ์ง ์์ ๋๋ False
dropout_ratio = 0.2
network = MultiLayerNetExtend(input_size=784, hidden_size_list=[100, 100, 100, 100, 100, 100],
output_size=10, use_dropout=use_dropout, dropout_ration=dropout_ratio)
trainer = Trainer(network, x_train, t_train, x_test, t_test,
epochs=301, mini_batch_size=100,
optimizer='sgd', optimizer_param={'lr': 0.01}, verbose=True)
trainer.train()
train_acc_list, test_acc_list = trainer.train_acc_list, trainer.test_acc_list
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
markers = {'train': 'o', 'test': 's'}
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, marker='o', label='train', markevery=10)
plt.plot(x, test_acc_list, marker='s', label='test', markevery=10)
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()
- ์์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด Dropout์ ์ ์ฉํ๋๊น Train Data, Test Data์ ๋ํ ์ ํ๋ ์ฐจ์ด๊ฐ ์ค์์ต๋๋ค.
- ๊ทธ๋ฆฌ๊ณ Training Data์ ๋ํ ์ ํ๋๊ฐ 100%์๋ ๋๋ฌํ์ง ์๊ฒ ๋์์ต๋๋ค.
- ์ด์ฒ๋ผ Dropout์ ์ด์ฉํ๋ฉด ํํ๋ ฅ์ ๋์ด๋ฉด์๋, Overfitting์ ์ต์ ํ๋ ํจ๊ณผ๊ฐ ์์ต๋๋ค.
์ ์ ํ HyperParameter Value ์ฐพ๊ธฐ
HyperParameter๋ ๊ฐ ์ธต์ Neuron์, Batch size, ๋งค๊ฐ๋ณ์ ๊ฐฑ์ ์์ Learning Rate์ Weight Decay ๋ฑ์ ๋๋ค.
- ํ๋ฒ Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)์ ๊ฐ์ ์ต๋ํ ํจ์จ์ ์ผ๋ก ํ์ํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค.
Validation Data (๊ฒ์ฆ ๋ฐ์ดํฐ)
- Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)๋ฅผ ๋ค์ํ ๊ฐ์ผ๋ก ์ค์ ํ๊ณ ๊ฒ์ฆํ ํ ๋ฐ, ์ฌ๊ธฐ์ ์ฃผ์ํ ์ ์ ํ์ดํผํ๋ผ๋ฏธํฐ์ ์ฑ๋ฅ์ ํ๊ฐํ ๋๋ ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด์ ์ ๋๋ค๋ ๊ฒ์ ๋๋ค.
- Test Data(์ํ ๋ฐ์ดํฐ)๋ฅผ ์ฌ์ฉํ์ฌ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ๋ฉด Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ) ๊ฐ์ด Test Data(์ํ ๋ฐ์ดํฐ)์ Overfitting(์ค๋ฒํผํ )๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
- ๊ทธ๋์ ํ์ดํผํ๋ผ๋ฏธํฐ ์กฐ์ ์ฉ ๋ฐ์ดํฐ๋ฅผ ์ผ๋ฐ์ ์ผ๋ก ๊ฒ์ฆ ๋ฐ์ดํฐ(validation data)๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)์ ์ ์ ์ฑ์ ํ๊ฐํ๋ ๋ฐ์ดํฐ์ธ ์ ์ ๋๋ค.
- ๋ณดํต์ Training Data(ํ๋ จ ๋ฐ์ดํฐ)์ค 20%๋ฅผ Validation Data(๊ฒ์ฆ ๋ฐ์ดํฐ)๋ก ๋ถ๋ฆฌํฉ๋๋ค.
๊ฐ ๋ฐ์ดํฐ์ ์ญํ : Training Data(ํ๋ จ ๋ฐ์ดํฐ - ๋งค๊ฐ๋ณ์ ํ์ต), Validation Data (๊ฒ์ฆ ๋ฐ์ดํฐ - Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ) ์ฑ๋ฅ ํ๊ฐ), Test Data(์ํ ๋ฐ์ดํฐ - ์ ๊ฒธ๋ง์ ๋ฒ์ฉ ์ฑ๋ฅ ํ๊ฐ)
(x_train, t_train), (x_test, t_test) = load_mnist()
# ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ๋ค์์
x_train, t_train = shuffle_dataset(x_train, t_train)
# 20%๋ฅผ ๊ฒ์ฆ ๋ฐ์ดํฐ๋ก ๋ถํ
validation_rate = 0.2
validation_num = int(x_train.shape[0] * validation_rate)
x_val = x_train[:validation_num]
t_val = t_train[:validation_num]
x_train = x_train[validation_num:]
t_train = t_train[validation_num:]
Hyperparameter ์ต์ ํ
Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)๋ฅผ ์ต์ ํํ ๋, ์ต์ ๊ฐ์ด ์กด์ฌํ๋ ๋ฒ์๋ฅผ ์กฐ๊ธ์ฉ ์ค์ฌ๊ฐ๋ค๋ ๊ฒ์ ๋๋ค.
๋ฒ์๋ฅผ ์กฐ๊ธ์ฉ ์ค์ด๋ ค๋ฉด ๋๋ต์ ์ธ ๋ฒ์๋ฅผ ์ค์ ํ๊ณ ๊ทธ ๋ฒ์์์ ๋ฌด์์๋ก Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)๊ฐ์ ์ํ๋งํ ํ, ๊ทธ ๊ฐ์ผ๋ก ์ ํ๋๋ฅผ ํ๊ฐํฉ๋๋ค. ์ด ๊ณผ์ ์ ๋ฐ๋ณตํ์ฌ Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)์ '์ต์ ๊ฐ'์ ๋ฒ์๋ฅผ ์ขํ๊ฐ๋ ๊ฒ์ ๋๋ค.
- ๋ณดํต Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)์ ๋ฒ์๋ '๋๋ต์ ์ผ๋ก' ์ง์ ํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค(0.001~1000)์ฌ์ด.
- ๋ํ Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)๋ฅผ ์ต์ ํํ ๋๋ ์ค๋ ์๊ฐ(๋ฉฐ์น ~๋ช์ฃผ ์ด์)์ด ๊ฑธ๋ฆฝ๋๋ค.
- ๊ทธ๋์ ํ์ต์ ์ํ epoch์ ์๊ฒ ํ์ฌ, 1ํ ํ๊ฐ์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ ๋จ์ถํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค. ์ด ๋ง์ ์์ฝํ๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
- 0๋จ๊ณ
ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ฒ์๋ฅผ ์ค์ ํฉ๋๋ค. - 1๋จ๊ณ
์ค์ ๋ ๋ฒ์์์ ํ์ดํผํ๋ผ๋ฏธํฐ์ ๊ฐ์ ๋ฌด์์๋ก ์ถ์ถํฉ๋๋ค. - 2๋จ๊ณ
1๋จ๊ณ์์ ์ํ๋งํ ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ์ ์ฌ์ฉํ์ฌ ํ์ตํ๊ณ , ๊ฒ์ฆ ๋ฐ์ดํฐ๋ก ์ ํ๋๋ฅผ ํ๊ฐํฉ๋๋ค. (์ํญ์ ์๊ฒ ์ค์ ) - 3๋จ๊ณ
1๋จ๊ณ์ 2๋จ๊ณ๋ฅผ ํน์ ํ์(100ํ ๋ฑ) ๋ฐ๋ณตํ๋ฉฐ, ๊ทธ ์ ํ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๊ณ ํ์ดํผํ๋ผ๋ฏธํฐ์ ๋ฒ์๋ฅผ ์ขํ๋๋ค.
Hyperparameter ์ต์ ํ ๊ตฌํํ๊ธฐ
ํ๋ฒ MNIST ๋ฐ์ดํฐ์ ์ ์ฌ์ฉํ์ฌ ํ์ดํผํ๋ผ๋ฏธํฐ๋ฅผ ์ต์ ํํด๋ณด๊ฒ ์ต๋๋ค.
Learning Rate(ํ์ต๋ฅ )๊ณผ Weight Decay(๊ฐ์ค์น ๊ฐ์)์ ์ธ๊ธฐ๋ฅผ ์กฐ์ ํ๋ ๊ณ์๋ฅผ ํ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
- Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)์ ๋ฌด์์ ์ถ์ถ ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
- (0.001~1000)์ฌ์ด log scale ๋ฒ์ ๋ด์ ๋ฌด์์ ์ถ์ถ
weight_decay = 10 ** np.random.uniform(-8, -4)
lr = 10 ** np.random.uniform(-6, -2)
- ๋ฌด์์๋ก ์ถ์ถํ ๊ฐ์ ์ฌ์ฉํ์ฌ ํ์ต์ ์ํํฉ๋๋ค.
- ๊ทธ ํ, ๋ค์ํ Hyperparameter(ํ์ดํผํ๋ผ๋ฏธํฐ)๊ฐ์ผ๋ก ํ์ต์ ๋ฐ๋ณตํ๋ฉฐ ์ ๊ฒฝ๋ง์ ์ข์ ๊ฒ ๊ฐ์ ๊ฐ์ด ์ด๋์ ์กด์ฌํ๋์ง ๊ด์ฐฐํฉ๋๋ค.
# coding: utf-8
import sys, os
sys.path.append(os.pardir) # ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ํ์ผ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ์ค์
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.multi_layer_net import MultiLayerNet
from common.util import shuffle_dataset
from common.trainer import Trainer
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)
# ๊ฒฐ๊ณผ๋ฅผ ๋น ๋ฅด๊ฒ ์ป๊ธฐ ์ํด ํ๋ จ ๋ฐ์ดํฐ๋ฅผ ์ค์
x_train = x_train[:500]
t_train = t_train[:500]
# 20%๋ฅผ ๊ฒ์ฆ ๋ฐ์ดํฐ๋ก ๋ถํ
validation_rate = 0.20
validation_num = int(x_train.shape[0] * validation_rate)
x_train, t_train = shuffle_dataset(x_train, t_train)
x_val = x_train[:validation_num]
t_val = t_train[:validation_num]
x_train = x_train[validation_num:]
t_train = t_train[validation_num:]
def __train(lr, weight_decay, epocs=50):
network = MultiLayerNet(input_size=784, hidden_size_list=[100, 100, 100, 100, 100, 100],
output_size=10, weight_decay_lambda=weight_decay)
trainer = Trainer(network, x_train, t_train, x_val, t_val,
epochs=epocs, mini_batch_size=100,
optimizer='sgd', optimizer_param={'lr': lr}, verbose=False)
trainer.train()
return trainer.test_acc_list, trainer.train_acc_list
# ํ์ดํผํ๋ผ๋ฏธํฐ ๋ฌด์์ ํ์
optimization_trial = 100
results_val = {}
results_train = {}
for _ in range(optimization_trial):
# ํ์ํ ํ์ดํผํ๋ผ๋ฏธํฐ์ ๋ฒ์ ์ง์
weight_decay = 10 ** np.random.uniform(-8, -4)
lr = 10 ** np.random.uniform(-6, -2)
val_acc_list, train_acc_list = __train(lr, weight_decay)
print("val acc:" + str(val_acc_list[-1]) + " | lr:" + str(lr) + ", weight decay:" + str(weight_decay))
key = "lr:" + str(lr) + ", weight decay:" + str(weight_decay)
results_val[key] = val_acc_list
results_train[key] = train_acc_list
# ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
print("=========== Hyper-Parameter Optimization Result ===========")
graph_draw_num = 20
col_num = 5
row_num = int(np.ceil(graph_draw_num / col_num))
i = 0
for key, val_acc_list in sorted(results_val.items(), key=lambda x:x[1][-1], reverse=True):
print("Best-" + str(i+1) + "(val acc:" + str(val_acc_list[-1]) + ") | " + key)
plt.subplot(row_num, col_num, i+1)
plt.title("Best-" + str(i+1))
plt.ylim(0.0, 1.0)
if i % 5: plt.yticks([])
plt.xticks([])
x = np.arange(len(val_acc_list))
plt.plot(x, val_acc_list)
plt.plot(x, results_train[key], "--")
i += 1
if i >= graph_draw_num:
break
plt.show()
Best-1 (val acc:0.83) | Ir:0.0092, weight dec ay:3.86e - 07
Best-2 (val acc:0.78) | Ir:0.00956, weight dec ay:6.04e - 07
Best-3 (val acc:0.77) | lr:0.00571, weight decay:1.27e - 06
Best-4 (val acc:0.74) | Ir:0.00626, weight decay:1.43e - 05
Best-5 (val acc:0.73) | lr:0.OO52, weight dec ay:8.97e - 06
- ์ด๋ ๊ฒ ์ ์ ํ ๊ฐ์ด ์์นํ ๋ฒ์๋ฅผ ์ขํ๊ฐ๋ค๊ฐ ํน์ ๋จ๊ณ์์ ์ต์ข ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ์ ํ๋ ์ ํํฉ๋๋ค.
Summary
- ๋งค๊ฐ๋ณ์ ๊ฐฑ์ ๋ฐฉ๋ฒ์๋ ํ๋ฅ ์ ๊ฒฝํ ํ๊ฐ๋ฒ(SGD) ์ธ์๋ ๋ชจ๋ฉํ , AdaGrad, Adam ๋ฑ์ด ์์ต๋๋ค.
- ๊ฐ์ค์น ์ด๊น๊ฐ์ ์ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฐ๋ฅธ ํ์ต์ ํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.
- ๊ฐ์ค์น์ ์ด๊น๊ฐ์ผ๋ก๋ Xavier ์ด๊น๊ฐ๊ณผ He ์ด๊น๊ฐ์ด ํจ๊ณผ์ ์ ๋๋ค.
- ๋ฐฐ์น ์ ๊ทํ๋ฅผ ์ด์ฉํ๋ฉด ํ์ต์ ๋น ๋ฅด๊ฒ ์งํํ ์ ์์ผ๋ฉฐ, ์ด๊น๊ฐ์ ์ํฅ์ ๋ ๋ฐ๊ฒ ๋ฉ๋๋ค.
- ์ค๋ฒํผํ ์ ์ต์ ํ๋ ์ ๊ทํ ๊ธฐ์ ๋ก๋ ๊ฐ์ค์น ๊ฐ์์ ๋๋กญ์์์ด ์์ต๋๋ค.
- ํ์ดํผํ๋ผ๋ฏธํฐ ๊ฐ ํ์์ ์ต์ ๊ฐ์ด ์กด์ฌํ ๋ฒํ ๋ฒ์๋ฅผ ์ ์ฐจ ์ขํ๋ฉด์ ํ๋ ๊ฒ์ด ํจ๊ณผ์ ์ ๋๋ค.
๋ฐ์ํ
'๐ฅ๏ธ Deep Learning' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[DL] Convolution & Pooling Layer ๊ตฌํํด๋ณด๊ธฐ (0) | 2024.05.13 |
---|---|
[DL] Convolution Neural Network - CNN (ํฉ์ฑ๊ณฑ ์ ๊ฒฝ๋ง), Convolution Layer, Pooling Layer (0) | 2024.05.12 |
[DL] Batch Normalization - ๋ฐฐ์น ์ ๊ทํ (0) | 2024.05.01 |
[DL] Training Related Skills - SGD, Momentum, AdaGrad, Adam (ํ์ต ๊ด๋ จ ๊ธฐ์ ๋ค) (0) | 2024.04.30 |
[DL] Activation Function - ํ์ฑํ ํจ์ (0) | 2024.04.29 |