반응형

Tensorflow.org의 링크 내용을 정리함.


HParams Dashboard로 Hyperparameter 튜닝

    ML모델을 만들때, 레이어에서 dropout 비율 또는 학습률 같은 다양한 하이퍼파라미터를 선택해야 한다. 이런 결정은 정확도 같은 모델의 지표에 영향을 미친다. 따라서 ML 작업에서 중요한 단계는 문제를 위한 가장 좋은 하이퍼파라미터를 구분하는 것이다. 이는 때때로 실험과 연관된다. 이 절차는 하이퍼파라미터 최적화("Hyperparameter Optimization") 또는 하이퍼파라미터 튜닝("Hyperparamter Tuning")으로 알려져 있다.

    텐서보드의 HParams dashboard는 가장 훌륭한 실험 또는 가장 유망한 하이퍼파라미터 셋을 구별하는 처리를 돕는 몇가지 도구를 제공한다.

    이 글에서는 다음 단계에 집중한다.

  1. 실험 설정(experiment setup)과 HParams summary
  2. 하이퍼파라미터와 지표를 로그로 남기기 위한 텐서플로 실행 적용
  3. 실행하고 하나의 부모(parent) 디렉토리에 로그 기록
  4. 텐서보드의 HParams dashboard에 결과 시각화
    Note : HParams summary API와 dashboard UI는 'preview'에 있고 매번 바뀔 것이다.

    텐서플로와 TensorBoard HParams plugin을 import한다.

Source>>

    import tensorflow as tf
    from tensorboard.plugins.hparams import api as hp

    FashionMNIST를 다운로드하고 정규화한다.

Source>>

    fashion_mnist = tf.keras.datasets.fashion_mnist

    (x_train, y_train),(x_test, y_test) = fashion_mnist.load_data()
    x_train, x_test = x_train / 255.0, x_test / 255.0


1. 실험 설정 및 HParams 실험 요약(experiment summary)

    모델에서 3개의 하이퍼파라미터로 실험한다.

  1. 첫번째 밀집(dense)레이어의 유닛 수
  2. Dropout레이어의 드롭아웃 비율
  3. 옵티마이져

    실험을 위한 값을 나열하고, 텐서보드에 실험 설정을 로그로 기록한다. 이 단계는 선택(optional)이다. UI에 좀 더 정확한 하이퍼파라미터의 필터링이 가능하도록 도메잉 정보를 제공할 수도 있고 지표(metrics)가 표시되도록 지정할 수 있다.

