본문 바로가기

AI/아이펠_리서치

KerasTuner 와 Tensorboard 로 HyperParameter 시각화하기

KerasTuner 사용하기

https://keras.io/api/keras_tuner/

 

Keras documentation: KerasTuner API

KerasTuner API The Hyperparameters class is used to specify a set of hyperparameters and their values, to be used in the model building function. The Tuner subclasses corresponding to different tuning algorithms are called directly by the user to start the

keras.io

 

KerasTuner 설치

!pip install keras-tuner -q
import keras_tuner as kt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPooling2D
from tensorflow.keras.datasets import mnist
import os

 

HyperModel 클래스 상속 하여 build 메서드 정의

class MyHyperModel(kt.HyperModel):
    def build(self, hp):
        # Sequential 모델 생성
        model = models.Sequential()
        
        # Conv2D 레이어: 입력 이미지를 처리하기 위한 합성곱 레이어
        # 필터 수(filters)를 32에서 128 사이, 32 간격으로 하이퍼파라미터 최적화
        # 커널 크기(kernel_size)는 3 또는 5 중에서 선택
        model.add(layers.Conv2D(
            filters=hp.Int('filters', min_value=32, max_value=128, step=32),
            kernel_size=hp.Choice('kernel_size', values=[3, 5]),
            activation='relu',  # ReLU 활성화 함수 사용
            input_shape=(28, 28, 1)  # 입력 데이터 형태: 28x28 픽셀의 1채널 이미지
        ))
        # MaxPooling 레이어: 특징 맵의 크기를 줄이고 계산량 감소
        model.add(layers.MaxPooling2D(pool_size=2))
        
        # 특징 맵을 1차원 벡터로 변환하여 Dense 레이어에 전달
        model.add(layers.Flatten())
        
        # Dropout 레이어: 하이퍼파라미터를 통해 사용 여부를 결정
        # Dropout은 과적합 방지를 위해 50% 뉴런을 랜덤하게 제외
        if hp.Boolean("dropout"):  # Dropout 사용 여부를 Boolean 하이퍼파라미터로 설정
            model.add(layers.Dropout(0.5))

        # Dense 레이어: 하이퍼파라미터로 유닛 수를 최적화 (32에서 128 사이, 32 간격)
        model.add(layers.Dense(
            units=hp.Int('units', min_value=32, max_value=128, step=32),
            activation='relu'  # ReLU 활성화 함수 사용
        ))
        
        # 출력 레이어: 10개의 클래스(MNIST 숫자 0~9)를 분류하기 위한 소프트맥스 레이어
        model.add(layers.Dense(10, activation='softmax'))

        # 모델 컴파일
        # Adam 최적화 알고리즘 사용, 학습률(learning_rate)을 하이퍼파라미터로 선택
        model.compile(
            optimizer=keras.optimizers.Adam(
                hp.Choice('learning_rate', values=[1e-2, 1e-3, 1e-4])  # 학습률 최적화
            ),
            loss='sparse_categorical_crossentropy',  # 다중 클래스 분류 손실 함수
            metrics=['accuracy']  # 평가 지표로 정확도 사용
        )
        return model

 

카테고리 변수 범위/가능한 값
1. 모델 구조 변수 레이어 수 (num_layers) 1–3
  레이어 유닛 수 (units_{i}) 32–128 (32 간격)
  활성화 함수 (activation) relu, tanh
  CNN 레이어 수 (cnn_layers) 1–3
  필터 개수 (filters_{i}) 32–128 (32 간격)
  커널 크기 (kernel_size) (3, 3), (5, 5)
  풀링 전략 (pooling) max, average
2. 정규화 변수 드롭아웃 비율 (dropout_rate) 0.0–0.5 (0.1 간격)
  L2 정규화 (l2_lambda) 1e-4, 1e-3
3. 데이터 처리 변수 배치 크기 (batch_size) 32, 64, 128
  이미지 정규화 0–1로 값 스케일링
  데이터 증강 회전, 반전, 크롭핑 등
4. 학습 변수 학습률 (learning_rate) 1e-4–1e-2
  옵티마이저 (optimizer) adam, sgd, rmsprop
  에폭 수 (epochs) 5–50
5. 샘플링 및 탐색 전략 샘플링 전략 Uniform, LogUniform, Random, TPE
  탐색 공간 정의 초기 탐색: 넓은 범위미세 조정: 좁은 범위
6. 성능 지표 정확도 (val_accuracy, test_accuracy) 모델 성능의 주요 평가 지표
  손실 (val_loss, test_loss) 손실 평가 지표
  학습 시간 효율성 비교용 보조 지표
7. 모델 비교 변수 모델 타입 (model_type) "mlp", "cnn"
  공통 변수 드롭아웃, 레이어 수, 유닛/필터 수

 

# 하이퍼모델 인스턴스 생성
hypermodel = MyHyperModel()

# 텐서보드 로그 디렉토리 설정
tensorboard_log_dir = "logs/hparam_tuning"
if not os.path.exists(tensorboard_log_dir):
    os.makedirs(tensorboard_log_dir)
