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()

[그림1] 검증 데이터에 대한 정확도와 훈련 데이터에 대한 정확도

 

  • 실선은 검증 데이터에 대한 정확도, 점선은 훈련 데이터에 대한 정확도 
  • 정확도가 높은 순서로 나열

[그림2] 좋은 정확도들 결과

 

 

출처 : 밑바닥부터 시작하는 딥러닝

https://www.hanbit.co.kr/store/books/look.php?p_code=B8475831198

 

밑바닥부터 시작하는 딥러닝

직접 구현하고 움직여보며 익히는 가장 쉬운 딥러닝 입문서

www.hanbit.co.kr

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기