Source>>

    HP_NUM_UNITS = hp.HParam('num_units', hp.Discrete([16, 32]))
    HP_DROPOUT = hp.HParam('dropout', hp.RealInterval(0.1, 0.2))
    HP_OPTIMIZER = hp.HParam('optimizer', hp.Discrete(['adam', 'sgd']))

    METRIC_ACCURACY = 'accuracy'

    with tf.summary.create_file_writer('logs/hparam_tuning').as_default():
        hp.hparams_config(
            hparams=[HP_NUM_UNITS, HP_DROPOUT, HP_OPTIMIZER],
            metrics=[hp.Metric(METRIC_ACCURACY, display_name='Accuracy')],
        )

    만약 이 단계를 건너뛰면, 언제든지 문자열을 사용할 수 있지만, 그렇지 않으면, HParam 값을 사용해야 한다. 예를 들면, hparams[HP_DROPOUT'] 대신에 hparams['dropuot']

    tensorboard 관련 API 문서는 도대체 어디 있는걸까?


2. 하이퍼파라미터와 지표 로그 기록을 위한 TensorFlow 적용

    2개의 밀집(dense) 레이어와 그 사이에 드롭아웃 레이어가 있는 간단한 모델을 만들자. 훈련 코드는 하이퍼파라미터가 더이상 하드코딩되어 있지 않지만, 크게 낯설지는 않을 것이다. 대신, 하이퍼파라미터는 hparams 딕셔너리로 제공되어지고 훈련 함수를 통해 사용된다.

Source>>

    def train_test_model(hparams):
        model = tf.keras.models.Sequential([
            tf.keras.layers.Flatten(),
            tf.keras.layers.Dense(hparams[HP_NUM_UNITS], activation=tf.nn.relu),
            tf.keras.layers.Dropout(hparams[HP_DROPOUT]),
            tf.keras.layers.Dense(10, activation=tf.nn.softmax),
        ])
        model.compile(
            optimizer=hparams[HP_OPTIMIZER],
                loss='sparse_categorical_crossentropy',
                metrics=['accuracy'],
        )

        model.fit(x_train, y_train, epochs=1) # Run with 1 epoch to speed things up for demo purposes
        _, accuracy = model.evaluate(x_test, y_test)
        return accuracy

    각 실행에 대해, 하이퍼파라미터와 최종 정확도를 포함한 hparams summary를 로그로 기록한다.

Source>>

    def run(run_dir, hparams):
        with tf.summary.create_file_writer(run_dir).as_default():
            hp.hparams(hparams)  # record the values used in this trial
            accuracy = train_test_model(hparams)
            tf.summary.scalar(METRIC_ACCURACY, accuracy, step=1)

    케라스 모델을 훈련할 때, 이를 직접 기록하는 대신 콜백을 사용할 수 있다.

Source>>

    model.fit(
        ...,
        callbacks=[
            tf.keras.callbacks.TensorBoard(logdir),  # log metrics
            hp.KerasCallback(logdir, hparams),  # log hparams
        ],
    )


3.실행하고 부모 디렉토리 하나에 모두 로그 기록하기

    이제 다른 하이퍼파라미터의 셋으로 각각 훈련하는 여러개의 실험을 시도할 수 있다.

    간단하게, grid search를 사용하자. 각각의 파라미터 조합과 실제 파라미터값의 상한과 하한만으로 시도해보자.

    참고로 더 복잡한 시나리오는, 각 파라미터 값을 임의로 선택하기에 더 효과적일 것이다.(이를 random search라 부른다). 이외에도 사용할 수 있는 더욱 발전된 방법들이 있다.

    몇가지 실험을 수행하자. 이는 몇분정도 걸릴 것이다.

Soruce>>

    session_num = 0

    for num_units in HP_NUM_UNITS.domain.values:
        for dropout_rate in (HP_DROPOUT.domain.min_value, HP_DROPOUT.domain.max_value):
            for optimizer in HP_OPTIMIZER.domain.values:
                hparams = {
                    HP_NUM_UNITS: num_units,
                    HP_DROPOUT: dropout_rate,
                    HP_OPTIMIZER: optimizer,
                }
                run_name = "run-%d" % session_num
                print('--- Starting trial: %s' % run_name)
                print({h.name: hparams[h] for h in hparams})
                run('logs/hparam_tuning/' + run_name, hparams)
                session_num += 1

Result>>

--- Starting trial: run-0
    {'num_units': 16, 'dropout': 0.1, 'optimizer': 'adam'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 35us/sample - loss: 0.7298 - accuracy: 0.7424
    10000/10000 [==============================] - 0s 24us/sample - loss: 0.5277 - accuracy: 0.8148
    --- Starting trial: run-1
    {'num_units': 16, 'dropout': 0.1, 'optimizer': 'sgd'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 31us/sample - loss: 0.9634 - accuracy: 0.6814
    10000/10000 [==============================] - 0s 26us/sample - loss: 0.6483 - accuracy: 0.7786
    --- Starting trial: run-2
    {'num_units': 16, 'dropout': 0.2, 'optimizer': 'adam'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 35us/sample - loss: 0.7699 - accuracy: 0.7304
    10000/10000 [==============================] - 0s 26us/sample - loss: 0.5065 - accuracy: 0.8206
    --- Starting trial: run-3
    {'num_units': 16, 'dropout': 0.2, 'optimizer': 'sgd'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 33us/sample - loss: 1.1120 - accuracy: 0.6143
    10000/10000 [==============================] - 0s 24us/sample - loss: 0.6989 - accuracy: 0.7751
    --- Starting trial: run-4
    {'num_units': 32, 'dropout': 0.1, 'optimizer': 'adam'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 34us/sample - loss: 0.6177 - accuracy: 0.7861
    10000/10000 [==============================] - 0s 27us/sample - loss: 0.4591 - accuracy: 0.8376
    --- Starting trial: run-5
    {'num_units': 32, 'dropout': 0.1, 'optimizer': 'sgd'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 30us/sample - loss: 0.8944 - accuracy: 0.6987
    10000/10000 [==============================] - 0s 27us/sample - loss: 0.6257 - accuracy: 0.7911
    --- Starting trial: run-6
    {'num_units': 32, 'dropout': 0.2, 'optimizer': 'adam'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 34us/sample - loss: 0.6274 - accuracy: 0.7834
    10000/10000 [==============================] - 0s 26us/sample - loss: 0.4594 - accuracy: 0.8398
    --- Starting trial: run-7
    {'num_units': 32, 'dropout': 0.2, 'optimizer': 'sgd'}
    Train on 60000 samples
    60000/60000 [==============================] - 2s 34us/sample - loss: 0.9446 - accuracy: 0.6887
    10000/10000 [==============================] - 0s 26us/sample - loss: 0.6301 - accuracy: 0.7880


4. 텐서보드 HParams plugin에 결과 시각화하기

    HParams dashboard를 이제 사용할 수 있다. 텐서보드를 실행하고 'HParams' 메뉴를 선택한다.

Console>>

    > tensorboard --logdir=logs/hparam_tuning


    대쉬보드의 좌측패널은 HParams dashboard의 모든 뷰에 활성상태인 필터 기능을 제공한다.

  • 대쉬보드에서 보여지는 hyperparameters/metrics 필터
  • 대쉬보드에서 보여지는 hyperparameters/metrics 값 필터
  • 실행 상태 필터 (running, success, ...)
  • Table view에서 hyperparameters/metrics 정렬
  • 보여주기 위한 session group의 수 (많은 실험이 있을때 유용)

    HParams dashboard는 유용한 정보를 갖는 세가지 다른 view가 있다.

  • Table View는 실행, 하이퍼파라미터 그리고 지표를 목록으로 보여준다.
  • Parallel Coordinates View는 각 하이퍼파라미터와 지표에 대해 축(axis)을 따라 진해하는 직선으로 각 실행을 나타낸다. 마우스를 클릭하고 축에서 마우스를 끌어 해당 축을 통과하는 실행만 강조 표시할 영역을 표시한다. 이것은 어떤 그룹의 하이퍼파라미터가 가장 중요한지 구분할때 유용하다. 축 자체는 끌어서 재설정할 수 있다.
  • Scatter Plot View는 각 지표와 하이퍼파라미터/지표 각각을 비교한 표를 보여준다. 이것은 연관성을 구분하는데 도움이 된다. 특정 표에서 영역을 선택하기 위해 마우스를 클릭하고 끌면 다른 표의 해당 세션이 하이라이트 된다.

    Table row, Parallel coordinates line 그리고 Scatter plot market을 클릭하면 해당 세선에 대한 훈련 단계의 함수로 지표(metrics)의 그림을 볼 수 있다.(이 글에서는 각 실행마다 한 단계만 사용되었다.)

    HParams dashboard의 기능을 좀 더 알아보기 위해, 더 많은 실험을 가진 미리 생성된 로그 셋을 다운로드 하고 로그 디렉토리에서 압축 해제 후 텐서보드를 시작하자. 다운로드

Console>>>

    > tensorboard --logdir=logs/hparams_demo_logs


    HParams dashboard에서 다른 뷰를 시도해 볼 수 있다

    예를 들면, Parallel coordinates view에 가고 정확도 축에서 마우스를 끄는 것으로 가장 높은 정확도를 가진 실행을 선택할 수 있다. 이 실행은 옵티마이져 축에서 'adam'을 거쳐 오기 때문에 이 실험에서는 'sgd'보다 'adam'의 더 좋다는 결론을 내릴 수 있다.

반응형

+ Recent posts