tuner = kt.RandomSearch(
    MyHyperModel(),
    objective='val_accuracy',
    max_trials=20,  # 탐색할 하이퍼파라미터 조합 수
    executions_per_trial=1,  # 각 조합당 실행 횟수
    directory='my_dir',
    project_name='my_project'
)
# 콜백 설정 (텐서보드)
# TensorBoard 콜백을 사용하여 학습 중의 로그를 기록
tensorboard_callback = keras.callbacks.TensorBoard(log_dir=tensorboard_log_dir)
# 하이퍼파라미터 검색 수행
tuner.search(x_train, y_train,
             validation_data=(x_test, y_test),
             epochs=25,
             callbacks=[tensorboard_callback])
Trial 20 Complete [00h 01m 51s]
val_accuracy: 0.9919000267982483

Best val_accuracy So Far: 0.9919000267982483
Total elapsed time: 00h 37m 11s

1. 하이퍼파라미터 탐색 공간 정의

MyHyperModel 클래스의 build 메서드에서 하이퍼파라미터를 정의합니다. 여기서 탐색할 하이퍼파라미터는 다음과 같습니다:

  • filters:
    • 합성곱 레이어의 필터 수.
    • 범위: 32~128 (32 단위로 증가).
  • kernel_size:
    • 합성곱 커널의 크기.
    • 선택값: 3 또는 5.
  • units:
    • 완전 연결(Dense) 레이어의 뉴런 수.
    • 범위: 32~128 (32 단위로 증가).
  • learning_rate:
    • Adam 옵티마이저의 학습률.
    • 선택값: 0.01, 0.001, 0.0001.
  • dropout:
    • Dropout 사용 여부.
    • 선택값: True 또는 False.

이 탐색 공간은 총 4 (filters) × 2 (kernel_size) × 4 (units) × 3 (learning_rate) × 2 (dropout) = 192개의 조합을 가집니다.


2. 탐색 전략: Random Search

RandomSearch 는 위에서 정의한 탐색 공간에서 랜덤하게 하이퍼파라미터 조합을 선택합니다.

  • max_trials=20: 총 20개의 하이퍼파라미터 조합을 선택하여 실험합니다. 모든 조합(192개)을 탐색하지 않으며, 일부 랜덤 조합만 실험합니다.
  • 탐색 과정의 특징:
    • 조합이 랜덤으로 선택되므로, 동일한 설정을 반복 실행하면 다른 조합이 선택될 수 있습니다.
    • 랜덤하게 조합을 선택하므로, 최적의 조합을 찾을 확률은 GridSearch 보다 낮을 수 있으나 실행 속도가 빠릅니다.
    • 간단한 Conv2D 모델과 RandomSearch 임에 불구 하고 Colab Pro A100 GPU 에서 30분 이상 소요 되었습니다.

3. 모델 생성 및 컴파일

RandomSearch는 각 실험에서 다음을 수행합니다:

  1. 선택된 하이퍼파라미터로 MyHyperModel.build()를 호출하여 모델 생성.
  2. 모델을 컴파일(Adam 옵티마이저, 손실 함수, 평가 지표 설정).

4. 모델 훈련

  • executions_per_trial=1: 각 하이퍼파라미터 조합에 대해 한 번만 실행합니다.
    • 결과가 불안정할 경우, executions_per_trial 값을 증가시켜 평균 성능을 평가할 수 있습니다.

5. 성능 평가 및 기록

  • 목표(metric)'val_accuracy' (검증 정확도).
    • 각 모델은 훈련 후 검증 데이터에서 성능(정확도)을 평가합니다.
    • RandomSearch는 각 조합의 성능을 기록합니다.

6. 최적의 하이퍼파라미터 선택

  • 20번의 실험이 완료된 후, 가장 높은 val_accuracy 를 기록한 하이퍼파라미터 조합이 선택됩니다.
  • 선택된 최적의 하이퍼파라미터는 다음 코드로 확인할 수 있습니다:
# 최적의 하이퍼파라미터 및 그에 해당하는 trial ID 가져오기
best_trial = tuner.oracle.get_best_trials(num_trials=1)[0]

# 최적의 하이퍼파라미터 가져오기
best_hps = best_trial.hyperparameters

# 출력: 최적의 하이퍼파라미터와 관련된 실험(trial) 정보
print(f"""
Best Trial:
- Trial ID: {best_trial.trial_id}
- The optimal number of filters is {best_hps.get('filters')},
- The optimal kernel size is {best_hps.get('kernel_size')},
- Dropout was {'used' if best_hps.get('dropout') else 'not used'},
- The optimal number of units is {best_hps.get('units')},
- The optimal learning rate is {best_hps.get('learning_rate')}.
""")
Best Trial:
- Trial ID: 19
- The optimal number of filters is 96,
- The optimal kernel size is 5,
- Dropout was used,
- The optimal number of units is 96,
- The optimal learning rate is 0.0001.

 

Tensorboard 에서 시각화

# 텐서보드 실행
%reload_ext tensorboard
%tensorboard --logdir logs/hparam_tuning

  • Trial 17 은 train loss 는 가장 낮으나 validation loss 를 보면 오버피팅이 보임
  • 반면 validation loss 가 가장 낮은 Trial 19 는 오버피팅 현상이 일어 나지 않음
  • dropout 의 활성화 유무로 판단 됨