728x90
반응형
하이퍼파라미터
- 각 층의 뉴런 수
- 배치 크기
- 매개 변수 갱신 시의 학습률과 가중치 감소 등
- 적절히 설정하지 않으면 모델의 성능이 크게 떨어지기도 한다.
검증 데이터
- 지금까지는 데이터셋 훈련 데이터와 시험 데이터로 분리해 이용
- 하이퍼 파라미터의 성능을 평가할 때는 시험 데이터를 사용해서는 안된다.
- 시험 데이터 사용해 하이퍼 파라미터 조정시 하이퍼파라미터 값이 시험 데이터에 오버피팅되기 때문이다.
- 하이퍼 파라미터 값의 '좋음'을 시험 데이터로 확인하기 되므로 하이퍼 파라미터의 값이 시험 데이터에만 적합하도록 조정되어 버린다. 그렇게 되면 다른 데이터에는 적응하지 못하는 범용 성능이 떨어지는 모델이 될지도 모른다.
- 하이퍼 파라미터 조정시 하이퍼파라미터 전용 확인 데이터가 필요하다.
- 일반적으로 하이퍼파라미터 조정용 데이터를 검증 데이터(validation data)라고 부른다.
훈련 데이터 | 매개변수 학습 |
검증 데이터 | 하이퍼파라미터 성능 평가 |
시험 데이터 | 신경망의 범용 성능 평가 |
MNIST 데이터셋에서 검증 데이터 얻는 가장 간단한 방법
- 훈련 데이터 중 20% 정도를 검증 데이터로 먼저 분리하는 방법
(x_train, t_train), (x_test, t_test) = load_mnist()
# 훈련 데이터 뒤섞기
x_train, t_train = shuffle_dataset(x_train,t_train)
# 20% 를 검증 데이터로 분할
validation_rate = 0.20
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:]
# shuffle_dataset은 np.random.suffle이용
하이퍼파라미터 최적화
- 최적화 핵심은 하이퍼파라미터의 '최적 값'이 존재하는 범위를 조금씩 줄여간다는 점이다.
- 범위를 대략적 설정, 그 범위에서 무작위로 하이퍼 파라미터 값을 골라낸(샘플링) 후, 그 값으로 정확도 평가
- 정확도 잘 살피면서 이 작업을 여러 번 반복해 하이퍼 파라미터의 '최적 값'의 범위를 좁혀가는 것이다.
- 대력적 지정이 효과적 - 실제로도 0.001에서 1.000 사이(10^-3~10^3)와 같이 '10의 거듭제곱'단위로 범위 지정한다.
- 이를 '로그 스케일(log scale)로 지정'한다고 표현
0단계
- 하이퍼파라미터 값의 범위를 설정한다.
1단계
- 설정된 범위에서 하이퍼파라미터의 값을 무작위로 추출
2단계
- 1단계에서 샘플링한 하이퍼파라미터 값을 사용해 학습하고, 검증 데이터로 정확도를 평가한다.(단, 에폭은 작게 설정)
3단계
- 1단계와 2단계를 특정 횟수(100회 등) 반복해, 그 정확도의 결과를 보고 하이퍼파라미터 범위를 좁힌다.
하이퍼파라미터 최적화 구현
weight_decay = 10 ** np.random.uniform(-8,-4)
lr = 10 ** np.random.uniform(-6,-2)
import sys, os
sys.path.append(os.pardir) # 부모 디렉터리의 파일을 가져올 수 있도록 설정
import numpy as np
import matplotlib.pyplot as plt
from mnist import load_mnist
from multi_layer_net import MultiLayerNet
from util import shuffle_dataset
from 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()
- 실선은 검증 데이터에 대한 정확도, 점선은 훈련 데이터에 대한 정확도
- 정확도가 높은 순서로 나열
출처 : 밑바닥부터 시작하는 딥러닝
https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198
728x90
반응형
최근댓글