반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

https://d2l.ai/chapter_hyperparameter-optimization/sh-async.html

 

19.5. Asynchronous Successive Halving — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.5. Asynchronous Successive Halving

 

As we have seen in Section 19.3, we can accelerate HPO by distributing the evaluation of hyperparameter configurations across either multiple instances or multiples CPUs / GPUs on a single instance. However, compared to random search, it is not straightforward to run successive halving (SH) asynchronously in a distributed setting. Before we can decide which configuration to run next, we first have to collect all observations at the current rung level. This requires to synchronize workers at each rung level. For example, for the lowest rung level r min, we first have to evaluate all N=η**k configurations, before we can promote the 1/η of them to the next rung level.

 

섹션 19.3에서 살펴본 것처럼 하이퍼파라미터 구성 평가를 여러 인스턴스 또는 단일 인스턴스의 여러 CPU/GPU에 분산하여 HPO를 가속화할 수 있습니다. 그러나 무작위 검색에 비해 분산 설정에서 비동기적으로 연속 반감기(SH)를 실행하는 것은 간단하지 않습니다. 다음에 실행할 구성을 결정하기 전에 먼저 현재 단계 수준에서 모든 관찰을 수집해야 합니다. 이를 위해서는 각 단계 수준에서 작업자를 동기화해야 합니다. 예를 들어, 가장 낮은 단계 수준 r min의 경우 먼저 모든 N=eta**k 구성을 평가해야 그 중 1/eta를 다음 단계 수준으로 승격할 수 있습니다.

 

In any distributed system, synchronization typically implies idle time for workers. First, we often observe high variations in training time across hyperparameter configurations. For example, assuming the number of filters per layer is a hyperparameter, then networks with less filters finish training faster than networks with more filters, which implies idle worker time due to stragglers. Moreover, the number of slots in a rung level is not always a multiple of the number of workers, in which case some workers may even sit idle for a full batch.

 

모든 분산 시스템에서 동기화는 일반적으로 작업자의 유휴 시간을 의미합니다. 첫째, 우리는 하이퍼파라미터 구성 전반에 걸쳐 훈련 시간의 높은 변동을 자주 관찰합니다. 예를 들어, 레이어당 필터 수가 하이퍼파라미터라고 가정하면 필터가 적은 네트워크는 필터가 많은 네트워크보다 훈련을 더 빨리 완료합니다. 이는 낙오자로 인한 유휴 작업자 시간을 의미합니다. 또한 단계 수준의 슬롯 수가 항상 작업자 수의 배수가 되는 것은 아니며, 이 경우 일부 작업자는 전체 배치 동안 유휴 상태로 있을 수도 있습니다.

 

Figure Fig. 19.5.1 shows the scheduling of synchronous SH with η=2 for four different trials with two workers. We start with evaluating Trial-0 and Trial-1 for one epoch and immediately continue with the next two trials once they are finished. We first have to wait until Trial-2 finishes, which takes substantially more time than the other trials, before we can promote the best two trials, i.e., Trial-0 and Trial-3 to the next rung level. This causes idle time for Worker-1. Then, we continue with Rung 1. Also, here Trial-3 takes longer than Trial-0, which leads to an additional ideling time of Worker-0. Once, we reach Rung-2, only the best trial, Trial-0, remains which occupies only one worker. To avoid that Worker-1 idles during that time, most implementaitons of SH continue already with the next round, and start evaluating new trials (e.g Trial-4) on the first rung.

 

그림 그림 19.5.1은 2명의 워커를 사용한 4가지 다른 시도에 대해 θ=2인 동기식 SH의 스케줄링을 보여줍니다. 한 에포크 동안 Trial-0과 Trial-1을 평가하는 것으로 시작하고, 완료되면 다음 두 번의 시도를 즉시 계속합니다. 가장 좋은 두 가지 시도, 즉 Trial-0과 Trial-3을 다음 단계로 승격하려면 먼저 다른 시도보다 훨씬 더 많은 시간이 걸리는 Trial-2가 완료될 때까지 기다려야 합니다. 이로 인해 Worker-1의 유휴 시간이 발생합니다. 그런 다음 Rung 1을 계속 진행합니다. 또한 여기서 Trial-3은 Trial-0보다 시간이 오래 걸리므로 Worker-0의 추가 유휴 시간이 발생합니다. 일단 Rung-2에 도달하면 가장 좋은 시도인 Trial-0만 남고 작업자는 한 명만 차지합니다. 해당 시간 동안 Worker-1이 유휴 상태가 되는 것을 방지하기 위해 대부분의 SH 구현은 이미 다음 라운드에서 계속되고 첫 번째 단계에서 새로운 시도(예: Trial-4) 평가를 시작합니다.

 

Fig. 19.5.1  Synchronous successive halving with two workers.

 

Asynchronous successive halving (ASHA) (Li et al., 2018) adapts SH to the asynchronous parallel scenario. The main idea of ASHA is to promote configurations to the next rung level as soon as we collected at least η observations on the current rung level. This decision rule may lead to suboptimal promotions: configurations can be promoted to the next rung level, which in hindsight do not compare favourably against most others at the same rung level. On the other hand, we get rid of all synchronization points this way. In practice, such suboptimal initial promotions have only a modest impact on performance, not only because the ranking of hyperparameter configurations is often fairly consistent across rung levels, but also because rungs grow over time and reflect the distribution of metric values at this level better and better. If a worker is free, but no configuration can be promoted, we start a new configuration with r = r min, i.e the first rung level.

 

비동기 연속 반감기(ASHA)(Li et al., 2018)는 SH를 비동기 병렬 시나리오에 적용합니다. ASHA의 주요 아이디어는 현재 단계 수준에서 최소 eta 관측치를 수집하자마자 구성을 다음 단계 수준으로 승격시키는 것입니다. 이 결정 규칙은 최적이 아닌 승격으로 이어질 수 있습니다. 구성은 다음 단계 수준으로 승격될 수 있으며, 돌이켜보면 동일한 단계 수준의 대부분의 다른 단계와 비교했을 때 호의적이지 않습니다. 반면에 우리는 이런 방식으로 모든 동기화 지점을 제거합니다. 실제로 이러한 최적이 아닌 초기 승격은 성능에 미미한 영향만 미칠 뿐입니다. 이는 초매개변수 구성의 순위가 단계 수준 전체에서 상당히 일관되는 경우가 많을 뿐만 아니라 단계가 시간이 지남에 따라 증가하고 이 수준에서 메트릭 값의 분포를 더 잘 반영하고 더 잘 반영하기 때문입니다. 더 나은. 작업자가 무료이지만 승격할 수 있는 구성이 없으면 r = r min으로 새 구성, 즉 첫 번째 단계 수준을 시작합니다.

 

Fig. 19.5.2 shows the scheduling of the same configurations for ASHA. Once Trial-1 finishes, we collect the results of two trials (i.e Trial-0 and Trial-1) and immediately promote the better of them (Trial-0) to the next rung level. After Trial-0 finishes on rung 1, there are too few trials there in order to support a further promotion. Hence, we continue with rung 0 and evaluate Trial-3. Once Trial-3 finishes, Trial-2 is still pending. At this point we have 3 trials evaluated on rung 0 and one trial evaluated already on rung 1. Since Trial-3 performs worse than Trial-0 at rung 0, and η = 2, we cannot promote any new trial yet, and Worker-1 starts Trial-4 from scratch instead. However, once Trial-2 finishes and scores worse than Trial-3, the latter is promoted towards rung 1. Afterwards, we collected 2 evaluations on rung 1, which means we can now promote Trial-0 towards rung 2. At the same time, Worker-1 continues with evaluating new trials (i.e., Trial-5) on rung 0.

 

그림 19.5.2는 ASHA에 대한 동일한 구성의 스케줄링을 보여줍니다. Trial-1이 완료되면 두 가지 시도(즉, Trial-0 및 Trial-1)의 결과를 수집하고 그 중 더 나은 것(Trial-0)을 즉시 다음 단계 수준으로 승격합니다. 평가판 0이 단계 1에서 끝난 후에는 추가 승격을 지원하기에는 시도 횟수가 너무 적습니다. 따라서 우리는 단계 0을 계속 진행하고 평가판 3을 평가합니다. 평가판 3이 끝나면 평가판 2가 계속 보류됩니다. 이 시점에서 우리는 단계 0에서 평가된 3개의 시도와 단계 1에서 이미 평가된 하나의 시도를 가지고 있습니다. Trial-3은 단계 0에서 Trial-0보다 성능이 떨어지고 θ = 2이므로 아직 새로운 시도를 승격할 수 없으며 Worker- 1은 대신 Trial-4를 처음부터 시작합니다. 그러나 평가판 2가 완료되고 평가판 3보다 낮은 점수를 받으면 후자는 단계 1로 승격됩니다. 이후 단계 1에서 2개의 평가를 수집했습니다. 이는 이제 평가판 0을 단계 2로 승격할 수 있음을 의미합니다. , 작업자-1은 단계 0에서 새로운 시도(즉, 시도 5)를 계속 평가합니다.

 

Fig. 19.5.2  Asynchronous successive halving (ASHA) with two workers.

 

import logging
from d2l import torch as d2l

logging.basicConfig(level=logging.INFO)
import matplotlib.pyplot as plt
from syne_tune import StoppingCriterion, Tuner
from syne_tune.backend.python_backend import PythonBackend
from syne_tune.config_space import loguniform, randint
from syne_tune.experiments import load_experiment
from syne_tune.optimizer.baselines import ASHA

위의 코드는 HPO(Hyperparameter Optimization) 실험을 수행하기 위한 설정을 위한 코드입니다. 주요 라이브러리와 로깅 설정을 포함하고 있습니다.

  • import logging: 로깅(logging)을 위한 파이썬 라이브러리를 가져옵니다.
  • from d2l import torch as d2l: "d2l" 라이브러리에서 "torch" 모듈을 가져옵니다. 이 모듈은 PyTorch 기반의 딥 러닝 코드 작성을 지원합니다.
  • logging.basicConfig(level=logging.INFO): 로깅 레벨을 INFO로 설정하고 기본 로깅 구성을 초기화합니다. 이를 통해 코드 실행 중에 로그 메시지를 출력할 수 있습니다.
  • import matplotlib.pyplot as plt: Matplotlib을 사용하여 그래프를 그리기 위한 모듈을 가져옵니다.
  • from syne_tune import StoppingCriterion, Tuner: SyneTune 라이브러리에서 StoppingCriterion과 Tuner 클래스를 가져옵니다. 이 클래스들은 HPO 실험을 관리하고 조정하는 데 사용됩니다.
  • from syne_tune.backend.python_backend import PythonBackend: SyneTune에서 사용하는 백엔드(backend) 중 하나인 PythonBackend를 가져옵니다. 백엔드는 HPO 실험을 실행하는 방식을 지정합니다.
  • from syne_tune.config_space import loguniform, randint: HPO 실험에서 사용할 하이퍼파라미터 공간을 정의하기 위해 loguniform과 randint 등의 함수를 가져옵니다. 이 함수들을 사용하여 하이퍼파라미터를 샘플링할 수 있습니다.
  • from syne_tune.experiments import load_experiment: SyneTune에서 실험을 로드하고 관리하기 위한 함수를 가져옵니다.
  • from syne_tune.optimizer.baselines import ASHA: ASHA(Hyperband 기반의 비동기 하이퍼파라미터 최적화 알고리즘)를 가져옵니다. ASHA는 하이퍼파라미터 최적화에 사용되는 알고리즘 중 하나입니다.
INFO:root:SageMakerBackend is not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
INFO:root:Ray Tune schedulers and searchers are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[raytune]'
or (for everything)
   pip install 'syne-tune[extra]'

 

19.5.1. Objective Function

 

We will use Syne Tune with the same objective function as in Section 19.3.

 

섹션 19.3과 동일한 목적 함수를 사용하여 Syne Tune을 사용하겠습니다.

 

def hpo_objective_lenet_synetune(learning_rate, batch_size, max_epochs):
    from syne_tune import Reporter
    from d2l import torch as d2l

    model = d2l.LeNet(lr=learning_rate, num_classes=10)
    trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1)
    data = d2l.FashionMNIST(batch_size=batch_size)
    model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
    report = Reporter()
    for epoch in range(1, max_epochs + 1):
        if epoch == 1:
            # Initialize the state of Trainer
            trainer.fit(model=model, data=data)
        else:
            trainer.fit_epoch()
        validation_error = trainer.validation_error().cpu().detach().numpy()
        report(epoch=epoch, validation_error=float(validation_error))

위의 코드는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 최적화를 수행하는 목적 함수(hpo_objective_lenet_synetune)를 정의한 부분입니다. 이 함수는 LeNet 아키텍처를 사용하여 이미지 분류 모델을 훈련하고, 각 하이퍼파라미터 설정에 대한 검증 오차(validation error)를 반환합니다.

주요 내용은 다음과 같습니다.

  • learning_rate, batch_size, max_epochs 등의 하이퍼파라미터를 입력으로 받습니다.
  • model = d2l.LeNet(lr=learning_rate, num_classes=10): 주어진 학습률(learning_rate)과 클래스 수(num_classes)를 가지고 LeNet 모델을 생성합니다.
  • trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1): 하이퍼파라미터 최적화를 위한 트레이너를 생성합니다. max_epochs는 1로 설정되어 있으므로 하나의 에포크만 훈련됩니다.
  • data = d2l.FashionMNIST(batch_size=batch_size): Fashion MNIST 데이터셋을 로드하고 주어진 배치 크기(batch_size)로 데이터를 미니배치 형태로 제공합니다.
  • model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn): 초기화 함수 d2l.init_cnn을 사용하여 모델을 초기화합니다.
  • report = Reporter(): 실험 결과를 기록하기 위한 Reporter 객체를 생성합니다.
  • 반복문을 통해 에포크(epoch)를 1부터 max_epochs까지 증가시키면서 모델을 훈련합니다.
  • 에포크가 1인 경우에는 트레이너를 초기화하고 모델을 훈련시킵니다.
  • 에포크가 1보다 큰 경우에는 trainer.fit_epoch()를 호출하여 한 번의 에포크를 추가로 훈련시킵니다.
  • trainer.validation_error().cpu().detach().numpy()를 통해 검증 오차(validation error)를 계산하고 반환합니다.
  • report(epoch=epoch, validation_error=float(validation_error))를 사용하여 현재 에포크와 검증 오차를 Reporter에 기록합니다.

즉, 이 함수는 주어진 하이퍼파라미터 설정으로 모델을 훈련하고 검증 오차를 반환하는 역할을 합니다. SyneTune은 이 함수를 사용하여 다양한 하이퍼파라미터 설정을 시도하고 최적의 설정을 찾습니다.

 

 

We will also use the same configuration space as before:

 

또한 이전과 동일한 구성 공간을 사용합니다.

 

min_number_of_epochs = 2
max_number_of_epochs = 10
eta = 2

config_space = {
    "learning_rate": loguniform(1e-2, 1),
    "batch_size": randint(32, 256),
    "max_epochs": max_number_of_epochs,
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 최적화를 수행할 때 사용되는 설정과 초기 하이퍼파라미터 값을 정의하는 부분입니다. 주요 내용은 다음과 같습니다.

  • min_number_of_epochs: 실험에서 허용하는 최소 에포크 수입니다. 이 값은 2로 설정되어 있습니다.
  • max_number_of_epochs: 실험에서 허용하는 최대 에포크 수입니다. 이 값은 10으로 설정되어 있습니다.
  • eta: Successive Halving 알고리즘에서 사용되는 파라미터로, 곱셈 연산을 수행할 때 사용됩니다. 이 값은 2로 설정되어 있습니다.
  • config_space: 하이퍼파라미터 공간을 정의하는 부분입니다. 여기서는 세 가지 하이퍼파라미터인 learning_rate, batch_size, max_epochs의 범위를 지정합니다.
    • learning_rate: 로그균등 분포(loguniform distribution)를 사용하여 1e-2에서 1 사이의 값으로 설정됩니다.
    • batch_size: 균등 분포(uniform distribution)를 사용하여 32에서 256 사이의 정수 값으로 설정됩니다.
    • max_epochs: max_number_of_epochs로 설정된 최대 에포크 값을 가집니다.
  • initial_config: 초기 하이퍼파라미터 설정을 정의하는 부분입니다. 여기서는 learning_rate를 0.1로, batch_size를 128로 초기화합니다.

이러한 설정과 초기값은 하이퍼파라미터 최적화 실험을 수행할 때 사용됩니다. SyneTune 라이브러리를 통해 하이퍼파라미터 탐색을 진행하면서 이러한 설정 범위 내에서 하이퍼파라미터 값을 조정하고 최적의 설정을 찾게 됩니다.

 

19.5.2. Asynchronous Scheduler

 

First, we define the number of workers that evaluate trials concurrently. We also need to specify how long we want to run random search, by defining an upper limit on the total wall-clock time.

 

먼저, 동시에 시험을 평가하는 작업자 수를 정의합니다. 또한 총 벽시계 시간의 상한을 정의하여 무작위 검색을 실행할 기간을 지정해야 합니다.

 

n_workers = 2  # Needs to be <= the number of available GPUs
max_wallclock_time = 12 * 60  # 12 minutes

위의 코드는 하이퍼파라미터 최적화 실험을 수행할 때 사용되는 두 가지 중요한 설정을 나타냅니다.

  • n_workers: 실험 도중에 병렬로 실행되는 워커(작업자)의 수를 나타냅니다. 이 수는 사용 가능한 GPU 수보다 작거나 같아야 합니다. 여기서는 2로 설정되어 있으므로 최대 2개의 GPU 또는 병렬 작업자를 사용할 수 있음을 의미합니다.
  • max_wallclock_time: 하이퍼파라미터 최적화 실험의 최대 시간을 분 단위로 나타냅니다. 이 값은 12 * 60으로 설정되어 있으므로 최대 12시간(720분) 동안 실험을 진행할 수 있음을 의미합니다. 실험 시간이 이 설정 값 이내에 끝나도록 실험을 조절합니다.

 

The code for running ASHA is a simple variation of what we did for asynchronous random search.

 

ASHA를 실행하기 위한 코드는 비동기 무작위 검색을 위해 수행한 작업의 간단한 변형입니다.

 

mode = "min"
metric = "validation_error"
resource_attr = "epoch"

scheduler = ASHA(
    config_space,
    metric=metric,
    mode=mode,
    points_to_evaluate=[initial_config],
    max_resource_attr="max_epochs",
    resource_attr=resource_attr,
    grace_period=min_number_of_epochs,
    reduction_factor=eta,
)

위의 코드는 하이퍼파라미터 최적화 실험에서 사용되는 스케줄러인 ASHA (Asynchronous Successive Halving Algorithm)를 설정하는 부분입니다.

  • mode: ASHA 알고리즘에서 최적화할 메트릭의 모드를 나타냅니다. "min"으로 설정되어 있으므로 이 알고리즘은 가장 낮은 값을 찾는 데 초점을 맞추게 됩니다.
  • metric: ASHA 알고리즘에서 최적화할 메트릭의 이름을 나타냅니다. 이 경우 "validation_error"로 설정되어 있으므로 검증 오차(validation error)를 최소화하려고 시도합니다.
  • resource_attr: 실험에서 사용할 리소스 속성을 나타냅니다. 여기서는 "epoch"으로 설정되어 있으므로 에포크(epoch) 수를 리소스로 사용하여 하이퍼파라미터 최적화를 수행합니다.
  • max_resource_attr: ASHA 알고리즘에서 사용할 최대 리소스 속성을 지정합니다. 이 경우 "max_epochs"로 설정되어 있으므로 최대 에포크 수가 사용됩니다.
  • grace_period: ASHA 알고리즘에서 고려할 하이퍼파라미터를 선택하는데 필요한 최소 리소스 수를 나타냅니다. 이 값은 "min_number_of_epochs"로 설정되어 있으므로 최소 에포크 수만큼 리소스가 할당된 경우에만 하이퍼파라미터가 선택됩니다.
  • reduction_factor: ASHA 알고리즘에서 에포크 수를 줄이는 비율을 나타냅니다. 이 값은 "eta"로 설정되어 있으므로 2입니다. 이것은 각 라운드에서 절반씩 에포크 수를 줄이는 것을 의미합니다.

ASHA 스케줄러는 하이퍼파라미터 최적화를 수행하는 데 사용되며, 리소스 속성을 기반으로 하이퍼파라미터 검색을 조절하는 데 도움을 줍니다.

INFO:syne_tune.optimizer.schedulers.fifo:max_resource_level = 10, as inferred from config_space
INFO:syne_tune.optimizer.schedulers.fifo:Master random_seed = 3140976097

 

Here, metric and resource_attr specify the key names used with the report callback, and max_resource_attr denotes which input to the objective function corresponds to r max. Moreover, grace_period provides r min, and reduction_factor is η. We can run Syne Tune as before (this will take about 12 minutes):

 

여기에서 metric 및 resources_attr은 보고서 콜백과 함께 사용되는 키 이름을 지정하고 max_resource_attr은 목적 함수에 대한 입력이 r max에 해당하는지 나타냅니다. 또한, Grace_기간은 r min을 제공하고, 감소_인자는 θ입니다. 이전과 같이 Syne Tune을 실행할 수 있습니다(약 12분 소요).

 

trial_backend = PythonBackend(
    tune_function=hpo_objective_lenet_synetune,
    config_space=config_space,
)

stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time)
tuner = Tuner(
    trial_backend=trial_backend,
    scheduler=scheduler,
    stop_criterion=stop_criterion,
    n_workers=n_workers,
    print_update_interval=int(max_wallclock_time * 0.6),
)
tuner.run()

위의 코드는 ASHA 스케줄러를 사용하여 하이퍼파라미터 최적화 실험을 실행하는 부분입니다.

  • trial_backend: 실험을 실행하는 백엔드(Backend)를 설정합니다. 여기서는 PythonBackend를 사용하며, tune_function에는 hpo_objective_lenet_synetune 함수를, config_space에는 하이퍼파라미터 검색 공간을 설정합니다. 이 백엔드는 Python 함수를 호출하여 실험을 실행합니다.
  • stop_criterion: ASHA 스케줄러를 중지시키는 기준을 설정합니다. max_wallclock_time은 실험을 실행할 최대 시간(분)을 설정하며, 이 값은 12 * 60으로 설정되어 있으므로 12분 동안 실험을 실행한 후 중지됩니다.
  • tuner: Tuner 클래스를 사용하여 최적화 프로세스를 설정합니다. trial_backend에는 백엔드 설정, scheduler에는 ASHA 스케줄러, stop_criterion에는 중지 기준, n_workers에는 사용할 워커(실험 실행 프로세스) 수를 설정합니다. print_update_interval은 중간 업데이트를 출력하는 간격을 설정하며, max_wallclock_time의 60%에 해당하는 값으로 설정됩니다.
  • tuner.run(): 이 명령은 하이퍼파라미터 최적화 실험을 실행합니다. ASHA 스케줄러를 사용하여 여러 하이퍼파라미터 조합을 평가하고 최적의 하이퍼파라미터를 찾습니다. 실험이 실행되는 동안 중간 업데이트가 출력됩니다.
INFO:syne_tune.tuner:results of trials will be saved on /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046
INFO:root:Detected 4 GPUs
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1 --batch_size 128 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/0/checkpoints
INFO:syne_tune.tuner:(trial 0) - scheduled config {'learning_rate': 0.1, 'batch_size': 128, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.44639554136672527 --batch_size 196 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/1/checkpoints
INFO:syne_tune.tuner:(trial 1) - scheduled config {'learning_rate': 0.44639554136672527, 'batch_size': 196, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.011548051321691994 --batch_size 254 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/2/checkpoints
INFO:syne_tune.tuner:(trial 2) - scheduled config {'learning_rate': 0.011548051321691994, 'batch_size': 254, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.14942487313193167 --batch_size 132 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/3/checkpoints
INFO:syne_tune.tuner:(trial 3) - scheduled config {'learning_rate': 0.14942487313193167, 'batch_size': 132, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 1 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.06317157191455719 --batch_size 242 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/4/checkpoints
INFO:syne_tune.tuner:(trial 4) - scheduled config {'learning_rate': 0.06317157191455719, 'batch_size': 242, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.48801815412811467 --batch_size 41 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/5/checkpoints
INFO:syne_tune.tuner:(trial 5) - scheduled config {'learning_rate': 0.48801815412811467, 'batch_size': 41, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.5904067586747807 --batch_size 244 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/6/checkpoints
INFO:syne_tune.tuner:(trial 6) - scheduled config {'learning_rate': 0.5904067586747807, 'batch_size': 244, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08812857364095393 --batch_size 148 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/7/checkpoints
INFO:syne_tune.tuner:(trial 7) - scheduled config {'learning_rate': 0.08812857364095393, 'batch_size': 148, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.012271314788363914 --batch_size 235 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/8/checkpoints
INFO:syne_tune.tuner:(trial 8) - scheduled config {'learning_rate': 0.012271314788363914, 'batch_size': 235, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 5 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08845692598296777 --batch_size 236 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/9/checkpoints
INFO:syne_tune.tuner:(trial 9) - scheduled config {'learning_rate': 0.08845692598296777, 'batch_size': 236, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.0825770880068151 --batch_size 75 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/10/checkpoints
INFO:syne_tune.tuner:(trial 10) - scheduled config {'learning_rate': 0.0825770880068151, 'batch_size': 75, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.20235201406823256 --batch_size 65 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/11/checkpoints
INFO:syne_tune.tuner:(trial 11) - scheduled config {'learning_rate': 0.20235201406823256, 'batch_size': 65, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.3359885631737537 --batch_size 58 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/12/checkpoints
INFO:syne_tune.tuner:(trial 12) - scheduled config {'learning_rate': 0.3359885631737537, 'batch_size': 58, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.7892434579795236 --batch_size 89 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/13/checkpoints
INFO:syne_tune.tuner:(trial 13) - scheduled config {'learning_rate': 0.7892434579795236, 'batch_size': 89, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1233786579597858 --batch_size 176 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/14/checkpoints
INFO:syne_tune.tuner:(trial 14) - scheduled config {'learning_rate': 0.1233786579597858, 'batch_size': 176, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 13 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.13707981127012328 --batch_size 141 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/15/checkpoints
INFO:syne_tune.tuner:(trial 15) - scheduled config {'learning_rate': 0.13707981127012328, 'batch_size': 141, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02913976299993913 --batch_size 116 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/16/checkpoints
INFO:syne_tune.tuner:(trial 16) - scheduled config {'learning_rate': 0.02913976299993913, 'batch_size': 116, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.033362897489792855 --batch_size 154 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/17/checkpoints
INFO:syne_tune.tuner:(trial 17) - scheduled config {'learning_rate': 0.033362897489792855, 'batch_size': 154, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.29442952580755816 --batch_size 210 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/18/checkpoints
INFO:syne_tune.tuner:(trial 18) - scheduled config {'learning_rate': 0.29442952580755816, 'batch_size': 210, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10214259921521483 --batch_size 239 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/19/checkpoints
INFO:syne_tune.tuner:(trial 19) - scheduled config {'learning_rate': 0.10214259921521483, 'batch_size': 239, 'max_epochs': 10}
INFO:syne_tune.tuner:tuning status (last metric is reported)
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0    Stopped     4       0.100000         128          10    4.0          0.430578    29.093798
        1  Completed    10       0.446396         196          10   10.0          0.205652    72.747496
        2    Stopped     2       0.011548         254          10    2.0          0.900570    13.729115
        3    Stopped     8       0.149425         132          10    8.0          0.259171    58.980305
        4    Stopped     4       0.063172         242          10    4.0          0.900579    27.773950
        5  Completed    10       0.488018          41          10   10.0          0.140488   113.171314
        6    Stopped    10       0.590407         244          10   10.0          0.193776    70.364757
        7    Stopped     2       0.088129         148          10    2.0          0.899955    14.169738
        8    Stopped     2       0.012271         235          10    2.0          0.899840    13.434274
        9    Stopped     2       0.088457         236          10    2.0          0.899801    13.034437
       10    Stopped     4       0.082577          75          10    4.0          0.385970    35.426524
       11    Stopped     4       0.202352          65          10    4.0          0.543102    34.653495
       12    Stopped    10       0.335989          58          10   10.0          0.149558    90.924182
       13  Completed    10       0.789243          89          10   10.0          0.144887    77.365970
       14    Stopped     2       0.123379         176          10    2.0          0.899987    12.422906
       15    Stopped     2       0.137080         141          10    2.0          0.899983    13.395153
       16    Stopped     4       0.029140         116          10    4.0          0.900532    27.834111
       17    Stopped     2       0.033363         154          10    2.0          0.899996    13.407285
       18 InProgress     1       0.294430         210          10    1.0          0.899878     6.126259
       19 InProgress     0       0.102143         239          10      -                 -            -
2 trials running, 18 finished (3 until the end), 437.07s wallclock-time

INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02846298236356246 --batch_size 115 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/20/checkpoints
INFO:syne_tune.tuner:(trial 20) - scheduled config {'learning_rate': 0.02846298236356246, 'batch_size': 115, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.037703019195187606 --batch_size 91 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/21/checkpoints
INFO:syne_tune.tuner:(trial 21) - scheduled config {'learning_rate': 0.037703019195187606, 'batch_size': 91, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.0741039859356903 --batch_size 192 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/22/checkpoints
INFO:syne_tune.tuner:(trial 22) - scheduled config {'learning_rate': 0.0741039859356903, 'batch_size': 192, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.3032613031191755 --batch_size 252 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/23/checkpoints
INFO:syne_tune.tuner:(trial 23) - scheduled config {'learning_rate': 0.3032613031191755, 'batch_size': 252, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.019823425532533637 --batch_size 252 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/24/checkpoints
INFO:syne_tune.tuner:(trial 24) - scheduled config {'learning_rate': 0.019823425532533637, 'batch_size': 252, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.8203370335228594 --batch_size 77 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/25/checkpoints
INFO:syne_tune.tuner:(trial 25) - scheduled config {'learning_rate': 0.8203370335228594, 'batch_size': 77, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2960420911378594 --batch_size 104 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/26/checkpoints
INFO:syne_tune.tuner:(trial 26) - scheduled config {'learning_rate': 0.2960420911378594, 'batch_size': 104, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2993874715754653 --batch_size 192 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/27/checkpoints
INFO:syne_tune.tuner:(trial 27) - scheduled config {'learning_rate': 0.2993874715754653, 'batch_size': 192, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.08056711961080017 --batch_size 36 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/28/checkpoints
INFO:syne_tune.tuner:(trial 28) - scheduled config {'learning_rate': 0.08056711961080017, 'batch_size': 36, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.26868380288030347 --batch_size 151 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/29/checkpoints
INFO:syne_tune.tuner:(trial 29) - scheduled config {'learning_rate': 0.26868380288030347, 'batch_size': 151, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 29 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.9197404791177789 --batch_size 66 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/tune_function --tune_function_hash e03d187e043d2a17cae636d6af164015 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046/30/checkpoints
INFO:syne_tune.tuner:(trial 30) - scheduled config {'learning_rate': 0.9197404791177789, 'batch_size': 66, 'max_epochs': 10}
INFO:syne_tune.stopping_criterion:reaching max wallclock time (720), stopping there.
INFO:syne_tune.tuner:Stopping trials that may still be running.
INFO:syne_tune.tuner:Tuning finished, results of trials can be found on /home/ci/syne-tune/python-entrypoint-2023-08-18-20-01-52-046
--------------------
Resource summary (last result is reported):
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0    Stopped     4       0.100000         128          10      4          0.430578    29.093798
        1  Completed    10       0.446396         196          10     10          0.205652    72.747496
        2    Stopped     2       0.011548         254          10      2          0.900570    13.729115
        3    Stopped     8       0.149425         132          10      8          0.259171    58.980305
        4    Stopped     4       0.063172         242          10      4          0.900579    27.773950
        5  Completed    10       0.488018          41          10     10          0.140488   113.171314
        6    Stopped    10       0.590407         244          10     10          0.193776    70.364757
        7    Stopped     2       0.088129         148          10      2          0.899955    14.169738
        8    Stopped     2       0.012271         235          10      2          0.899840    13.434274
        9    Stopped     2       0.088457         236          10      2          0.899801    13.034437
       10    Stopped     4       0.082577          75          10      4          0.385970    35.426524
       11    Stopped     4       0.202352          65          10      4          0.543102    34.653495
       12    Stopped    10       0.335989          58          10     10          0.149558    90.924182
       13  Completed    10       0.789243          89          10     10          0.144887    77.365970
       14    Stopped     2       0.123379         176          10      2          0.899987    12.422906
       15    Stopped     2       0.137080         141          10      2          0.899983    13.395153
       16    Stopped     4       0.029140         116          10      4          0.900532    27.834111
       17    Stopped     2       0.033363         154          10      2          0.899996    13.407285
       18    Stopped     8       0.294430         210          10      8          0.241193    52.089688
       19    Stopped     2       0.102143         239          10      2          0.900002    12.487762
       20    Stopped     2       0.028463         115          10      2          0.899995    14.100359
       21    Stopped     2       0.037703          91          10      2          0.900026    14.664848
       22    Stopped     2       0.074104         192          10      2          0.901730    13.312770
       23    Stopped     2       0.303261         252          10      2          0.900009    12.725821
       24    Stopped     2       0.019823         252          10      2          0.899917    12.533380
       25    Stopped    10       0.820337          77          10     10          0.196842    81.816103
       26    Stopped    10       0.296042         104          10     10          0.198453    81.121330
       27    Stopped     4       0.299387         192          10      4          0.336183    24.610689
       28 InProgress     9       0.080567          36          10      9          0.203052   104.303746
       29  Completed    10       0.268684         151          10     10          0.222814    68.217289
       30 InProgress     1       0.919740          66          10      1          0.900037    10.070776
2 trials running, 29 finished (4 until the end), 723.70s wallclock-time

validation_error: best 0.1404876708984375 for trial-id 5
--------------------

 

Note that we are running a variant of ASHA where underperforming trials are stopped early. This is different to our implementation in Section 19.4.1, where each training job is started with a fixed max_epochs. In the latter case, a well-performing trial which reaches the full 10 epochs, first needs to train 1, then 2, then 4, then 8 epochs, each time starting from scratch. This type of pause-and-resume scheduling can be implemented efficiently by checkpointing the training state after each epoch, but we avoid this extra complexity here. After the experiment has finished, we can retrieve and plot results.

 

우리는 실적이 저조한 시험을 조기에 중단하는 ASHA 변형을 실행하고 있습니다. 이는 각 훈련 작업이 고정된 max_epochs로 시작되는 섹션 19.4.1의 구현과 다릅니다. 후자의 경우 전체 10개 에포크에 도달하는 잘 수행되는 시험은 처음부터 처음부터 시작할 때마다 먼저 1개, 2개, 4개, 8개 에포크를 훈련해야 합니다. 이러한 유형의 일시 중지 및 재개 스케줄링은 각 에포크 이후 훈련 상태를 검사하여 효율적으로 구현할 수 있지만 여기서는 이러한 추가적인 복잡성을 피합니다. 실험이 완료된 후 결과를 검색하고 플롯할 수 있습니다.

 

d2l.set_figsize()
e = load_experiment(tuner.name)
e.plot()

위의 코드는 실험 결과를 시각화하는 부분입니다.

  • d2l.set_figsize(): 그래프의 크기를 설정하는 함수입니다. 이 경우 그래프의 크기를 조정합니다.
  • e = load_experiment(tuner.name): load_experiment 함수를 사용하여 이전에 실행한 실험 결과를 로드합니다. tuner.name은 이전에 실행한 튜너의 이름을 나타냅니다.
  • e.plot(): 로드한 실험 결과를 시각화합니다. 이로써 실험 결과 그래프가 표시됩니다. 실험 결과에는 하이퍼파라미터 값에 대한 메트릭(metric)의 변화 추이와 관련된 정보가 포함됩니다.
WARNING:matplotlib.legend:No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

 

19.5.3. Visualize the Optimization Process

Once more, we visualize the learning curves of every trial (each color in the plot represents a trial). Compare this to asynchronous random search in Section 19.3. As we have seen for successive halving in Section 19.4, most of the trials are stopped at 1 or 2 epochs (r min or η ∗ r min). However, trials do not stop at the same point, because they require different amount of time per epoch. If we ran standard successive halving instead of ASHA, we would need to synchronize our workers, before we can promote configurations to the next rung level.

 

다시 한 번 모든 시행의 학습 곡선을 시각화합니다(플롯의 각 색상은 시행을 나타냄). 이것을 섹션 19.3의 비동기 무작위 검색과 비교하십시오. 섹션 19.4에서 연속적인 반감기에 대해 살펴본 것처럼 대부분의 시행은 1 또는 2 에포크(r min 또는 θ * r min)에서 중단됩니다. 그러나 시도는 에포크마다 필요한 시간이 다르기 때문에 동일한 지점에서 멈추지 않습니다. ASHA 대신 표준 연속 절반을 실행한 경우 구성을 다음 단계 수준으로 승격하려면 먼저 작업자를 동기화해야 합니다.

 

d2l.set_figsize([6, 2.5])
results = e.results
for trial_id in results.trial_id.unique():
    df = results[results["trial_id"] == trial_id]
    d2l.plt.plot(
        df["st_tuner_time"],
        df["validation_error"],
        marker="o"
    )
d2l.plt.xlabel("wall-clock time")
d2l.plt.ylabel("objective function")

위의 코드는 실험 결과를 시각화하는 부분입니다.

  • d2l.set_figsize([6, 2.5]): 그래프의 크기를 설정하는 함수입니다. 이 경우 그래프의 가로 폭을 6로, 세로 높이를 2.5로 설정합니다.
  • results = e.results: 로드한 실험 결과에서 실제 결과 데이터를 가져옵니다.
  • for trial_id in results.trial_id.unique():: 실험 결과 중에서 고유한(trial_id가 다른) 각 실험에 대해서 반복합니다.
  • df = results[results["trial_id"] == trial_id]: 현재 반복 중인 trial_id에 해당하는 실험 결과 데이터를 선택합니다.
  • d2l.plt.plot(...): 선택한 실험 결과 데이터를 그래프로 표시합니다. x 축은 wall-clock time(실행 시간)을, y 축은 objective function(목적 함수) 값을 나타냅니다. marker="o"는 데이터 포인트를 원 형태로 표시하라는 옵션입니다.
  • d2l.plt.xlabel("wall-clock time"): x 축에 "wall-clock time" 레이블을 추가합니다.
  • d2l.plt.ylabel("objective function"): y 축에 "objective function" 레이블을 추가합니다.

이 코드는 실험 중 각 trial의 wall-clock time에 따른 objective function 값의 변화를 그래프로 표시하여 실험 결과를 시각적으로 확인할 수 있도록 합니다.

Text(0, 0.5, 'objective function')

19.5.4. Summary

 

Compared to random search, successive halving is not quite as trivial to run in an asynchronous distributed setting. To avoid synchronisation points, we promote configurations as quickly as possible to the next rung level, even if this means promoting some wrong ones. In practice, this usually does not hurt much, and the gains of asynchronous versus synchronous scheduling are usually much higher than the loss of the suboptimal decision making.

 

무작위 검색과 비교할 때, 연속적인 반감기는 비동기 분산 설정에서 실행하는 것이 그리 간단하지 않습니다. 동기화 지점을 피하기 위해 우리는 구성을 가능한 한 빨리 다음 단계 수준으로 승격합니다. 이는 잘못된 구성의 승격을 의미하더라도 마찬가지입니다. 실제로 이것은 일반적으로 큰 해를 끼치지 않으며 비동기식 스케줄링과 동기식 스케줄링의 이점은 일반적으로 차선책 의사 결정의 손실보다 훨씬 높습니다.

 

 

Asynchronous Successive Halving에 대해서 (GPT 3.5. 의 설명)

 

**비동기식 연속 하프링(Asynchronous Successive Halving)**은 하이퍼파라미터 최적화를 위한 고급 알고리즘 중 하나입니다. 이 방법은 Successive Halving 기술을 기반으로 하지만 병렬 처리와 비동기적 실행을 허용하여 계산 리소스를 효율적으로 활용합니다.

 

연속 하프링(Continuous Successive Halving) 또는 ASHA로도 알려진 이 방법은 다음과 같은 주요 아이디어를 포함합니다:

 

  1. 파라미터 세트는 다양한 하이퍼파라미터 구성을 나타냅니다. 초기에는 여러 구성이 생성됩니다.
  2. 리소스 할당: 초기에는 모든 파라미터 세트가 작은 리소스를 할당받아 빠르게 평가됩니다. 그런 다음 상위 성능을 보이는 세트가 더 많은 리소스를 할당받게 됩니다.
  3. 제거 및 확장: 하위 퍼포먼스를 보이는 파라미터 세트는 제거되고, 상위 퍼포먼스를 보이는 세트는 추가 리소스를 받아 성능을 더욱 정확하게 평가합니다. 이 과정을 반복하여 가장 우수한 하이퍼파라미터 세트를 찾습니다.
  4. 병렬 처리: ASHA는 파라미터 세트를 병렬로 처리하여 리소스 효율성을 극대화합니다. 이것은 다수의 하이퍼파라미터 구성을 동시에 평가하는 데 사용되며, 여러 프로세스 또는 워커(worker)가 동시에 실행됩니다.

 

비동기식 연속 하프링은 병렬 처리를 통해 하이퍼파라미터 최적화의 속도를 크게 높이며, 최적의 하이퍼파라미터 설정을 더욱 효율적으로 찾을 수 있도록 돕습니다. 이것은 계산 리소스를 최대한 활용하면서도 최상의 결과를 달성하기 위한 강력한 도구 중 하나입니다.

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/sh-intro.html

 

19.4. Multi-Fidelity Hyperparameter Optimization — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.4. Multi-Fidelity Hyperparameter Optimization

Training neural networks can be expensive even on moderate size datasets. Depending on the configuration space (Section 19.1.1.2), hyperparameter optimization requires tens to hundreds of function evaluations to find a well-performing hyperparameter configuration. As we have seen in Section 19.3, we can significantly speed up the overall wall-clock time of HPO by exploiting parallel resources, but this does not reduce the total amount of compute required.

 

적당한 크기의 데이터 세트에서도 신경망을 훈련하는 데 비용이 많이 들 수 있습니다. 구성 공간(19.1.1.2절)에 따라 하이퍼파라미터 최적화에는 성능이 좋은 하이퍼파라미터 구성을 찾기 위해 수십에서 수백 번의 함수 평가가 필요합니다. 섹션 19.3에서 살펴본 것처럼 병렬 리소스를 활용하여 HPO의 전체 벽시계 시간을 크게 단축할 수 있지만 이것이 필요한 총 컴퓨팅 양을 줄이지는 않습니다.

 

In this section, we will show how the evaluation of hyperparameter configurations can be sped up. Methods such as random search allocate the same amount of resources (e.g., number of epochs, training data points) to each hyperparameter evaluation. Fig. 19.4.1 depicts learning curves of a set of neural networks trained with different hyperparameter configurations. After a few epochs we are already able to visually distinguish between well-performing and suboptimal configurations. However, the learning curves are noisy, and we might still require the full amount of 100 epochs to identify the best performing one.

 

이 섹션에서는 하이퍼파라미터 구성의 평가 속도를 높이는 방법을 보여줍니다. 무작위 검색과 같은 방법은 각 하이퍼파라미터 평가에 동일한 양의 리소스(예: 시대 수, 교육 데이터 포인트)를 할당합니다. 그림 19.4.1은 다양한 하이퍼파라미터 구성으로 훈련된 신경망 세트의 학습 곡선을 보여줍니다. 몇 번의 시대가 지나면 이미 성능이 좋은 구성과 최적이 아닌 구성을 시각적으로 구분할 수 있습니다. 그러나 학습 곡선에는 잡음이 많으므로 최고의 성과를 내는 것을 식별하려면 여전히 100개의 에포크가 필요할 수 있습니다.

 

Fig. 19.4.1&nbsp; Learning curves of random hyperparameter configurations

 

Multi-fidelity hyperparameter optimization allocates more resources to promising configurations and stop evaluations of poorly performing ones early. This speeds up the optimization process, since we can try a larger number of configurations for the same total amount of resources.

 

다중 충실도 하이퍼파라미터 최적화는 유망한 구성에 더 많은 리소스를 할당하고 성능이 낮은 구성에 대한 평가를 조기에 중지합니다. 동일한 총 리소스 양에 대해 더 많은 수의 구성을 시도할 수 있으므로 최적화 프로세스 속도가 빨라집니다.

 

More formally, we expand our definition in Section 19.1.1, such that our objective function f(x,r) gets an additional input r∈[r min,r max], specifying the amount of resources that we are willing to spend for the evaluation of configuration x. We assume that the error f(x,r) decreases with r, whereas the computational cost c(x,r) increases. Typically, r represents the number of epochs for training the neural network, but it could also be the training subset size or the number of cross-validation folds.

 

보다 공식적으로, 목적 함수 f(x,r)가 추가 입력 r∈[r min,r max]를 얻도록 섹션 19.1.1의 정의를 확장하여 지출하려는 자원의 양을 지정합니다. 구성 x의 평가. 오류 f(x,r)는 r에 따라 감소하는 반면 계산 비용 c(x,r)은 증가한다고 가정합니다. 일반적으로 r은 신경망 훈련을 위한 에포크 수를 나타내지만 훈련 하위 집합 크기 또는 교차 검증 접기 수일 수도 있습니다.

 

from collections import defaultdict
import numpy as np
from scipy import stats
from d2l import torch as d2l

d2l.set_figsize()

위의 코드는 Python 라이브러리와 도구를 가져오고, 그림의 크기를 설정하는 부분입니다.

  1. from collections import defaultdict: Python의 내장 모듈인 collections에서 defaultdict 클래스를 가져옵니다. defaultdict는 기본값(default)을 가진 딕셔너리(dictionary)를 생성하는데 사용됩니다.
  2. import numpy as np: NumPy 라이브러리를 가져옵니다. NumPy는 과학적 계산을 위한 파이썬 라이브러리로 배열(array)과 행렬(matrix) 연산을 지원합니다. np는 NumPy를 짧게 참조하기 위한 별칭(alias)입니다.
  3. from scipy import stats: SciPy 라이브러리에서 stats 모듈을 가져옵니다. SciPy는 과학적 계산을 위한 다양한 기능을 제공하는 라이브러리로, 통계 분석과 관련된 함수와 도구를 포함하고 있습니다.
  4. from d2l import torch as d2l: "d2l" 라이브러리에서 "torch" 모듈을 가져오고, "d2l"을 짧게 참조하기 위한 별칭으로 사용합니다.
  5. d2l.set_figsize(): "d2l" 라이브러리에서 제공하는 함수인 set_figsize()를 호출하여 그림(플롯)의 크기를 설정합니다. 이 함수는 시각화에서 그림의 크기를 조정하는 데 사용됩니다. 크기를 따로 지정하지 않으면 기본 크기로 설정됩니다.

이 코드는 라이브러리를 가져와 사용할 수 있도록 하고, 그림의 크기를 설정하여 나중에 생성할 그래프나 플롯의 크기를 지정합니다.

 

Multi-Fidelity Hyperparameter Optimization이란? (GPT 3.5 답변)

 

**다중 신뢰도 하이퍼파라미터 최적화(Multi-Fidelity Hyperparameter Optimization)**는 하이퍼파라미터 최적화를 위한 고급 기술 중 하나로, 기계 학습 모델을 효율적으로 튜닝하기 위해 여러 가지 신뢰도 또는 리소스 수준에서 모델을 평가하는 방법입니다. 일반적으로 이러한 접근 방식은 계산 비용이 높은 고신뢰도(또는 고 리소스) 평가와 계산 비용이 낮은 저신뢰도(또는 저 리소스) 평가를 혼합하여 사용합니다.

 

다중 신뢰도 하이퍼파라미터 최적화의 핵심 아이디어는 다음과 같습니다.

 

  1. 고신뢰도 평가 (High-Fidelity Evaluation): 높은 신뢰도를 가진 평가는 모델의 성능을 정확하게 측정합니다. 이것은 많은 계산 리소스와 시간을 필요로 합니다. 예를 들어, 모든 훈련 데이터와 에포크 수를 늘리는 것과 같이 모델을 더 오랫동안 훈련하는 것이 포함될 수 있습니다.
  2. 저신뢰도 평가 (Low-Fidelity Evaluation): 저신뢰도 평가는 고신뢰도 평가보다 빠르게 수행됩니다. 예를 들어, 더 적은 훈련 데이터를 사용하거나 적은 에포크로 모델을 훈련하는 것이 이에 해당합니다.
  3. 리소스 관리: 다중 신뢰도 하이퍼파라미터 최적화는 제한된 계산 리소스 또는 시간 내에서 가장 효율적으로 최적화를 수행하려는 목표를 가지고 있습니다. 이를 위해 리소스를 고정된 신뢰도 평가와 저신뢰도 평가 사이에서 분배합니다.
  4. 바람직한 트레이드오프 탐색: 목표는 최적의 하이퍼파라미터 설정을 찾는 것이지만, 모든 경우에 고신뢰도 평가를 수행하는 것은 현실적이지 않을 수 있습니다. 따라서 가용한 리소스 내에서 가능한 한 많은 하이퍼파라미터 설정을 평가하여 최상의 트레이드오프를 찾습니다.
  5. 자동화된 하이퍼파라미터 선택: 다중 신뢰도 하이퍼파라미터 최적화는 주어진 리소스 내에서 자동으로 하이퍼파라미터를 선택하고 평가합니다. 이것은 기계 학습 엔지니어 또는 데이터 과학자에게 매우 유용합니다.

다중 신뢰도 하이퍼파라미터 최적화는 하이퍼파라미터 튜닝 과정을 가속화하고 계산 리소스를 효율적으로 활용하면서 최상의 하이퍼파라미터 설정을 찾는 데 도움을 줍니다. 이 방법은 기계 학습 모델의 성능을 최대화하는 데 중요합니다.

19.4.1. Successive Halving

One of the simplest ways to adapt random search to the multi-fidelity setting is successive halving (Jamieson and Talwalkar, 2016, Karnin et al., 2013). The basic idea is to start with N configurations, for example randomly sampled from the configuration space, and to train each of them for r min epochs only. We then discard a fraction of the worst performing trials and train the remaining ones for longer. Iterating this process, fewer trials run for longer, until at least one trial reaches r max epochs.

 

다중 충실도 설정에 무작위 검색을 적용하는 가장 간단한 방법 중 하나는 연속적인 반감기입니다(Jamieson and Talwalkar, 2016, Karnin et al., 2013). 기본 아이디어는 예를 들어 구성 공간에서 무작위로 샘플링된 N 구성으로 시작하고 각 구성을 r min epoch 동안만 훈련하는 것입니다. 그런 다음 성능이 가장 낮은 시험 중 일부를 버리고 나머지 시험을 더 오랫동안 훈련합니다. 이 프로세스를 반복하면 적어도 하나의 시도가 r 최대 에포크에 도달할 때까지 더 적은 수의 시도가 더 오랫동안 실행됩니다.

 

More formally, consider a minimum budget r min (for example 1 epoch), a maximum budget r max, for example max_epochs in our previous example, and a halving constant η∈{2,3,…}. For simplicity, assume that r max = r min η**k, with K∈ . The number of initial configurations is then N=η**k. Let us define the set of rungs R = {r min, r min η, r min η**2,…,r max}.

 

보다 공식적으로는 최소 예산 r min(예: 1 epoch), 최대 예산 r max(예: 이전 예의 max_epochs) 및 반감 상수 eta∈{2,3,…}를 고려합니다. 단순화를 위해 r max = r min θ**k, K∈ʼ 라고 가정합니다. 그러면 초기 구성 수는 N=θ**k입니다. 단계 세트 R = {r min, r min eta, r min eta**2,…,r max}를 정의해 보겠습니다.

 

One round of successive halving proceeds as follows. We start with running N trials until the first rung r min. Sorting the validation errors, we keep the top 1/η fraction (which amounts to η**k−1 configurations) and discard all the rest. The surviving trials are trained for the next rung (r min η epochs), and the process is repeated. At each rung, a 1/η fraction of trials survives and their training continues with a η times larger budget. With this particular choice of N, only a single trial will be trained to the full budget r max. Once such a round of successive halving is done, we start the next one with a new set of initial configurations, iterating until the total budget is spent.

 

한 라운드의 연속적인 반감기는 다음과 같이 진행됩니다. 첫 번째 rung r min까지 N번 시도를 실행하는 것으로 시작합니다. 검증 오류를 정렬하면서 상위 1/eta 부분(eta**k−1 구성에 해당)을 유지하고 나머지는 모두 삭제합니다. 살아남은 시도는 다음 단계(r min θ epochs)에 대해 훈련되고 프로세스가 반복됩니다. 각 단계에서 시행의 1/θ 비율이 살아남고 해당 훈련은 θ배 더 큰 예산으로 계속됩니다. 이 특정 N 선택을 사용하면 단일 시도만 전체 예산 r max로 학습됩니다. 이러한 연속적인 반감기가 완료되면 새로운 초기 구성 세트로 다음 단계를 시작하여 총 예산이 소비될 때까지 반복합니다.

 

Fig. 19.4.2&nbsp; Learning curves of random hyperparameter configurations.

 

Successive Halving 이란? (GPT 3.5 답변)

 

Successive Halving은 하이퍼파라미터 최적화에서 사용되는 고급 기술 중 하나입니다. 이 방법은 많은 하이퍼파라미터 구성을 효율적으로 평가하고 가장 우수한 하이퍼파라미터 구성을 찾는 데 도움을 줍니다.

 

Successive Halving은 다음 단계로 구성됩니다:

 

  1. 초기 라운드 (Initial Round): 먼저 모든 하이퍼파라미터 구성을 동일한 리소스 또는 시간 내에서 평가합니다. 이 단계에서는 많은 하이퍼파라미터 구성을 아직 유망한지 판단하지 않고 각각을 동등하게 다룹니다.
  2. 선택 (Selection): 초기 라운드에서 우수한 일부 하이퍼파라미터 구성만 선택합니다. 일반적으로 이것은 상위 N개 구성을 선택하는 것으로 시작합니다. 이 선택 기준은 주로 목표 지표 (예: 정확도 또는 손실)을 기반으로 합니다.
  3. 제거 (Elimination): 선택된 하이퍼파라미터 구성 중 일부를 제거합니다. 제거 기준은 각 구성의 상대적 효용성을 평가하는 데 사용됩니다. 이것은 효율성을 높이기 위한 주요 단계로, 낮은 성능을 보이는 하이퍼파라미터 구성을 제거하고 리소스를 더 높은 효과적인 평가로 할당하는 데 도움을 줍니다.
  4. 라운드 반복 (Iteration): 선정된 하이퍼파라미터 구성들을 다음 라운드로 이동시킵니다. 이제 리소스 또는 시간을 더욱 증가시켜 더 정확한 평가를 수행합니다. 이 프로세스는 몇 라운드에 걸쳐 반복됩니다.

Successive Halving은 초기에 무작위로 선택된 하이퍼파라미터 구성들을 점진적으로 걸러내고 가장 우수한 구성을 찾기 위해 리소스를 최적으로 활용하는 방법 중 하나입니다. 이 방법은 계산 리소스를 효율적으로 활용하면서도 최상의 하이퍼파라미터 설정을 찾는 데 도움을 줍니다.

 

We subclass the HPOScheduler base class from Section 19.2 in order to implement successive halving, allowing for a generic HPOSearcher object to sample configurations (which, in our example below, will be a RandomSearcher). Additionally, the user has to pass the minimum resource r min, the maximum resource r max and η as input. Inside our scheduler, we maintain a queue of configurations that still need to be evaluated for the current rung ri. We update the queue every time we jump to the next rung.

 

연속적인 절반 분할을 구현하기 위해 섹션 19.2에서 HPOScheduler 기본 클래스를 서브클래싱하여 일반 HPOSearcher 객체가 샘플 구성(아래 예에서는 RandomSearcher가 됨)을 허용합니다. 또한 사용자는 최소 리소스 r min, 최대 리소스 r max 및 eta를 입력으로 전달해야 합니다. 스케줄러 내에서는 현재 단계에 대해 여전히 평가해야 하는 구성 대기열을 유지 관리합니다. 다음 단계로 이동할 때마다 대기열을 업데이트합니다.

 

class SuccessiveHalvingScheduler(d2l.HPOScheduler):  #@save
    def __init__(self, searcher, eta, r_min, r_max, prefact=1):
        self.save_hyperparameters()
        # Compute K, which is later used to determine the number of configurations
        self.K = int(np.log(r_max / r_min) / np.log(eta))
        # Define the rungs
        self.rung_levels = [r_min * eta ** k for k in range(self.K + 1)]
        if r_max not in self.rung_levels:
            # The final rung should be r_max
            self.rung_levels.append(r_max)
            self.K += 1
        # Bookkeeping
        self.observed_error_at_rungs = defaultdict(list)
        self.all_observed_error_at_rungs = defaultdict(list)
        # Our processing queue
        self.queue = []

위의 코드는 SuccessiveHalvingScheduler라는 클래스를 정의하는 부분입니다. 이 클래스는 하이퍼파라미터 최적화 실험을 위한 스케줄러로 사용됩니다.

  1. def __init__(self, searcher, eta, r_min, r_max, prefact=1):: SuccessiveHalvingScheduler 클래스의 초기화 메서드입니다. 이 클래스는 여러 하이퍼파라미터를 받아 초기화됩니다.
    • searcher: 하이퍼파라미터 탐색기(searcher) 객체입니다.
    • eta: 탐색 단계 간의 이동 비율입니다.
    • r_min: 최소 리소스(예: 시간, 계산 능력)입니다.
    • r_max: 최대 리소스(예: 시간, 계산 능력)입니다.
    • prefact: 사전 요소(pre-factored)입니다.
  2. self.K = int(np.log(r_max / r_min) / np.log(eta)): K는 하이퍼파라미터 조합을 조사할 최대 횟수를 나타내는 변수입니다. eta와 리소스 범위에 따라 계산됩니다.
  3. self.rung_levels = [r_min * eta ** k for k in range(self.K + 1)]: rung_levels는 각 단계의 리소스 레벨을 저장하는 리스트입니다. r_min에서 시작하여 eta의 거듭제곱을 계산하여 각 단계의 리소스 레벨을 결정합니다.
  4. if r_max not in self.rung_levels:: r_max가 rung_levels에 포함되지 않으면, r_max를 추가합니다. 이렇게 하여 최종 단계에서도 r_max 리소스를 사용할 수 있도록 합니다.
  5. self.observed_error_at_rungs = defaultdict(list): observed_error_at_rungs는 각 단계에서 관찰된 에러를 저장하기 위한 딕셔너리입니다. 에러는 각 단계에서 계산되고 저장됩니다.
  6. self.all_observed_error_at_rungs = defaultdict(list): all_observed_error_at_rungs는 모든 실험에서 관찰된 에러를 저장하기 위한 딕셔너리입니다. 모든 실험에서 관찰된 에러를 추적합니다.
  7. self.queue = []: 실험을 수행하기 위한 큐(queue)를 초기화합니다. 실험 조합은 이 큐에 추가되어 순차적으로 실행됩니다.

이 클래스는 Successive Halving 알고리즘에 기반하여 하이퍼파라미터 탐색을 수행합니다. 각 단계에서 최적의 하이퍼파라미터 조합을 선택하고, 이를 기반으로 다음 단계의 실험을 수행합니다.

 

In the beginning our queue is empty, and we fill it with n=prefact⋅η**k configurations, which are first evaluated on the smallest rung r min. Here, prefact allows us to reuse our code in a different context. For the purpose of this section, we fix prefact=1. Every time resources become available and the HPOTuner object queries the suggest function, we return an element from the queue. Once we finish one round of successive halving, which means that we evaluated all surviving configurations on the highest resource level r max and our queue is empty, we start the entire process again with a new, randomly sampled set of configurations.

 

처음에는 대기열이 비어 있으며 n=prefact⋅eta**k 구성으로 채워져 가장 작은 단계 r min에서 먼저 평가됩니다. 여기서 prefact를 사용하면 다른 컨텍스트에서 코드를 재사용할 수 있습니다. 이 섹션의 목적을 위해 prefact=1을 수정합니다. 리소스를 사용할 수 있게 되고 HPOTuner 개체가 제안 기능을 쿼리할 때마다 대기열에서 요소를 반환합니다. 한 라운드의 연속적인 반감기를 마치면, 즉 가장 높은 리소스 수준 r max에서 살아남은 모든 구성을 평가하고 대기열이 비어 있으면 무작위로 샘플링된 새로운 구성 세트로 전체 프로세스를 다시 시작합니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def suggest(self):
    if len(self.queue) == 0:
        # Start a new round of successive halving
        # Number of configurations for the first rung:
        n0 = int(self.prefact * self.eta ** self.K)
        for _ in range(n0):
            config = self.searcher.sample_configuration()
            config["max_epochs"] = self.r_min  # Set r = r_min
            self.queue.append(config)
    # Return an element from the queue
    return self.queue.pop()

위의 코드는 SuccessiveHalvingScheduler 클래스에 suggest 메서드를 추가하는 부분입니다. 이 메서드는 다음 실험에 사용할 하이퍼파라미터 조합을 제안하는 역할을 합니다.

  1. if len(self.queue) == 0:: 큐(queue)가 비어있는 경우, 새로운 Successive Halving 라운드를 시작합니다. 이는 다음 단계에서 실험할 하이퍼파라미터 조합을 선택하는 단계입니다.
  2. n0 = int(self.prefact * self.eta ** self.K): 첫 번째 단계의 실험 횟수(n0)를 계산합니다. prefact와 eta를 사용하여 최초 단계에서 실험할 하이퍼파라미터 조합의 수를 결정합니다.
  3. for _ in range(n0):: 계산된 실험 횟수만큼 반복하여 하이퍼파라미터 조합을 선택하고 큐에 추가합니다.
  4. config["max_epochs"] = self.r_min: 선택한 하이퍼파라미터 조합의 max_epochs 값을 r_min으로 설정합니다. 이렇게 하여 해당 단계에서의 최소 리소스를 사용하게 됩니다.
  5. self.queue.pop(): 큐에서 하이퍼파라미터 조합을 하나씩 꺼내서 반환합니다. 이 조합은 다음 실험에 사용됩니다.

이 메서드는 Successive Halving 알고리즘에 따라 다음 실험에 사용할 하이퍼파라미터 조합을 선택하고, 큐에서 해당 조합을 제거하는 역할을 합니다.

 

 

When we collected a new data point, we first update the searcher module. Afterwards we check if we already collect all data points on the current rung. If so, we sort all configurations and push the top 1/η configurations into the queue.

 

새로운 데이터 포인트를 수집하면 먼저 검색 모듈을 업데이트합니다. 그런 다음 현재 단계에서 모든 데이터 포인트를 이미 수집했는지 확인합니다. 그렇다면 모든 구성을 정렬하고 상위 1/eta 구성을 대기열에 푸시합니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def update(self, config: dict, error: float, info=None):
    ri = int(config["max_epochs"])  # Rung r_i
    # Update our searcher, e.g if we use Bayesian optimization later
    self.searcher.update(config, error, additional_info=info)
    self.all_observed_error_at_rungs[ri].append((config, error))
    if ri < self.r_max:
        # Bookkeeping
        self.observed_error_at_rungs[ri].append((config, error))
        # Determine how many configurations should be evaluated on this rung
        ki = self.K - self.rung_levels.index(ri)
        ni = int(self.prefact * self.eta ** ki)
        # If we observed all configuration on this rung r_i, we estimate the
        # top 1 / eta configuration, add them to queue and promote them for
        # the next rung r_{i+1}
        if len(self.observed_error_at_rungs[ri]) >= ni:
            kiplus1 = ki - 1
            niplus1 = int(self.prefact * self.eta ** kiplus1)
            best_performing_configurations = self.get_top_n_configurations(
                rung_level=ri, n=niplus1
            )
            riplus1 = self.rung_levels[self.K - kiplus1]  # r_{i+1}
            # Queue may not be empty: insert new entries at the beginning
            self.queue = [
                dict(config, max_epochs=riplus1)
                for config in best_performing_configurations
            ] + self.queue
            self.observed_error_at_rungs[ri] = []  # Reset

위의 코드는 SuccessiveHalvingScheduler 클래스에 update 메서드를 추가하는 부분입니다. 이 메서드는 각 실험의 결과를 기반으로 다음 단계의 실험을 업데이트하고 관리합니다.

  1. ri = int(config["max_epochs"]): 현재 실험에서 사용한 max_epochs 값을 가져와 ri 변수에 저장합니다. 이 값은 현재 실험의 리소스 레벨을 나타냅니다.
  2. self.searcher.update(config, error, additional_info=info): searcher 객체를 업데이트합니다. 이는 나중에 베이지안 최적화와 같은 다른 탐색 알고리즘을 사용할 때 유용합니다.
  3. self.all_observed_error_at_rungs[ri].append((config, error)): 모든 실험에서 현재 리소스 레벨 ri에서 관찰된 에러를 저장합니다.
  4. if ri < self.r_max:: 현재 리소스 레벨이 최대 리소스 레벨 r_max보다 작은 경우에만 다음 단계의 처리를 진행합니다.
  5. ki = self.K - self.rung_levels.index(ri): 현재 리소스 레벨에 해당하는 단계 ki를 계산합니다.
  6. ni = int(self.prefact * self.eta ** ki): 현재 단계에서 평가할 실험의 수를 계산합니다.
  7. if len(self.observed_error_at_rungs[ri]) >= ni:: 현재 리소스 레벨에서 이미 모든 실험을 수행한 경우에는 다음 단계로 넘어갑니다.
  8. kiplus1 = ki - 1과 niplus1 = int(self.prefact * self.eta ** kiplus1)을 계산하여 다음 단계에서 평가할 실험의 수와 단계를 결정합니다.
  9. best_performing_configurations = self.get_top_n_configurations(rung_level=ri, n=niplus1): 현재 단계에서 성능이 가장 좋은 상위 niplus1개의 하이퍼파라미터 조합을 가져옵니다.
  10. riplus1 = self.rung_levels[self.K - kiplus1]: 다음 단계의 리소스 레벨 riplus1을 결정합니다.
  11. self.queue = [...] + self.queue: 다음 단계의 실험을 큐에 추가합니다. 이때, 현재 큐에 있는 실험들은 다음 단계의 리소스 레벨로 업데이트되고, 상위 성능 조합들이 추가됩니다.
  12. self.observed_error_at_rungs[ri] = []: 현재 단계에서 관찰된 에러를 리셋하여 다음 단계를 위한 준비를 합니다.

이 메서드는 Successive Halving 알고리즘의 핵심 로직을 구현하며, 각 실험의 결과를 바탕으로 다음 실험의 하이퍼파라미터 조합을 선택하고 큐를 관리합니다.

 

 

Configurations are sorted based on their observed performance on the current rung. 

구성은 현재 단계에서 관찰된 성능을 기준으로 정렬됩니다.

 

@d2l.add_to_class(SuccessiveHalvingScheduler)  #@save
def get_top_n_configurations(self, rung_level, n):
    rung = self.observed_error_at_rungs[rung_level]
    if not rung:
        return []
    sorted_rung = sorted(rung, key=lambda x: x[1])
    return [x[0] for x in sorted_rung[:n]]

위의 코드는 SuccessiveHalvingScheduler 클래스에 get_top_n_configurations 메서드를 추가하는 부분입니다. 이 메서드는 주어진 리소스 레벨에서 성능이 가장 좋은 상위 n개 하이퍼파라미터 조합을 반환합니다.

  1. rung = self.observed_error_at_rungs[rung_level]: 주어진 리소스 레벨 rung_level에서 관찰된 모든 실험 결과를 가져옵니다.
  2. if not rung:: 만약 해당 리소스 레벨에서 아직 어떤 실험이 수행되지 않았다면 빈 리스트를 반환합니다.
  3. sorted_rung = sorted(rung, key=lambda x: x[1]): 실험 결과를 성능(에러 값)에 따라 정렬합니다.
  4. return [x[0] for x in sorted_rung[:n]]: 상위 n개의 실험 중 하이퍼파라미터 조합만을 반환합니다. 이는 다음 단계의 실험에 사용됩니다.

즉, get_top_n_configurations 메서드는 주어진 리소스 레벨에서 성능이 가장 좋은 하이퍼파라미터 조합을 선택하는데 사용되며, Successive Halving 알고리즘의 핵심 부분 중 하나입니다.

 

Let us see how successive halving is doing on our neural network example. We will use r min=2, η=2, r max=10, so that rung levels are 2,4,8,10.

 

신경망 예제에서 연속적인 반감기가 어떻게 수행되는지 살펴보겠습니다. r min=2, eta=2, r max=10을 사용하므로 단계 수준은 2,4,8,10이 됩니다.

 

min_number_of_epochs = 2
max_number_of_epochs = 10
eta = 2
num_gpus=1

config_space = {
    "learning_rate": stats.loguniform(1e-2, 1),
    "batch_size": stats.randint(32, 256),
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 Successive Halving HPO (Hyperparameter Optimization) 알고리즘을 설정하는 부분입니다. 이 알고리즘은 하이퍼파라미터 최적화를 위해 사용되며, 주어진 리소스로 가장 좋은 하이퍼파라미터 설정을 찾는 데 도움이 됩니다. 아래는 각 설정과 변수에 대한 설명입니다.

  • min_number_of_epochs (최소 에포크 수): 각 실험에서 최소 몇 번의 에포크를 실행할지를 나타냅니다. 이 값은 2로 설정되어 있습니다.
  • max_number_of_epochs (최대 에포크 수): 각 실험에서 최대 몇 번의 에포크까지 실행할지를 나타냅니다. 이 값은 10으로 설정되어 있습니다.
  • eta (탐색 요인): Successive Halving 알고리즘에서 리소스를 나누는 데 사용되는 요인을 나타냅니다. 이 값은 2로 설정되어 있으며, 리소스가 반으로 줄어들 때마다 실행되는 실험 수가 2배로 증가합니다.
  • num_gpus (GPU 수): 사용 가능한 GPU 수를 나타냅니다. 이 예제에서는 1로 설정되어 있습니다.
  • config_space (하이퍼파라미터 공간): 하이퍼파라미터 최적화를 위해 탐색할 하이퍼파라미터 공간을 정의합니다. 여기에서는 학습률(learning_rate)과 배치 크기(batch_size)를 설정하고, 각각 loguniform 및 randint 확률 분포를 사용하여 하이퍼파라미터를 탐색할 범위를 지정합니다.
  • initial_config (초기 하이퍼파라미터 설정): 최초의 실험을 위해 사용되는 초기 하이퍼파라미터 설정을 나타냅니다. 이 예제에서는 학습률을 0.1로, 배치 크기를 128로 설정합니다.

이러한 설정과 변수들은 Successive Halving HPO 알고리즘을 실행하고 하이퍼파라미터 최적화를 수행하는 데 필요한 매개변수와 공간을 정의합니다.

 

We just replace the scheduler with our new SuccessiveHalvingScheduler.

 

스케줄러를 새로운 SuccessiveHalvingScheduler로 교체합니다.

 

searcher = d2l.RandomSearcher(config_space, initial_config=initial_config)
scheduler = SuccessiveHalvingScheduler(
    searcher=searcher,
    eta=eta,
    r_min=min_number_of_epochs,
    r_max=max_number_of_epochs,
)
tuner = d2l.HPOTuner(
    scheduler=scheduler,
    objective=d2l.hpo_objective_lenet,
)
tuner.run(number_of_trials=30)

위의 코드는 Successive Halving HPO 알고리즘을 구현하고 실행하는 부분입니다. 아래는 코드의 주요 내용에 대한 설명입니다.

  • searcher: RandomSearcher는 하이퍼파라미터 탐색을 수행하는 데 사용되는 탐색자(searcher)입니다. config_space에서 정의한 하이퍼파라미터 공간을 기반으로 하이퍼파라미터 설정을 무작위로 추출하며, 초기 설정은 initial_config로 설정됩니다.
  • scheduler: SuccessiveHalvingScheduler는 Successive Halving 알고리즘의 스케줄러입니다. 이 스케줄러는 searcher로부터 샘플된 하이퍼파라미터 설정을 기반으로 실험을 관리하고, eta, r_min, r_max 등을 사용하여 실험을 반복하고 스케줄링합니다.
  • tuner: HPOTuner는 하이퍼파라미터 최적화를 수행하는 클래스입니다. scheduler를 통해 실험을 관리하고, objective 함수를 사용하여 각 실험의 성능을 평가하며, number_of_trials 매개변수에 지정된 횟수만큼 실험을 실행합니다.

이렇게 구성된 코드는 Successive Halving 알고리즘을 사용하여 하이퍼파라미터 최적화를 수행하며, 30회의 실험을 실행하여 최적의 하이퍼파라미터 설정을 찾습니다.

 error = 0.17762434482574463, runtime = 53.576584339141846

We can visualize the learning curves of all configurations that we evaluated. Most of the configurations are stopped early and only the better performing configurations survive until r max. Compare this to vanilla random search, which would allocate r max to every configuration.

 

평가한 모든 구성의 학습 곡선을 시각화할 수 있습니다. 대부분의 구성은 조기에 중지되며 더 나은 성능의 구성만 r max까지 유지됩니다. 이것을 모든 구성에 r max를 할당하는 바닐라 무작위 검색과 비교해 보세요.

 

for rung_index, rung in scheduler.all_observed_error_at_rungs.items():
    errors = [xi[1] for xi in rung]
    d2l.plt.scatter([rung_index] * len(errors), errors)
d2l.plt.xlim(min_number_of_epochs - 0.5, max_number_of_epochs + 0.5)
d2l.plt.xticks(
    np.arange(min_number_of_epochs, max_number_of_epochs + 1),
    np.arange(min_number_of_epochs, max_number_of_epochs + 1)
)
d2l.plt.ylabel("validation error")
d2l.plt.xlabel("epochs")

위의 코드는 Successive Halving HPO 알고리즘을 통해 각 rung(레벨)에서 관찰된 검증 오차(validation error)를 시각화하는 부분입니다. 아래는 코드의 주요 내용에 대한 설명입니다.

  • for rung_index, rung in scheduler.all_observed_error_at_rungs.items():: all_observed_error_at_rungs에는 각 rung 레벨에서 관찰된 검증 오차의 정보가 저장되어 있습니다. 이 코드는 각 rung에 대한 정보를 반복하며 그래프를 그립니다.
  • errors = [xi[1] for xi in rung]: 각 rung에서 관찰된 검증 오차를 추출하여 errors 리스트에 저장합니다.
  • d2l.plt.scatter([rung_index] * len(errors), errors): rung 레벨에 해당하는 x 좌표에 해당 오차 값을 점으로 표시하여 그래프에 추가합니다.
  • d2l.plt.xlim(min_number_of_epochs - 0.5, max_number_of_epochs + 0.5): x 축의 범위를 설정합니다.
  • d2l.plt.xticks(np.arange(min_number_of_epochs, max_number_of_epochs + 1), np.arange(min_number_of_epochs, max_number_of_epochs + 1)): x 축의 눈금을 설정합니다. rung 레벨에 해당하는 값들이 표시됩니다.
  • d2l.plt.ylabel("validation error")와 d2l.plt.xlabel("epochs"): y 축과 x 축에 라벨을 추가합니다.

이 코드를 통해 각 rung 레벨에서 관찰된 검증 오차를 epochs(에폭)별로 시각적으로 확인할 수 있습니다.

Text(0.5, 0, 'epochs')

Finally, note some slight complexity in our implementation of SuccessiveHalvingScheduler. Say that a worker is free to run a job, and suggest is called when the current rung has almost been completely filled, but another worker is still busy with an evaluation. Since we lack the metric value from this worker, we cannot determine the top 1/η fraction to open up the next rung. On the other hand, we want to assign a job to our free worker, so it does not remain idle. Our solution is to start a new round of successive halving and assign our worker to the first trial there. However, once a rung is completed in update, we make sure to insert new configurations at the beginning of the queue, so they take precedence over configurations from the next round.

 

마지막으로 SuccessiveHalvingScheduler 구현이 약간 복잡하다는 점에 유의하세요. 작업자가 작업을 자유롭게 실행할 수 있고 현재 단계가 거의 완전히 채워졌을 때 제안이 호출되지만 다른 작업자는 여전히 평가로 바쁘다고 가정해 보겠습니다. 이 작업자의 메트릭 값이 부족하기 때문에 다음 단계를 열기 위한 상위 1/θ 비율을 결정할 수 없습니다. 반면에 우리는 무료 작업자에게 작업을 할당하여 유휴 상태로 남아 있지 않도록 하려고 합니다. 우리의 해결책은 새로운 연속 반감기 라운드를 시작하고 그곳에서 첫 번째 시도에 작업자를 할당하는 것입니다. 그러나 업데이트에서 단계가 완료되면 대기열 시작 부분에 새 구성을 삽입하여 다음 라운드의 구성보다 우선하도록 합니다.

 

19.4.2. Summary

In this section, we introduced the concept of multi-fidelity hyperparameter optimization, where we assume to have access to cheap-to-evaluate approximations of the objective function, such as validation error after a certain number of epochs of training as proxy to validation error after the full number of epochs. Multi-fidelity hyperparameter optimization allows to reduce the overall computation of the HPO instead of just reducing the wall-clock time.

 

이 섹션에서는 다중 충실도 하이퍼파라미터 최적화의 개념을 소개했습니다. 여기서 우리는 검증 오류에 대한 프록시로서 특정 횟수의 훈련 후 검증 오류와 같이 목적 함수의 평가하기 쉬운 근사값에 액세스할 수 있다고 가정합니다. 전체 에포크 수 이후. 다중 충실도 하이퍼파라미터 최적화를 사용하면 벽시계 시간을 줄이는 대신 HPO의 전체 계산을 줄일 수 있습니다.

 

We implemented and evaluated successive halving, a simple yet efficient multi-fidelity HPO algorithm.

 

우리는 간단하면서도 효율적인 다중 충실도 HPO 알고리즘인 연속 반감기를 구현하고 평가했습니다.

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/rs-async.html

 

19.3. Asynchronous Random Search — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.3. Asynchronous Random Search

 

As we have seen in the previous Section 19.2, we might have to wait hours or even days before random search returns a good hyperparameter configuration, because of the expensive evaluation of hyperparameter configurations. In practice, we have often access to a pool of resources such as multiple GPUs on the same machine or multiple machines with a single GPU. This begs the question: How do we efficiently distribute random search?

 

이전 섹션 19.2에서 살펴본 것처럼 하이퍼파라미터 구성에 대한 평가 비용이 많이 들기 때문에 무작위 검색이 좋은 하이퍼파라미터 구성을 반환하기까지 몇 시간 또는 심지어 며칠을 기다려야 할 수도 있습니다. 실제로 우리는 동일한 시스템의 여러 GPU 또는 단일 GPU가 있는 여러 시스템과 같은 리소스 풀에 액세스하는 경우가 많습니다. 이는 다음과 같은 질문을 던집니다. 무작위 검색을 어떻게 효율적으로 배포할 수 있습니까?

 

In general, we distinguish between synchronous and asynchronous parallel hyperparameter optimization (see Fig. 19.3.1). In the synchronous setting, we wait for all concurrently running trials to finish, before we start the next batch. Consider configuration spaces that contain hyperparameters such as the number of filters or number of layers of a deep neural network. Hyperparameter configurations that contain a larger number of layers of filters will naturally take more time to finish, and all other trials in the same batch will have to wait at synchronisation points (grey area in Fig. 19.3.1) before we can continue the optimization process.

 

일반적으로 우리는 동기식 병렬 하이퍼파라미터 최적화와 비동기식 병렬 하이퍼파라미터 최적화를 구별합니다(그림 19.3.1 참조). 동기 설정에서는 다음 배치를 시작하기 전에 동시에 실행 중인 모든 시도가 완료될 때까지 기다립니다. 심층 신경망의 필터 수나 레이어 수와 같은 하이퍼파라미터가 포함된 구성 공간을 고려하세요. 더 많은 수의 필터 레이어를 포함하는 하이퍼파라미터 구성은 당연히 완료하는 데 더 많은 시간이 걸립니다. 그리고 동일한 배치의 다른 모든 시도는 최적화 프로세스를 계속하기 전에 동기화 지점(그림 19.3.1의 회색 영역)에서 기다려야 합니다.

 

In the asynchronous setting we immediately schedule a new trial as soon as resources become available. This will optimally exploit our resources, since we can avoid any synchronisation overhead. For random search, each new hyperparameter configuration is chosen independently of all others, and in particular without exploiting observations from any prior evaluation. This means we can trivially parallelize random search asynchronously. This is not straight-forward with more sophisticated methods that make decision based on previous observations (see Section 19.5). While we need access to more resources than in the sequential setting, asynchronous random search exhibits a linear speed-up, in that a certain performance is reached K times faster if K trials can be run in parallel.

 

비동기식 설정에서는 리소스를 사용할 수 있게 되는 즉시 새로운 평가판을 예약합니다. 동기화 오버헤드를 피할 수 있으므로 리소스를 최적으로 활용하게 됩니다. 무작위 검색의 경우 각각의 새로운 하이퍼파라미터 구성은 다른 모든 구성과 독립적으로 선택되며, 특히 이전 평가에서 관찰한 내용을 활용하지 않습니다. 이는 무작위 검색을 비동기적으로 간단하게 병렬화할 수 있음을 의미합니다. 이는 이전 관찰을 기반으로 결정을 내리는 보다 정교한 방법으로는 간단하지 않습니다(19.5절 참조). 순차 설정보다 더 많은 리소스에 액세스해야 하지만 비동기 무작위 검색은 K번 시도를 병렬로 실행할 수 있으면 특정 성능에 K배 더 빠르게 도달한다는 점에서 선형적인 속도 향상을 나타냅니다.

 

Fig. 19.3.1&nbsp; Distributing the hyperparameter optimization process either synchronously or asynchronously. Compared to the sequential setting, we can reduce the overall wall-clock time while keep the total compute constant. Synchronous scheduling might lead to idling workers in the case of stragglers.&nbsp;그림 19.3.1 하이퍼파라미터 최적화 프로세스를 동기식 또는 비동기식으로 배포합니다. 순차 설정에 비해 총 계산을 일정하게 유지하면서 전체 벽시계 시간을 줄일 수 있습니다. 동기식 일정은 낙오자의 경우 유휴 작업자로 이어질 수 있습니다.

 

In this notebook, we will look at asynchronous random search that, where trials are executed in multiple python processes on the same machine. Distributed job scheduling and execution is difficult to implement from scratch. We will use Syne Tune (Salinas et al., 2022), which provides us with a simple interface for asynchronous HPO. Syne Tune is designed to be run with different execution back-ends, and the interested reader is invited to study its simple APIs in order to learn more about distributed HPO.

 

이 노트북에서는 동일한 머신의 여러 Python 프로세스에서 시도가 실행되는 비동기 무작위 검색을 살펴보겠습니다. 분산 작업 스케줄링 및 실행은 처음부터 구현하기 어렵습니다. 비동기식 HPO를 위한 간단한 인터페이스를 제공하는 Syne Tune(Salinas et al., 2022)을 사용하겠습니다. Syne Tune은 다양한 실행 백엔드와 함께 실행되도록 설계되었으며 관심 있는 독자는 분산형 HPO에 대해 자세히 알아보기 위해 간단한 API를 연구하도록 초대됩니다.

 

import logging
from d2l import torch as d2l

logging.basicConfig(level=logging.INFO)
from syne_tune import StoppingCriterion, Tuner
from syne_tune.backend.python_backend import PythonBackend
from syne_tune.config_space import loguniform, randint
from syne_tune.experiments import load_experiment
from syne_tune.optimizer.baselines import RandomSearch

위의 코드는 하이퍼파라미터 최적화를 위한 도구와 라이브러리를 가져오고 초기 설정을 수행하는 부분입니다. 코드의 주요 내용은 다음과 같습니다:

  1. import logging: 로그 메시지를 기록하기 위한 로깅 모듈을 가져옵니다.
  2. from d2l import torch as d2l: "d2l" 패키지에서 PyTorch 관련 기능을 가져옵니다. 이 패키지는 Deep Learning for Dummies(이해를 돕기 위한 딥 러닝)에서 사용되는 유틸리티 함수와 도구를 제공합니다.
  3. logging.basicConfig(level=logging.INFO): 로깅 레벨을 설정하고 로깅을 초기화합니다. 이 코드는 INFO 레벨 이상의 로그 메시지를 표시하도록 설정합니다.
  4. from syne_tune import StoppingCriterion, Tuner: "syne_tune" 라이브러리에서 하이퍼파라미터 튜닝에 필요한 클래스인 StoppingCriterion과 Tuner를 가져옵니다.
  5. from syne_tune.backend.python_backend import PythonBackend: "syne_tune" 라이브러리에서 하이퍼파라미터 튜닝에 사용되는 백엔드(backend)인 PythonBackend를 가져옵니다.
  6. from syne_tune.config_space import loguniform, randint: 하이퍼파라미터 탐색 공간을 정의하기 위해 "syne_tune" 라이브러리에서 loguniform과 randint 함수를 가져옵니다. 이 함수들을 사용하여 하이퍼파라미터의 분포를 정의할 수 있습니다.
  7. from syne_tune.experiments import load_experiment: 하이퍼파라미터 튜닝 실험을 로드하는 데 사용되는 load_experiment 함수를 가져옵니다.
  8. from syne_tune.optimizer.baselines import RandomSearch: 랜덤 서치 기반의 최적화 알고리즘인 RandomSearch를 가져옵니다.

이 코드는 하이퍼파라미터 튜닝을 위한 다양한 도구와 라이브러리를 가져와 초기 설정을 수행하며, 이후의 코드에서 하이퍼파라미터 튜닝 실험을 진행할 준비를 마칩니다.

INFO:root:SageMakerBackend is not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
AWS dependencies are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[aws]'
or (for everything)
   pip install 'syne-tune[extra]'
INFO:root:Ray Tune schedulers and searchers are not imported since dependencies are missing. You can install them with
   pip install 'syne-tune[raytune]'
or (for everything)
   pip install 'syne-tune[extra]'

 

19.3.1. Objective Function

First, we have to define a new objective function such that it now returns the performance back to Syne Tune via the report callback.

 

먼저, 보고서 콜백을 통해 성능을 Syne Tune으로 다시 반환하도록 새로운 목적 함수를 정의해야 합니다.

 

def hpo_objective_lenet_synetune(learning_rate, batch_size, max_epochs):
    from syne_tune import Reporter
    from d2l import torch as d2l

    model = d2l.LeNet(lr=learning_rate, num_classes=10)
    trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1)
    data = d2l.FashionMNIST(batch_size=batch_size)
    model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
    report = Reporter()
    for epoch in range(1, max_epochs + 1):
        if epoch == 1:
            # Initialize the state of Trainer
            trainer.fit(model=model, data=data)
        else:
            trainer.fit_epoch()
        validation_error = trainer.validation_error().cpu().detach().numpy()
        report(epoch=epoch, validation_error=float(validation_error))

위의 코드는 하이퍼파라미터 최적화 실험을 위한 목표 함수인 hpo_objective_lenet_synetune를 정의하는 부분입니다. 이 함수는 SyneTune 라이브러리를 사용하여 하이퍼파라미터 튜닝을 수행하는데 필요한 내용을 포함하고 있습니다. 코드의 주요 내용은 다음과 같습니다:

  1. from syne_tune import Reporter: SyneTune 라이브러리에서 Reporter 클래스를 가져옵니다. Reporter는 실험 결과를 기록하고 보고하는 데 사용됩니다.
  2. model = d2l.LeNet(lr=learning_rate, num_classes=10): LeNet 아키텍처를 사용하여 모델을 생성합니다. 이때 학습률(learning_rate)은 인자로 전달된 값으로 설정됩니다.
  3. trainer = d2l.HPOTrainer(max_epochs=1, num_gpus=1): 하이퍼파라미터 최적화 트레이너인 HPOTrainer를 생성합니다. max_epochs와 num_gpus는 인자로 전달된 값으로 설정됩니다.
  4. data = d2l.FashionMNIST(batch_size=batch_size): Fashion MNIST 데이터셋을 사용하여 데이터를 로드합니다. 미니배치 크기(batch_size)는 인자로 전달된 값으로 설정됩니다.
  5. model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn): 모델의 초기화를 수행합니다. 초기화에 필요한 데이터를 제공하고, CNN 모델을 초기화하는 함수인 d2l.init_cnn을 사용합니다.
  6. report = Reporter(): 실험 결과를 기록하기 위해 Reporter 객체를 생성합니다.
  7. for epoch in range(1, max_epochs + 1):: 주어진 에폭 수(max_epochs)에 대한 반복문을 시작합니다.
  8. if epoch == 1:: 첫 번째 에폭에서는 트레이너의 초기 상태를 초기화합니다.
  9. trainer.fit(model=model, data=data): 트레이너를 사용하여 모델을 학습합니다.
  10. else:: 첫 번째 에폭 이후에는 trainer.fit_epoch()를 호출하여 추가 에폭을 학습합니다.
  11. validation_error = trainer.validation_error().cpu().detach().numpy(): 검증 오차를 계산하고 numpy 배열로 변환하여 저장합니다.
  12. report(epoch=epoch, validation_error=float(validation_error)): 현재 에폭과 검증 오차를 Reporter에 보고합니다.

이러한 과정을 통해 hpo_objective_lenet_synetune 함수는 하이퍼파라미터 최적화 실험을 수행하고, 각 에폭에서의 검증 오차를 기록하여 SyneTune 라이브러리와 함께 사용할 수 있도록 준비합니다.

 

Note that the PythonBackend of Syne Tune requires dependencies to be imported inside the function definition.

 

Syne Tune의 PythonBackend를 사용하려면 함수 정의 내로 종속성을 가져와야 합니다.

 

19.3.2. Asynchronous Scheduler

 

First, we define the number of workers that evaluate trials concurrently. We also need to specify how long we want to run random search, by defining an upper limit on the total wall-clock time.

 

먼저, 동시에 시험을 평가하는 작업자 수를 정의합니다. 또한 총 벽시계 시간의 상한을 정의하여 무작위 검색을 실행할 기간을 지정해야 합니다.

 

n_workers = 2  # Needs to be <= the number of available GPUs

max_wallclock_time = 12 * 60  # 12 minutes

위의 코드는 하이퍼파라미터 최적화 실험에 대한 몇 가지 설정을 지정하는 부분입니다.

  1. n_workers = 2: 병렬로 실행되는 작업자(worker)의 수를 나타냅니다. 이 값은 사용 가능한 GPU 수보다 작거나 같아야 합니다. 즉, 최대로 사용할 GPU 수를 지정합니다. 이 예에서는 2개의 GPU를 사용하도록 설정되어 있습니다.
  2. max_wallclock_time = 12 * 60: 최대 실행 시간을 분 단위로 나타냅니다. 즉, 실험의 최대 실행 시간을 12분으로 설정하고 있습니다. 이 값은 실험을 제한하는 데 사용될 수 있으며, 지정된 시간 내에 실험이 완료되어야 합니다. 실험에 따라 실행 시간이 다를 수 있으므로 적절한 값으로 설정해야 합니다. 이 예에서는 12분으로 설정되어 있으므로 실험이 12분 이내에 완료되어야 합니다.

 

Next, we state which metric we want to optimize and whether we want to minimize or maximize this metric. Namely, metric needs to correspond to the argument name passed to the report callback.

 

다음으로, 최적화할 측정항목과 이 측정항목을 최소화할지 최대화할지 여부를 명시합니다. 즉, 측정항목은 보고서 콜백에 전달된 인수 이름과 일치해야 합니다.

 

mode = "min"
metric = "validation_error"

위의 코드는 하이퍼파라미터 튜닝 실험에서 사용되는 최적화 모드와 평가 지표를 설정하는 부분입니다.

  1. mode = "min": 최적화 모드를 나타내는 변수입니다. "min"으로 설정되어 있으므로 최적화 과정에서는 평가 지표(metric)를 최소화하는 방향으로 진행됩니다. 다시 말해, 모델의 성능을 향상시키는 방향으로 하이퍼파라미터가 조절될 것입니다. 이는 일반적으로 검증 오차나 손실 함수를 최소화하는 경우에 사용됩니다.
  2. metric = "validation_error": 평가 지표를 나타내는 변수입니다. 이 변수는 최적화 모드에 따라 설정되며, 실험 중에 평가되는 지표를 나타냅니다. 이 경우 "validation_error"로 설정되어 있으므로 검증 오차를 평가 지표로 사용하여 최적화를 수행할 것입니다. 검증 오차를 최소화하도록 하이퍼파라미터를 조절하는 것이 목표입니다.

이러한 설정은 하이퍼파라미터 튜닝 실험의 목표와 방향성을 결정하는 중요한 요소 중 하나입니다.

 

We use the configuration space from our previous example. In Syne Tune, this dictionary can also be used to pass constant attributes to the training script. We make use of this feature in order to pass max_epochs. Moreover, we specify the first configuration to be evaluated in initial_config.

 

이전 예제의 구성 공간을 사용합니다. Syne Tune에서 이 사전을 사용하여 상수 속성을 교육 스크립트에 전달할 수도 있습니다. max_epochs를 전달하기 위해 이 기능을 사용합니다. 또한,initial_config에서 평가할 첫 번째 구성을 지정합니다.

 

config_space = {
    "learning_rate": loguniform(1e-2, 1),
    "batch_size": randint(32, 256),
    "max_epochs": 10,
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 하이퍼파라미터 튜닝 실험을 위한 하이퍼파라미터 공간과 초기 설정을 정의하는 부분입니다.

  1. config_space: 하이퍼파라미터 탐색 공간을 나타내는 딕셔너리입니다. 이 공간에는 다양한 하이퍼파라미터의 범위나 분포를 정의할 수 있습니다. 여기서 정의된 하이퍼파라미터는 다음과 같습니다:
    • "learning_rate": 학습률(learning rate)을 나타냅니다. loguniform(1e-2, 1)은 0.01에서 1 사이의 로그 균등 분포를 가진 값을 의미합니다.
    • "batch_size": 미니배치 크기(batch size)를 나타냅니다. randint(32, 256)은 32에서 256 사이의 정수 값을 나타냅니다.
    • "max_epochs": 최대 에폭 수를 나타냅니다. 여기서는 고정값으로 10으로 설정되어 있습니다.
  2. initial_config: 초기 하이퍼파라미터 설정을 나타내는 딕셔너리입니다. 실험의 초기 단계에서 사용할 하이퍼파라미터 설정을 정의합니다. 이 설정은 실험의 초기값으로 사용됩니다. 여기서는 다음과 같은 하이퍼파라미터 설정을 가지고 있습니다:
    • "learning_rate": 초기 학습률을 0.1로 설정합니다.
    • "batch_size": 초기 미니배치 크기를 128로 설정합니다.

이렇게 정의된 하이퍼파라미터 공간과 초기 설정은 하이퍼파라미터 튜닝 실험을 수행할 때 사용됩니다. 실험은 이 하이퍼파라미터 공간에서 하이퍼파라미터를 샘플링하고, 초기 설정을 시작점으로 하여 최적의 하이퍼파라미터 조합을 찾게 됩니다.

 

Next, we need to specify the back-end for job executions. Here we just consider the distribution on a local machine where parallel jobs are executed as sub-processes. However, for large scale HPO, we could run this also on a cluster or cloud environment, where each trial consumes a full instance.

 

다음으로 작업 실행을 위한 백엔드를 지정해야 합니다. 여기서는 병렬 작업이 하위 프로세스로 실행되는 로컬 시스템에서의 배포를 고려합니다. 그러나 대규모 HPO의 경우 각 평가판이 전체 인스턴스를 사용하는 클러스터 또는 클라우드 환경에서도 이를 실행할 수 있습니다.

 

trial_backend = PythonBackend(
    tune_function=hpo_objective_lenet_synetune,
    config_space=config_space,
)

위의 코드는 실험을 실행하기 위해 SyneTune 라이브러리의 Python 백엔드를 설정하는 부분입니다.

  1. trial_backend = PythonBackend(...): PythonBackend는 SyneTune 라이브러리에서 실험을 수행하기 위한 백엔드(실행 환경)를 설정하는데 사용됩니다. 이 백엔드는 Python 코드를 실행하는 데 사용됩니다.
  2. tune_function=hpo_objective_lenet_synetune: tune_function 매개변수에는 하이퍼파라미터 최적화 실험을 실행할 함수를 지정합니다. 여기서는 hpo_objective_lenet_synetune 함수를 지정하여 이 함수가 하이퍼파라미터 튜닝을 수행하도록 합니다.
  3. config_space=config_space: config_space 매개변수에는 하이퍼파라미터 탐색 공간을 지정합니다. 이전에 정의한 config_space 딕셔너리가 여기에 사용됩니다.

이렇게 설정된 trial_backend는 하이퍼파라미터 최적화 실험을 실행하는 데 필요한 백엔드 설정을 가지고 있습니다. 이제 이 백엔드를 사용하여 하이퍼파라미터 튜닝 실험을 실행할 수 있습니다.

 

We can now create the scheduler for asynchronous random search, which is similar in behaviour to our BasicScheduler from Section 19.2.

 

이제 섹션 19.2의 BasicScheduler와 동작이 유사한 비동기 무작위 검색을 위한 스케줄러를 생성할 수 있습니다.

 

scheduler = RandomSearch(
    config_space,
    metric=metric,
    mode=mode,
    points_to_evaluate=[initial_config],
)

위의 코드는 랜덤 서치(Random Search)를 사용하여 하이퍼파라미터 튜닝 실험을 설정하는 부분입니다.

  1. scheduler = RandomSearch(...): RandomSearch는 랜덤 서치 최적화 전략을 사용하는 스케줄러를 설정하는데 사용됩니다.
  2. config_space: config_space 매개변수에는 하이퍼파라미터 탐색 공간을 지정합니다. 이전에 정의한 config_space 딕셔너리가 여기에 사용됩니다.
  3. metric=metric: metric 매개변수에는 평가 지표(metric)를 지정합니다. 이전에 설정한 metric 변수가 사용됩니다. 이 경우 "validation_error"가 평가 지표로 사용됩니다.
  4. mode=mode: mode 매개변수에는 최적화 모드를 지정합니다. 이전에 설정한 mode 변수가 사용됩니다. 이 경우 "min" 모드로 설정되어 있으므로 평가 지표를 최소화하려고 시도할 것입니다.
  5. points_to_evaluate=[initial_config]: points_to_evaluate 매개변수에는 초기 하이퍼파라미터 설정을 포함하는 리스트를 지정합니다. 이전에 정의한 initial_config 변수가 사용됩니다. 이는 랜덤 서치의 시작점으로 사용됩니다.

이렇게 설정된 scheduler는 랜덤 서치 최적화 전략을 사용하여 하이퍼파라미터 탐색을 수행합니다. 랜덤 서치는 주어진 하이퍼파라미터 탐색 공간에서 무작위로 하이퍼파라미터 조합을 샘플링하고, 해당 조합을 평가하여 최적의 조합을 찾는 방법 중 하나입니다.

INFO:syne_tune.optimizer.schedulers.fifo:max_resource_level = 10, as inferred from config_space
INFO:syne_tune.optimizer.schedulers.fifo:Master random_seed = 2737092907

Syne Tune also features a Tuner, where the main experiment loop and bookkeeping is centralized, and interactions between scheduler and back-end are mediated.

 

Syne Tune에는 주요 실험 루프와 장부를 중앙 집중화하고 스케줄러와 백엔드 간의 상호 작용을 중재하는 튜너 기능도 있습니다.

 

stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time)

tuner = Tuner(
    trial_backend=trial_backend,
    scheduler=scheduler,
    stop_criterion=stop_criterion,
    n_workers=n_workers,
    print_update_interval=int(max_wallclock_time * 0.6),
)

위의 코드는 하이퍼파라미터 튜닝 실험을 위한 Tuner 객체를 설정하는 부분입니다.

  1. stop_criterion = StoppingCriterion(max_wallclock_time=max_wallclock_time): StoppingCriterion은 실험이 종료될 조건을 설정하는데 사용됩니다. 이전에 정의한 max_wallclock_time 변수를 사용하여 실험이 최대 실행 시간을 초과하면 종료되도록 설정합니다.
  2. tuner = Tuner(...): Tuner 객체를 설정합니다. 이 객체는 하이퍼파라미터 튜닝 실험을 제어하고 실행하는 역할을 합니다.
    • trial_backend: trial_backend 매개변수에는 실험을 실행할 백엔드(실행 환경)를 지정합니다. 이전에 설정한 trial_backend가 사용됩니다.
    • scheduler: scheduler 매개변수에는 스케줄러를 지정합니다. 이전에 설정한 scheduler가 사용됩니다.
    • stop_criterion: stop_criterion 매개변수에는 실험이 종료될 조건을 지정합니다. 이전에 설정한 stop_criterion이 사용됩니다.
    • n_workers: n_workers 매개변수에는 병렬로 실행될 작업자(worker)의 수를 지정합니다. 이전에 설정한 n_workers 변수가 사용됩니다.
    • print_update_interval: print_update_interval 매개변수에는 실험 진행 상황을 출력할 간격을 설정합니다. 여기서는 최대 실행 시간의 60%에 해당하는 간격으로 설정되어 있습니다.

Tuner 객체는 설정된 백엔드와 스케줄러를 사용하여 하이퍼파라미터 튜닝 실험을 실행하며, 종료 조건이 충족되거나 최대 실행 시간이 초과되면 실험을 종료합니다.

 

Let us run our distributed HPO experiment. According to our stopping criterion, it will run for about 12 minutes.

 

분산된 HPO 실험을 실행해 보겠습니다. 우리의 중지 기준에 따르면 약 12분 동안 실행됩니다.

 

tuner.run()

위의 코드는 설정된 Tuner 객체를 사용하여 하이퍼파라미터 튜닝 실험을 실행하는 부분입니다.

tuner.run() 함수를 호출하면 하이퍼파라미터 튜닝 실험이 시작됩니다. Tuner 객체는 설정된 백엔드와 스케줄러를 사용하여 하이퍼파라미터 공간에서 하이퍼파라미터 조합을 샘플링하고, 각 조합을 평가하여 최적의 하이퍼파라미터 조합을 찾습니다. 설정된 종료 조건이 충족되거나 최대 실행 시간이 초과되면 실험을 종료하고 최적의 하이퍼파라미터 조합 및 결과를 반환합니다.

실험 진행 상황은 이전에 설정한 print_update_interval 간격으로 출력될 것입니다. 이 코드를 실행하면 하이퍼파라미터 튜닝 실험이 실행되고, 최적의 모델을 찾기 위해 하이퍼파라미터 조합을 탐색하게 됩니다.

INFO:syne_tune.tuner:results of trials will be saved on /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958
INFO:root:Detected 4 GPUs
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1 --batch_size 128 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/0/checkpoints
INFO:syne_tune.tuner:(trial 0) - scheduled config {'learning_rate': 0.1, 'batch_size': 128, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1702844732454753 --batch_size 114 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/1/checkpoints
INFO:syne_tune.tuner:(trial 1) - scheduled config {'learning_rate': 0.1702844732454753, 'batch_size': 114, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 0 completed.
INFO:syne_tune.tuner:Trial trial_id 1 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.34019846567238493 --batch_size 221 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/2/checkpoints
INFO:syne_tune.tuner:(trial 2) - scheduled config {'learning_rate': 0.34019846567238493, 'batch_size': 221, 'max_epochs': 10}
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.014628124155727769 --batch_size 88 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/3/checkpoints
INFO:syne_tune.tuner:(trial 3) - scheduled config {'learning_rate': 0.014628124155727769, 'batch_size': 88, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 2 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.1114831485450576 --batch_size 142 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/4/checkpoints
INFO:syne_tune.tuner:(trial 4) - scheduled config {'learning_rate': 0.1114831485450576, 'batch_size': 142, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 3 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.014076038679980779 --batch_size 223 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/5/checkpoints
INFO:syne_tune.tuner:(trial 5) - scheduled config {'learning_rate': 0.014076038679980779, 'batch_size': 223, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 4 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.02558173674804846 --batch_size 62 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/6/checkpoints
INFO:syne_tune.tuner:(trial 6) - scheduled config {'learning_rate': 0.02558173674804846, 'batch_size': 62, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 5 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.026035979388614055 --batch_size 139 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/7/checkpoints
INFO:syne_tune.tuner:(trial 7) - scheduled config {'learning_rate': 0.026035979388614055, 'batch_size': 139, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 6 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.24202494130424274 --batch_size 231 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/8/checkpoints
INFO:syne_tune.tuner:(trial 8) - scheduled config {'learning_rate': 0.24202494130424274, 'batch_size': 231, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 7 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10483132064775551 --batch_size 145 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/9/checkpoints
INFO:syne_tune.tuner:(trial 9) - scheduled config {'learning_rate': 0.10483132064775551, 'batch_size': 145, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 8 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.017898854850751864 --batch_size 51 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/10/checkpoints
INFO:syne_tune.tuner:(trial 10) - scheduled config {'learning_rate': 0.017898854850751864, 'batch_size': 51, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 9 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.9645419978270817 --batch_size 200 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/11/checkpoints
INFO:syne_tune.tuner:(trial 11) - scheduled config {'learning_rate': 0.9645419978270817, 'batch_size': 200, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 11 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.10559888854748693 --batch_size 40 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/12/checkpoints
INFO:syne_tune.tuner:(trial 12) - scheduled config {'learning_rate': 0.10559888854748693, 'batch_size': 40, 'max_epochs': 10}
INFO:syne_tune.tuner:tuning status (last metric is reported)
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0  Completed    10       0.100000         128          10   10.0          0.277195    64.928907
        1  Completed    10       0.170284         114          10   10.0          0.286225    65.434195
        2  Completed    10       0.340198         221          10   10.0          0.218990    59.729758
        3  Completed    10       0.014628          88          10   10.0          0.899920    81.001636
        4  Completed    10       0.111483         142          10   10.0          0.268684    64.427400
        5  Completed    10       0.014076         223          10   10.0          0.899922    61.264475
        6  Completed    10       0.025582          62          10   10.0          0.399520    75.966186
        7  Completed    10       0.026036         139          10   10.0          0.899988    62.261541
        8  Completed    10       0.242025         231          10   10.0          0.257636    58.186485
        9  Completed    10       0.104831         145          10   10.0          0.273898    59.771699
       10 InProgress     8       0.017899          51          10    8.0          0.496118    66.999746
       11  Completed    10       0.964542         200          10   10.0          0.181600    59.159662
       12 InProgress     0       0.105599          40          10      -                 -            -
2 trials running, 11 finished (11 until the end), 436.60s wallclock-time

INFO:syne_tune.tuner:Trial trial_id 10 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.5846051207380589 --batch_size 35 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/13/checkpoints
INFO:syne_tune.tuner:(trial 13) - scheduled config {'learning_rate': 0.5846051207380589, 'batch_size': 35, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 12 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.2468891379769198 --batch_size 146 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/14/checkpoints
INFO:syne_tune.tuner:(trial 14) - scheduled config {'learning_rate': 0.2468891379769198, 'batch_size': 146, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 13 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.12956867470224812 --batch_size 218 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/15/checkpoints
INFO:syne_tune.tuner:(trial 15) - scheduled config {'learning_rate': 0.12956867470224812, 'batch_size': 218, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 14 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.24900745354561854 --batch_size 103 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/16/checkpoints
INFO:syne_tune.tuner:(trial 16) - scheduled config {'learning_rate': 0.24900745354561854, 'batch_size': 103, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 15 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.03903577426988046 --batch_size 80 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/17/checkpoints
INFO:syne_tune.tuner:(trial 17) - scheduled config {'learning_rate': 0.03903577426988046, 'batch_size': 80, 'max_epochs': 10}
INFO:syne_tune.tuner:Trial trial_id 16 completed.
INFO:root:running subprocess with command: /usr/bin/python /home/ci/.local/lib/python3.8/site-packages/syne_tune/backend/python_backend/python_entrypoint.py --learning_rate 0.01846559300690354 --batch_size 183 --max_epochs 10 --tune_function_root /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/tune_function --tune_function_hash 4d7d5b85e4537ad0c5d0a202623dcec5 --st_checkpoint_dir /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958/18/checkpoints
INFO:syne_tune.tuner:(trial 18) - scheduled config {'learning_rate': 0.01846559300690354, 'batch_size': 183, 'max_epochs': 10}
INFO:syne_tune.stopping_criterion:reaching max wallclock time (720), stopping there.
INFO:syne_tune.tuner:Stopping trials that may still be running.
INFO:syne_tune.tuner:Tuning finished, results of trials can be found on /home/ci/syne-tune/python-entrypoint-2023-08-18-19-45-39-958
--------------------
Resource summary (last result is reported):
 trial_id     status  iter  learning_rate  batch_size  max_epochs  epoch  validation_error  worker-time
        0  Completed    10       0.100000         128          10     10          0.277195    64.928907
        1  Completed    10       0.170284         114          10     10          0.286225    65.434195
        2  Completed    10       0.340198         221          10     10          0.218990    59.729758
        3  Completed    10       0.014628          88          10     10          0.899920    81.001636
        4  Completed    10       0.111483         142          10     10          0.268684    64.427400
        5  Completed    10       0.014076         223          10     10          0.899922    61.264475
        6  Completed    10       0.025582          62          10     10          0.399520    75.966186
        7  Completed    10       0.026036         139          10     10          0.899988    62.261541
        8  Completed    10       0.242025         231          10     10          0.257636    58.186485
        9  Completed    10       0.104831         145          10     10          0.273898    59.771699
       10  Completed    10       0.017899          51          10     10          0.405545    83.778503
       11  Completed    10       0.964542         200          10     10          0.181600    59.159662
       12  Completed    10       0.105599          40          10     10          0.182500    94.734384
       13  Completed    10       0.584605          35          10     10          0.153846   110.965637
       14  Completed    10       0.246889         146          10     10          0.215050    65.142847
       15  Completed    10       0.129569         218          10     10          0.313873    61.310455
       16  Completed    10       0.249007         103          10     10          0.196101    72.519127
       17 InProgress     9       0.039036          80          10      9          0.369000    73.403000
       18 InProgress     5       0.018466         183          10      5          0.900263    34.714568
2 trials running, 17 finished (17 until the end), 722.84s wallclock-time

validation_error: best 0.14451533555984497 for trial-id 13
--------------------

 

The logs of all evaluated hyperparameter configurations are stored for further analysis. At any time during the tuning job, we can easily get the results obtained so far and plot the incumbent trajectory.

 

평가된 모든 하이퍼파라미터 구성의 로그는 추가 분석을 위해 저장됩니다. 튜닝 작업 중 언제든지 지금까지 얻은 결과를 쉽게 얻고 기존 궤적을 그릴 수 있습니다.

 

d2l.set_figsize()
tuning_experiment = load_experiment(tuner.name)
tuning_experiment.plot()

 

19.3.3. Visualize the Asynchronous Optimization Process

Below we visualize how the learning curves of every trial (each color in the plot represents a trial) evolve during the asynchronous optimization process. At any point in time, there are as many trials running concurrently as we have workers. Once a trial finishes, we immediately start the next trial, without waiting for the other trials to finish. Idle time of workers is reduced to a minimum with asynchronous scheduling.

 

아래에서는 비동기 최적화 프로세스 동안 모든 시행(플롯의 각 색상은 시행을 나타냄)의 학습 곡선이 어떻게 발전하는지 시각화합니다. 어느 시점에서든 작업자 수만큼 동시에 실행되는 시험이 많이 있습니다. 시험이 끝나면 다른 시험이 끝날 때까지 기다리지 않고 즉시 다음 시험을 시작합니다. 비동기 스케줄링으로 작업자의 유휴 시간을 최소화합니다.

 

d2l.set_figsize([6, 2.5])
results = tuning_experiment.results

for trial_id in results.trial_id.unique():
    df = results[results["trial_id"] == trial_id]
    d2l.plt.plot(
        df["st_tuner_time"],
        df["validation_error"],
        marker="o"
    )

d2l.plt.xlabel("wall-clock time")
d2l.plt.ylabel("objective function")

위의 코드는 하이퍼파라미터 튜닝 실험 결과를 시각화하는 부분입니다.

  1. d2l.set_figsize([6, 2.5]): 그림의 크기를 설정하는 부분입니다. 이 경우 그림 크기가 [6, 2.5]로 설정됩니다.
  2. results = tuning_experiment.results: 이전에 실행한 하이퍼파라미터 튜닝 실험의 결과를 가져와 results 변수에 저장합니다.
  3. for trial_id in results.trial_id.unique():: 각 실험 트라이얼(trial)에 대해 반복하는 루프를 시작합니다. results.trial_id.unique()는 실험 트라이얼의 고유한 ID 목록을 가져옵니다.
  4. df = results[results["trial_id"] == trial_id]: 현재 트라이얼에 해당하는 결과만 선택하여 df 변수에 저장합니다.
  5. d2l.plt.plot(...): df에 저장된 결과를 시각화합니다. x축은 st_tuner_time으로, y축은 validation_error로 설정하며, marker="o"를 사용하여 점을 표시합니다.
  6. d2l.plt.xlabel("wall-clock time")와 d2l.plt.ylabel("objective function"): x축과 y축에 라벨을 추가합니다. x축은 "wall-clock time"을 나타내며, y축은 "objective function"을 나타냅니다.

이 코드는 각 실험 트라이얼의 실행 시간에 따른 목표 함수(여기서는 검증 오차)의 변화를 시각화합니다. 실험 결과를 통해 어떤 하이퍼파라미터 조합이 더 나은 성능을 보이는지를 파악할 수 있습니다.

Text(0, 0.5, 'objective function')

 

19.3.4. Summary

We can reduce the waiting time for random search substantially by distribution trials across parallel resources. In general, we distinguish between synchronous scheduling and asynchronous scheduling. Synchronous scheduling means that we sample a new batch of hyperparameter configurations once the previous batch finished. If we have a stragglers - trials that takes more time to finish than other trials - our workers need to wait at synchronization points. Asynchronous scheduling evaluates a new hyperparameter configurations as soon as resources become available, and, hence, ensures that all workers are busy at any point in time. While random search is easy to distribute asynchronously and does not require any change of the actual algorithm, other methods require some additional modifications.

 

병렬 리소스 전반에 걸친 배포 시도를 통해 무작위 검색 대기 시간을 크게 줄일 수 있습니다. 일반적으로 동기 스케줄링과 비동기 스케줄링을 구분합니다. 동기식 스케줄링은 이전 배치가 완료되면 새로운 하이퍼파라미터 구성 배치를 샘플링하는 것을 의미합니다. 다른 시도보다 완료하는 데 더 많은 시간이 걸리는 시도인 낙오자가 있는 경우 작업자는 동기화 지점에서 기다려야 합니다. 비동기식 스케줄링은 리소스를 사용할 수 있게 되는 즉시 새로운 하이퍼파라미터 구성을 평가하므로 모든 작업자가 언제든지 바쁜 상태가 되도록 보장합니다. 무작위 검색은 비동기적으로 배포하기 쉽고 실제 알고리즘을 변경할 필요가 없지만 다른 방법에는 몇 가지 추가 수정이 필요합니다.

 

19.3.5. Exercises

  1. Consider the DropoutMLP model implemented in Section 5.6, and used in Exercise 1 of Section 19.2.
    1. Implement an objective function hpo_objective_dropoutmlp_synetune to be used with Syne Tune. Make sure that your function reports the validation error after every epoch.
    2. Using the setup of Exercise 1 in Section 19.2, compare random search to Bayesian optimization. If you use SageMaker, feel free to use Syne Tune’s benchmarking facilities in order to run experiments in parallel. Hint: Bayesian optimization is provided as syne_tune.optimizer.baselines.BayesianOptimization.
    3. For this exercise, you need to run on an instance with at least 4 CPU cores. For one of the methods used above (random search, Bayesian optimization), run experiments with n_workers=1, n_workers=2, n_workers=4, and compare results (incumbent trajectories). At least for random search, you should observe linear scaling with respect to the number of workers. Hint: For robust results, you may have to average over several repetitions each.
  2. Advanced. The goal of this exercise is to implement a new scheduler in Syne Tune.
    1. Create a virtual environment containing both the d2lbook and syne-tune sources.
    2. Implement the LocalSearcher from Exercise 2 in Section 19.2 as a new searcher in Syne Tune. Hint: Read this tutorial. Alternatively, you may follow this example.
    3. Compare your new LocalSearcher with RandomSearch on the DropoutMLP benchmark.

 

 

 

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/hyperopt-api.html

 

19.2. Hyperparameter Optimization API — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.2. Hyperparameter Optimization API

 

Before we dive into the methodology, we will first discuss a basic code structure that allows us to efficiently implement various HPO algorithms. In general, all HPO algorithms considered here need to implement two decision making primitives, searching and scheduling. First, they need to sample new hyperparameter configurations, which often involves some kind of search over the configuration space. Second, for each configuration, an HPO algorithm needs to schedule its evaluation and decide how many resources to allocate for it. Once we start to evaluate a configuration, we will refer to it as a trial. We map these decisions to two classes, HPOSearcher and HPOScheduler. On top of that, we also provide a HPOTuner class that executes the optimization process.

 

방법론에 대해 알아보기 전에 먼저 다양한 HPO 알고리즘을 효율적으로 구현할 수 있는 기본 코드 구조에 대해 논의하겠습니다. 일반적으로 여기에서 고려되는 모든 HPO 알고리즘은 검색 searching 과 예약 scheduling이라는 두 가지 의사 결정 기본 요소를 구현해야 합니다. 첫째, 새로운 하이퍼파라미터 구성을 샘플링해야 하며, 여기에는 종종 구성 공간에 대한 일종의 검색이 포함됩니다. 둘째, 각 구성에 대해 HPO 알고리즘은 평가 일정을 계획하고 이에 할당할 리소스 수를 결정해야 합니다. 구성 평가를 시작하면 이를 평가판이라고 합니다. 우리는 이러한 결정을 HPOSearcher와 HPOScheduler라는 두 클래스에 매핑합니다. 또한 최적화 프로세스를 실행하는 HPOTuner 클래스도 제공합니다.

 

This concept of scheduler and searcher is also implemented in popular HPO libraries, such as Syne Tune (Salinas et al., 2022), Ray Tune (Liaw et al., 2018) or Optuna (Akiba et al., 2019).

 

이 스케줄러 및 검색기 개념은 Syne Tune(Salinas et al., 2022), Ray Tune(Liaw et al., 2018) 또는 Optuna(Akiba et al., 2019)와 같은 인기 있는 HPO 라이브러리에서도 구현됩니다.

 

import time
from scipy import stats
from d2l import torch as d2l

위의 코드는 파이썬 모듈 및 라이브러리를 가져오는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. import time: 파이썬의 내장 모듈인 time 모듈을 가져옵니다. 이 모듈은 시간과 관련된 함수를 제공하며, 시간 지연(delay)을 생성하거나 시간을 측정하는 데 사용될 수 있습니다.
  2. from scipy import stats: SciPy 라이브러리에서 stats 모듈을 가져옵니다. SciPy는 과학 및 공학 연산을 위한 파이썬 라이브러리로, 통계, 최적화, 선형 대수, 신호 처리 등 다양한 기능을 제공합니다. 여기서는 주로 확률 분포와 통계 함수를 사용하는 stats 모듈을 가져옵니다.
  3. from d2l import torch as d2l: "Dive into Deep Learning" (D2L) 도서와 관련된 PyTorch 유틸리티 함수 및 도움말 기능을 제공하는 d2l 라이브러리에서 PyTorch 모듈을 가져옵니다. 이 라이브러리는 딥러닝 교육 및 예제 코드를 지원하는 데 사용됩니다. 여기서는 d2l 라이브러리에서 torch 모듈을 가져와서 d2l로 별칭을 붙입니다.

이 코드는 필요한 모듈과 라이브러리를 가져와서 이후의 작업에서 사용할 수 있도록 설정하는 부분입니다.

 

Hyperparameter Optimization API란 (GPT 3.5 답변)

 

The Hyperparameter Optimization (HPO) API refers to a programming interface or toolset that allows developers and data scientists to perform hyperparameter optimization efficiently and effectively. This API typically includes functions, classes, and methods for configuring, running, and managing the hyperparameter optimization process.

 

하이퍼파라미터 최적화 (HPO) API는 개발자와 데이터 과학자가 하이퍼파라미터 최적화를 효율적이고 효과적으로 수행할 수 있도록 하는 프로그래밍 인터페이스 또는 도구 세트를 가리킵니다. 이 API에는 하이퍼파라미터 최적화 프로세스를 구성하고 실행하며 관리하는 데 사용되는 함수, 클래스 및 메서드가 포함됩니다.

 

Here are some key components and functionalities often found in an HPO API:

 

다음은 일반적으로 HPO API에서 찾을 수 있는 주요 구성 요소와 기능입니다.

 

  1. Hyperparameter Configuration: The API allows users to define the hyperparameters they want to optimize and specify their respective search spaces. This involves specifying the range of values or distribution from which each hyperparameter should be sampled during optimization.

    하이퍼파라미터 구성: API를 통해 사용자는 최적화하려는 하이퍼파라미터를 정의하고 해당 하이퍼파라미터의 검색 공간을 지정할 수 있습니다. 이는 각 하이퍼파라미터의 최적화 중에 샘플링해야 하는 값 또는 분포를 지정하는 것을 포함합니다.

  2. Objective Function: Users can define the objective function (also known as the loss or evaluation function) that quantifies the performance of a machine learning model with a given set of hyperparameters. The API provides a way to evaluate the model's performance using this function.

    목적 함수: 사용자는 주어진 하이퍼파라미터 세트에 대한 기계 학습 모델의 성능을 양적화하는 목적 함수(손실 또는 평가 함수로도 알려짐)를 정의할 수 있습니다. API는 이 함수를 사용하여 모델의 성능을 평가하는 방법을 제공합니다.

  3. Optimization Algorithms: The API offers a selection of optimization algorithms such as random search, Bayesian optimization, genetic algorithms, or more advanced techniques. Users can choose the algorithm that best suits their optimization problem.

    최적화 알고리즘: API는 무작위 검색, 베이지안 최적화, 유전 알고리즘 또는 더 고급 기술과 같은 최적화 알고리즘을 선택할 수 있는 옵션을 제공합니다. 사용자는 최적화 문제에 가장 적합한 알고리즘을 선택할 수 있습니다.

  4. Concurrency and Parallelism: It provides options for running multiple hyperparameter optimization trials concurrently or in parallel. This can significantly speed up the optimization process, especially when optimizing computationally expensive models.

    동시성과 병렬 처리: 일부 HPO API는 여러 하이퍼파라미터 최적화 시행을 동시에 또는 병렬로 실행하는 옵션을 제공합니다. 이렇게 하면 특히 계산 비용이 많이 드는 모델을 최적화할 때 최적화 프로세스가 크게 가속화될 수 있습니다.

  5. Early Stopping and Resource Management: Some HPO APIs support early stopping criteria based on the performance of ongoing trials. They can also manage resources, ensuring that the optimization process respects hardware constraints.

    조기 중지 및 리소스 관리: 일부 HPO API는 진행 중인 시행의 성능을 기반으로 조기 중지 기준을 지원합니다. 또한 하드웨어 제한을 존중하도록 최적화 프로세스를 관리할 수 있습니다.

  6. Results Tracking: The API may include functions for tracking and storing the results of each optimization trial, including hyperparameters, evaluation metrics, and other relevant information.

    결과 추적: API에는 각 하이퍼파라미터 최적화 시행의 결과를 추적하고 저장하는 함수가 포함될 수 있으며, 이는 하이퍼파라미터, 평가 메트릭, 기타 관련 정보를 포함합니다.

  7. Visualization and Reporting: It often includes tools for visualizing the progress of hyperparameter optimization, such as plots or graphs showing how the objective function changes over time.

    시각화 및 보고: 종종 하이퍼파라미터 최적화 진행 상황을 시각화하는 데 사용되는 도구를 포함하며, 이러한 도구는 목적 함수가 어떻게 시간에 따라 변하는지 보여주는 플롯이나 그래프를 제공합니다.

  8. Integration with Machine Learning Frameworks: Many HPO APIs are designed to seamlessly integrate with popular machine learning libraries and frameworks like TensorFlow, PyTorch, scikit-learn, and others.

    기계 학습 프레임워크 통합: 많은 HPO API는 인기 있는 기계 학습 라이브러리와 프레임워크인 TensorFlow, PyTorch, scikit-learn 및 기타 라이브러리와 원활하게 통합될 수 있도록 설계되었습니다.

  9. Customization: Advanced users can customize the optimization process by specifying custom algorithms, resource management policies, or search strategies.

    사용자 정의: 고급 사용자는 사용자 지정 알고리즘, 리소스 관리 정책 또는 검색 전략을 지정하여 최적화 프로세스를 사용자 정의할 수 있습니다.

  10. Hyperparameter Importance Analysis: Some APIs offer functionality for analyzing the importance of different hyperparameters in the final model's performance.

    하이퍼파라미터 중요도 분석: 일부 API는 최종 모델 성능에 대한 다른 하이퍼파라미터의 중요성을 분석하는 기능을 제공합니다.

Overall, the HPO API simplifies the process of hyperparameter tuning, allowing users to find optimal hyperparameter settings for their machine learning models more efficiently. It can save time and computational resources and help improve model performance. Popular examples of HPO APIs include Optuna, Hyperopt, and Ray Tune, among others.

전반적으로 HPO API는 하이퍼파라미터 튜닝 프로세스를 단순화하여 사용자가 기계 학습 모델의 최적 하이퍼파라미터 설정을 보다 효율적으로 찾을 수 있게 해줍니다. 시간과 계산 리소스를 절약하고 모델 성능을 향상시킬 수 있습니다. 인기 있는 HPO API 예제로는 Optuna, Hyperopt, Ray Tune 등이 있습니다.

 

19.2.1. Searcher

Below we define a base class for searchers, which provides a new candidate configuration through the sample_configuration function. A simple way to implement this function would be to sample configurations uniformly at random, as we did for random search in Section 19.1. More sophisticated algorithms, such as Bayesian optimization, will make these decisions based on the performance of previous trials. As a result, these algorithms are able to sample more promising candidates over time. We add the update function in order to update the history of previous trials, which can then be exploited to improve our sampling distribution.

 

아래에서는 Sample_configuration 함수를 통해 새로운 후보 구성을 제공하는 검색자를 위한 기본 클래스를 정의합니다. 이 기능을 구현하는 간단한 방법은 섹션 19.1에서 무작위 검색을 수행한 것처럼 무작위로 균일하게 구성을 샘플링하는 것입니다. 베이지안 최적화와 같은 보다 정교한 알고리즘은 이전 시도의 성능을 기반으로 이러한 결정을 내립니다. 결과적으로 이러한 알고리즘은 시간이 지남에 따라 더 유망한 후보자를 샘플링할 수 있습니다. 이전 시도의 기록을 업데이트하기 위해 업데이트 기능을 추가한 다음 샘플링 분포를 개선하는 데 활용할 수 있습니다.

 

class HPOSearcher(d2l.HyperParameters):  #@save
    def sample_configuration() -> dict:
        raise NotImplementedError

    def update(self, config: dict, error: float, additional_info=None):
        pass

위의 코드는 하이퍼파라미터(Hyperparameters) 탐색을 수행하는 클래스인 HPOSearcher를 정의하는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class HPOSearcher(d2l.HyperParameters):: HPOSearcher 클래스를 정의합니다. 이 클래스는 d2l.HyperParameters 클래스를 상속합니다.
  2. def sample_configuration() -> dict:: 하이퍼파라미터 탐색 과정에서 하이퍼파라미터 구성(configuration)을 샘플링하는 메서드를 정의합니다. 이 메서드는 하이퍼파라미터 탐색 알고리즘이 다음으로 시도할 하이퍼파라미터 구성을 생성하고 이를 딕셔너리 형태로 반환해야 합니다. 이 메서드는 추상 메서드로 구현되지 않으며 하위 클래스에서 구현되어야 합니다.
  3. def update(self, config: dict, error: float, additional_info=None):: 하이퍼파라미터 탐색 알고리즘이 하이퍼파라미터 구성을 시도한 후에, 해당 구성에 대한 결과인 검증 오차와 추가 정보를 기반으로 어떤 동작을 수행해야 하는지를 정의하는 메서드입니다. 이 메서드는 하이퍼파라미터 탐색 알고리즘이 현재 시도한 하이퍼파라미터 구성(config), 해당 구성에 대한 검증 오차(error), 그리고 추가 정보(additional_info)를 인자로 받습니다. 이 메서드는 추상 메서드로 구현되지 않으며 하위 클래스에서 구현되어야 합니다.

HPOSearcher 클래스는 하이퍼파라미터 탐색 과정에서 필요한 메서드를 정의하는 기본 클래스입니다. 실제 하이퍼파라미터 탐색을 위해서는 이 클래스를 상속하고 sample_configuration과 update 메서드를 구현해야 합니다. 이 클래스를 상속한 하위 클래스에서는 하이퍼파라미터 탐색 알고리즘에 따라 구체적인 동작을 정의하게 됩니다.

 

The following code shows how to implement our random search optimizer from the previous section in this API. As a slight extension, we allow the user to prescribe the first configuration to be evaluated via initial_config, while subsequent ones are drawn at random.

 

다음 코드는 이 API의 이전 섹션에서 무작위 검색 최적화 프로그램을 구현하는 방법을 보여줍니다. 약간의 확장으로 사용자가 초기 구성을 통해 평가할 첫 번째 구성을 규정하고 후속 구성은 무작위로 그릴 수 있습니다.

 

class RandomSearcher(HPOSearcher):  #@save
    def __init__(self, config_space: dict, initial_config=None):
        self.save_hyperparameters()

    def sample_configuration(self) -> dict:
        if self.initial_config is not None:
            result = self.initial_config
            self.initial_config = None
        else:
            result = {
                name: domain.rvs()
                for name, domain in self.config_space.items()
            }
        return result

위의 코드는 랜덤 탐색(Random Search)을 수행하는 RandomSearcher 클래스를 정의하는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class RandomSearcher(HPOSearcher):: RandomSearcher 클래스를 정의합니다. 이 클래스는 HPOSearcher 클래스를 상속합니다.
  2. def __init__(self, config_space: dict, initial_config=None):: RandomSearcher 클래스의 생성자 메서드를 정의합니다. 이 생성자 메서드는 두 개의 매개변수를 입력으로 받습니다.
    • config_space: 하이퍼파라미터 탐색을 위한 하이퍼파라미터 공간을 나타내는 딕셔너리입니다. 각 하이퍼파라미터의 이름과 확률 분포가 포함되어 있어야 합니다.
    • initial_config: 초기 하이퍼파라미터 구성을 나타내는 딕셔너리입니다. 기본값은 None으로 설정되어 있습니다.
  3. self.save_hyperparameters(): 하이퍼파라미터를 저장하는 메서드입니다. 이 메서드를 호출하여 RandomSearcher 클래스의 하이퍼파라미터를 저장합니다.
  4. def sample_configuration(self) -> dict:: 하이퍼파라미터 탐색 과정에서 하이퍼파라미터 구성을 랜덤하게 샘플링하는 메서드를 정의합니다. 이 메서드는 딕셔너리 형태로 하이퍼파라미터 구성을 반환해야 합니다.
    • 처음에 initial_config가 설정되어 있다면, 초기 구성을 사용하고 initial_config를 None으로 설정합니다.
    • 그렇지 않으면, config_space에 정의된 각 하이퍼파라미터에 대해 해당 확률 분포(domain)에서 랜덤하게 값을 샘플링하여 딕셔너리로 구성합니다.
    • 최종적으로 샘플링된 하이퍼파라미터 구성을 반환합니다.

RandomSearcher 클래스는 랜덤 탐색을 수행하는 클래스로, sample_configuration 메서드에서 랜덤하게 하이퍼파라미터를 선택하여 반환합니다. 이를 통해 하이퍼파라미터 탐색을 무작위로 수행하는 간단한 탐색 전략을 구현할 수 있습니다.

 

19.2.2. Scheduler

 

Beyond sampling configurations for new trials, we also need to decide when and for how long to run a trial. In practice, all these decisions are done by the HPOScheduler, which delegates the choice of new configurations to a HPOSearcher. The suggest method is called whenever some resource for training becomes available. Apart from invoking sample_configuration of a searcher, it may also decide upon parameters like max_epochs (i.e., how long to train the model for). The update method is called whenever a trial returns a new observation.

 

새로운 시험을 위한 샘플링 구성 외에도 시험을 실행할 시기와 기간도 결정해야 합니다. 실제로 이러한 모든 결정은 새로운 구성 선택을 HPOSearcher에 위임하는 HPOScheduler에 의해 수행됩니다. 훈련을 위한 리소스를 사용할 수 있을 때마다 제안 메소드가 호출됩니다. 검색기의 Sample_configuration을 호출하는 것 외에도 max_epochs(즉, 모델을 훈련할 기간)와 같은 매개변수를 결정할 수도 있습니다. 업데이트 메소드는 시행에서 새로운 관찰이 반환될 때마다 호출됩니다.

 

class HPOScheduler(d2l.HyperParameters):  #@save
    def suggest(self) -> dict:
        raise NotImplementedError

    def update(self, config: dict, error: float, info=None):
        raise NotImplementedError

위의 코드는 하이퍼파라미터(Hyperparameters) 탐색을 위한 스케줄러인 HPOScheduler 클래스를 정의하는 부분입니다. 이 클래스는 하이퍼파라미터 탐색 과정에서 다양한 하이퍼파라미터 탐색 알고리즘과 스케줄링을 구현하기 위한 기반 클래스입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class HPOScheduler(d2l.HyperParameters):: HPOScheduler 클래스를 정의합니다. 이 클래스는 d2l.HyperParameters 클래스를 상속합니다.
  2. def suggest(self) -> dict:: 하이퍼파라미터 탐색 알고리즘이 다음으로 시도할 하이퍼파라미터 구성(configuration)을 제안하는 메서드를 정의합니다. 이 메서드는 추상 메서드로 구현되지 않으며 하위 클래스에서 구현되어야 합니다. 구체적인 하이퍼파라미터 탐색 알고리즘에 따라 다음 시도할 하이퍼파라미터 구성을 반환합니다.
  3. def update(self, config: dict, error: float, info=None):: 하이퍼파라미터 탐색 알고리즘이 하이퍼파라미터 구성을 시도한 후에, 해당 구성에 대한 결과인 검증 오차와 추가 정보를 기반으로 어떤 동작을 수행해야 하는지를 정의하는 메서드입니다. 이 메서드는 추상 메서드로 구현되지 않으며 하위 클래스에서 구현되어야 합니다. 검증 오차와 추가 정보를 활용하여 하이퍼파라미터 탐색 알고리즘의 스케줄링 및 업데이트 동작을 정의합니다.

HPOScheduler 클래스는 다양한 하이퍼파라미터 탐색 알고리즘과 스케줄링 전략을 구현하기 위한 기반 클래스로 사용될 수 있습니다. 구체적인 하이퍼파라미터 탐색 알고리즘에 따라 suggest와 update 메서드를 하위 클래스에서 구현하여 사용할 수 있습니다.

 

To implement random search, but also other HPO algorithms, we only need a basic scheduler that schedules a new configuration every time new resources become available.

 

무작위 검색 및 기타 HPO 알고리즘을 구현하려면 새 리소스를 사용할 수 있을 때마다 새 구성을 예약하는 기본 스케줄러만 필요합니다.

 

class BasicScheduler(HPOScheduler):  #@save
    def __init__(self, searcher: HPOSearcher):
        self.save_hyperparameters()

    def suggest(self) -> dict:
        return self.searcher.sample_configuration()

    def update(self, config: dict, error: float, info=None):
        self.searcher.update(config, error, additional_info=info)

위의 코드는 기본적인 스케줄러인 BasicScheduler 클래스를 정의하는 부분입니다. 이 클래스는 하이퍼파라미터 탐색 과정에서 하이퍼파라미터를 제안하고 업데이트하는 역할을 합니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class BasicScheduler(HPOScheduler):: BasicScheduler 클래스를 정의합니다. 이 클래스는 HPOScheduler 클래스를 상속합니다.
  2. def __init__(self, searcher: HPOSearcher):: BasicScheduler 클래스의 생성자 메서드를 정의합니다. 이 생성자 메서드는 하이퍼파라미터 탐색을 수행하는 searcher 객체를 입력으로 받습니다.
    • searcher: 하이퍼파라미터 탐색을 담당하는 HPOSearcher 클래스의 객체입니다.
  3. self.save_hyperparameters(): 하이퍼파라미터를 저장하는 메서드입니다. 이 메서드를 호출하여 BasicScheduler 클래스의 하이퍼파라미터를 저장합니다.
  4. def suggest(self) -> dict:: 하이퍼파라미터 제안 메서드를 구현합니다. 이 메서드는 searcher 객체의 sample_configuration 메서드를 호출하여 다음으로 시도할 하이퍼파라미터 구성을 제안합니다.
    • self.searcher.sample_configuration(): searcher 객체의 sample_configuration 메서드를 호출하여 하이퍼파라미터 구성을 제안합니다.
  5. def update(self, config: dict, error: float, info=None):: 하이퍼파라미터 업데이트 메서드를 구현합니다. 이 메서드는 searcher 객체의 update 메서드를 호출하여 하이퍼파라미터 탐색 알고리즘의 업데이트 동작을 수행합니다.
    • self.searcher.update(config, error, additional_info=info): searcher 객체의 update 메서드를 호출하여 하이퍼파라미터 구성(config)과 검증 오차(error)를 기반으로 업데이트 동작을 수행합니다. 추가 정보(info)도 함께 전달할 수 있습니다.

BasicScheduler 클래스는 단순한 스케줄러로, searcher 객체의 메서드를 호출하여 하이퍼파라미터를 제안하고 업데이트합니다. 구체적인 하이퍼파라미터 탐색 알고리즘과 스케줄링 전략은 searcher 객체에서 결정됩니다. 이 클래스를 사용하여 기본적인 하이퍼파라미터 탐색을 수행할 수 있습니다.

19.2.3. Tuner

 

Finally, we need a component that runs the scheduler/searcher and does some book-keeping of the results. The following code implements a sequential execution of the HPO trials that evaluates one training job after the next and will serve as a basic example. We will later use Syne Tune for more scalable distributed HPO cases.

 

마지막으로 스케줄러/검색기를 실행하고 결과를 기록하는 구성 요소가 필요합니다. 다음 코드는 다음 훈련 작업을 차례로 평가하는 HPO 시도의 순차적 실행을 구현하며 기본 예제로 사용됩니다. 나중에 더 확장 가능한 분산 HPO 사례를 위해 Syne Tune을 사용할 것입니다.

 

class HPOTuner(d2l.HyperParameters):  #@save
    def __init__(self, scheduler: HPOScheduler, objective: callable):
        self.save_hyperparameters()
        # Bookeeping results for plotting
        self.incumbent = None
        self.incumbent_error = None
        self.incumbent_trajectory = []
        self.cumulative_runtime = []
        self.current_runtime = 0
        self.records = []

    def run(self, number_of_trials):
        for i in range(number_of_trials):
            start_time = time.time()
            config = self.scheduler.suggest()
            print(f"Trial {i}: config = {config}")
            error = self.objective(**config)
            error = float(error.cpu().detach().numpy())
            self.scheduler.update(config, error)
            runtime = time.time() - start_time
            self.bookkeeping(config, error, runtime)
            print(f"    error = {error}, runtime = {runtime}")

위의 코드는 하이퍼파라미터(Hyperparameters) 튜닝을 수행하는 HPOTuner 클래스를 정의하는 부분입니다. 이 클래스는 주어진 하이퍼파라미터 탐색 스케줄러(scheduler)와 목표 함수(objective)를 사용하여 하이퍼파라미터 탐색을 실행하고 결과를 기록하는 역할을 합니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class HPOTuner(d2l.HyperParameters):: HPOTuner 클래스를 정의합니다. 이 클래스는 d2l.HyperParameters 클래스를 상속합니다.
  2. def __init__(self, scheduler: HPOScheduler, objective: callable):: HPOTuner 클래스의 생성자 메서드를 정의합니다. 이 생성자 메서드는 두 개의 매개변수를 입력으로 받습니다.
    • scheduler: 하이퍼파라미터 탐색 스케줄러(HPOScheduler) 객체입니다. 이 객체는 하이퍼파라미터 탐색 알고리즘과 스케줄링을 제어합니다.
    • objective: 목표 함수(callable)입니다. 이 함수는 하이퍼파라미터 구성을 입력으로 받아 검증 오차를 반환하는 함수여야 합니다.
  3. self.save_hyperparameters(): 하이퍼파라미터를 저장하는 메서드입니다. 이 메서드를 호출하여 HPOTuner 클래스의 하이퍼파라미터를 저장합니다.
  4. self.incumbent, self.incumbent_error, self.incumbent_trajectory, self.cumulative_runtime, self.current_runtime, self.records: 하이퍼파라미터 탐색 결과를 저장하기 위한 인스턴스 변수들입니다. 이 변수들은 향후 결과 분석 및 시각화에 사용됩니다.
  5. def run(self, number_of_trials): 하이퍼파라미터 탐색을 실행하는 메서드입니다. 이 메서드는 number_of_trials 만큼의 하이퍼파라미터 탐색 시도를 수행합니다.
    • 먼저 현재 시간을 측정하여 시도의 시작 시간(start_time)을 저장합니다.
    • scheduler 객체를 사용하여 다음으로 시도할 하이퍼파라미터 구성(config)을 제안합니다.
    • objective 함수를 사용하여 제안된 하이퍼파라미터 구성에 대한 검증 오차(error)를 계산합니다.
    • 검증 오차를 float 형태로 변환하여 저장합니다.
    • scheduler 객체를 사용하여 하이퍼파라미터 탐색 알고리즘을 업데이트합니다.
    • 시도의 실행 시간(runtime)을 계산합니다.
    • bookkeeping 메서드를 호출하여 결과를 기록합니다.
    • 시도별로 제안된 하이퍼파라미터 구성, 검증 오차, 실행 시간을 출력합니다.

HPOTuner 클래스는 주어진 하이퍼파라미터 탐색 스케줄러와 목표 함수를 사용하여 하이퍼파라미터 탐색을 수행하고 결과를 기록하는 역할을 합니다. 탐색된 결과는 인스턴스 변수에 저장되어 이후 분석 및 시각화에 사용됩니다.

 

19.2.4. Bookkeeping the Performance of HPO Algorithms

 

With any HPO algorithm, we are mostly interested in the best performing configuration (called incumbent) and its validation error after a given wall-clock time. This is why we track runtime per iteration, which includes both the time to run an evaluation (call of objective) and the time to make a decision (call of scheduler.suggest). In the sequel, we will plot cumulative_runtime against incumbent_trajectory in order to visualize the any-time performance of the HPO algorithm defined in terms of scheduler (and searcher). This allows us to quantify not only how well the configuration found by an optimizer works, but also how quickly an optimizer is able to find it.

 

모든 HPO 알고리즘에서 우리는 가장 성능이 좋은 구성(현재라고 함)과 주어진 wall-clock time 이후의 유효성 검사 오류에 주로 관심이 있습니다. 이것이 바로 우리가 평가 실행 시간(목표 호출)과 결정을 내리는 시간(scheduler.suggest 호출)을 모두 포함하는 반복당 런타임을 추적하는 이유입니다. 후속편에서는 스케줄러(및 검색기) 측면에서 정의된 HPO 알고리즘의 언제든지 성능을 시각화하기 위해 incumbent_trajectory에 대해 cumulative_runtime을 플롯합니다. 이를 통해 우리는 옵티마이저가 찾은 구성이 얼마나 잘 작동하는지 뿐만 아니라 옵티마이저가 이를 얼마나 빨리 찾을 수 있는지를 정량화할 수 있습니다.

 

@d2l.add_to_class(HPOTuner)  #@save
def bookkeeping(self, config: dict, error: float, runtime: float):
    self.records.append({"config": config, "error": error, "runtime": runtime})
    # Check if the last hyperparameter configuration performs better
    # than the incumbent
    if self.incumbent is None or self.incumbent_error > error:
        self.incumbent = config
        self.incumbent_error = error
    # Add current best observed performance to the optimization trajectory
    self.incumbent_trajectory.append(self.incumbent_error)
    # Update runtime
    self.current_runtime += runtime
    self.cumulative_runtime.append(self.current_runtime)

위의 코드는 HPOTuner 클래스에 새로운 메서드인 bookkeeping을 추가하는 부분입니다. bookkeeping 메서드는 하이퍼파라미터 탐색 결과를 기록하고 현재까지의 최적 하이퍼파라미터 구성 및 검증 오차를 관리합니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. @d2l.add_to_class(HPOTuner): bookkeeping 메서드를 HPOTuner 클래스에 추가하는 데코레이터입니다. 이를 통해 bookkeeping 메서드가 HPOTuner 클래스의 일부로 추가됩니다.
  2. def bookkeeping(self, config: dict, error: float, runtime: float):: bookkeeping 메서드를 정의합니다. 이 메서드는 세 개의 매개변수를 입력으로 받습니다.
    • config: 현재 시도한 하이퍼파라미터 구성(configuration)을 나타내는 딕셔너리입니다.
    • error: 현재 시도한 하이퍼파라미터 구성에 대한 검증 오차를 나타내는 부동 소수점 숫자(float)입니다.
    • runtime: 현재 시도한 하이퍼파라미터 탐색 시도의 실행 시간을 나타내는 부동 소수점 숫자(float)입니다.
  3. self.records.append({"config": config, "error": error, "runtime": runtime}): 시도한 하이퍼파라미터 구성(config), 검증 오차(error), 실행 시간(runtime)을 딕셔너리 형태로 묶어 records 리스트에 추가합니다. 이를 통해 각 시도의 결과가 기록됩니다.
  4. if self.incumbent is None or self.incumbent_error > error:: 현재까지의 최적 하이퍼파라미터 구성(incumbent)이 없거나 현재 시도한 하이퍼파라미터 구성의 검증 오차가 현재까지의 최적 검증 오차(incumbent_error)보다 작을 경우, 새로운 최적 하이퍼파라미터 구성으로 업데이트합니다.
  5. self.incumbent_trajectory.append(self.incumbent_error): 최적 검증 오차를 최적화 경로(incumbent_trajectory)에 추가합니다. 이를 통해 최적 검증 오차의 변화를 추적할 수 있습니다.
  6. self.current_runtime += runtime: 현재 시도한 하이퍼파라미터 탐색 시도의 실행 시간을 누적 실행 시간에 추가합니다.
  7. self.cumulative_runtime.append(self.current_runtime): 누적 실행 시간을 cumulative_runtime 리스트에 추가합니다. 이를 통해 누적 실행 시간의 변화를 추적할 수 있습니다.

bookkeeping 메서드는 하이퍼파라미터 탐색 과정에서 발생한 결과를 기록하고 최적 하이퍼파라미터 구성 및 검증 오차를 관리하는 중요한 역할을 합니다. 이를 통해 하이퍼파라미터 탐색의 진행과 결과 분석을 용이하게 할 수 있습니다.

 

19.2.5. Example: Optimizing the Hyperparameters of a Convolutional Neural Network

 

We now use our new implementation of random search to optimize the batch size and learning rate of the LeNet convolutional neural network from Section 7.6. We being by defining the objective function, which will once more be validation error.

 

이제 우리는 섹션 7.6의 LeNet 컨벌루션 신경망의 배치 크기와 학습 속도를 최적화하기 위해 새로운 무작위 검색 구현을 사용합니다. 우리는 다시 한 번 검증 오류가 될 목적 함수를 정의하고 있습니다.

 

def hpo_objective_lenet(learning_rate, batch_size, max_epochs=10):  #@save
    model = d2l.LeNet(lr=learning_rate, num_classes=10)
    trainer = d2l.HPOTrainer(max_epochs=max_epochs, num_gpus=1)
    data = d2l.FashionMNIST(batch_size=batch_size)
    model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)
    trainer.fit(model=model, data=data)
    validation_error = trainer.validation_error()
    return validation_error

위의 코드는 하이퍼파라미터 튜닝을 위한 목표 함수인 hpo_objective_lenet 함수를 정의하는 부분입니다. 이 함수는 LeNet 모델을 사용하여 Fashion MNIST 데이터셋에 대한 검증 오차를 반환하는 역할을 합니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. def hpo_objective_lenet(learning_rate, batch_size, max_epochs=10):: hpo_objective_lenet 함수를 정의합니다. 이 함수는 세 개의 하이퍼파라미터와 하나의 선택적 매개변수를 입력으로 받습니다.
    • learning_rate: 학습률을 나타내는 부동 소수점 숫자(float)입니다.
    • batch_size: 미니배치 크기를 나타내는 정수(int)입니다.
    • max_epochs: 최대 에포크 수를 나타내는 정수(int)입니다. 기본값은 10입니다.
  2. model = d2l.LeNet(lr=learning_rate, num_classes=10): LeNet 아키텍처를 사용하여 모델을 초기화합니다. 이때 학습률과 클래스 수를 매개변수로 설정합니다.
  3. trainer = d2l.HPOTrainer(max_epochs=max_epochs, num_gpus=1): 하이퍼파라미터 튜닝을 위한 트레이너 객체를 생성합니다. 최대 에포크 수와 GPU 수를 설정합니다.
  4. data = d2l.FashionMNIST(batch_size=batch_size): Fashion MNIST 데이터셋을 불러와서 데이터 객체를 생성합니다. 이때 미니배치 크기를 설정합니다.
  5. model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn): 모델의 가중치를 초기화합니다. 이때 데이터로부터 첫 번째 미니배치를 추출하여 초기화에 사용합니다.
  6. trainer.fit(model=model, data=data): 트레이너를 사용하여 모델을 학습시킵니다. 모델과 데이터를 입력으로 제공합니다.
  7. validation_error = trainer.validation_error(): 학습된 모델을 검증 데이터에 대해 평가하여 검증 오차를 계산합니다.
  8. return validation_error: 검증 오차를 반환합니다.

이 함수는 주어진 하이퍼파라미터 구성(learning_rate, batch_size, max_epochs)으로 LeNet 모델을 학습하고 검증 오차를 반환합니다. 이 함수는 하이퍼파라미터 탐색에서 목표로 하는 검증 오차를 최소화하기 위해 호출됩니다.

 

We also need to define the configuration space. Moreover, the first configuration to be evaluated is the default setting used in Section 7.6.

 

또한 구성 공간을 정의해야 합니다. 또한 평가할 첫 번째 구성은 섹션 7.6에서 사용된 기본 설정입니다.

 

config_space = {
    "learning_rate": stats.loguniform(1e-2, 1),
    "batch_size": stats.randint(32, 256),
}
initial_config = {
    "learning_rate": 0.1,
    "batch_size": 128,
}

위의 코드는 하이퍼파라미터 탐색을 위한 하이퍼파라미터 공간(config_space)과 초기 하이퍼파라미터 구성(initial_config)을 정의하는 부분입니다. 각 부분에 대한 설명은 다음과 같습니다:

  1. config_space: 하이퍼파라미터 공간을 정의하는 딕셔너리입니다. 이 딕셔너리에는 탐색할 하이퍼파라미터의 이름과 각 하이퍼파라미터에 대한 확률 분포가 설정됩니다.
    • "learning_rate": 학습률을 나타내는 하이퍼파라미터입니다. 이 학습률은 로그 균등 분포(stats.loguniform)를 사용하여 1e-2에서 1 사이의 값 중에서 무작위로 선택됩니다.
    • "batch_size": 미니배치 크기를 나타내는 하이퍼파라미터입니다. 이 미니배치 크기는 균등 분포(stats.randint)를 사용하여 32에서 256 사이의 정수 중에서 무작위로 선택됩니다.
  2. initial_config: 초기 하이퍼파라미터 구성을 정의하는 딕셔너리입니다. 이 딕셔너리에는 하이퍼파라미터의 이름과 초기값이 설정됩니다.
    • "learning_rate": 학습률의 초기값을 0.1로 설정합니다.
    • "batch_size": 미니배치 크기의 초기값을 128로 설정합니다.

이렇게 정의된 config_space와 initial_config를 사용하여 하이퍼파라미터 탐색을 수행할 때, 하이퍼파라미터 탐색 공간은 learning_rate와 batch_size 두 가지 하이퍼파라미터를 다루며, 초기 탐색은 initial_config에서 정의한 값으로 시작합니다. 이후 하이퍼파라미터 탐색 알고리즘이 지정된 공간에서 하이퍼파라미터를 무작위로 탐색하고 목표 함수를 최적화하려고 시도합니다.

 

Now we can start our random search:

 

이제 무작위 검색을 시작할 수 있습니다.

 

searcher = RandomSearcher(config_space, initial_config=initial_config)
scheduler = BasicScheduler(searcher=searcher)
tuner = HPOTuner(scheduler=scheduler, objective=hpo_objective_lenet)
tuner.run(number_of_trials=5)

위의 코드는 하이퍼파라미터 튜닝 프로세스를 설정하고 실행하는 부분입니다. 이 코드는 다음과 같은 주요 단계로 구성됩니다:

  1. searcher = RandomSearcher(config_space, initial_config=initial_config): RandomSearcher 클래스를 사용하여 하이퍼파라미터 탐색기(searcher)를 생성합니다. 이 탐색기는 정의한 하이퍼파라미터 공간(config_space)에서 무작위로 하이퍼파라미터를 샘플링하며, 초기 하이퍼파라미터 구성(initial_config)은 최초 탐색 시도에서 사용됩니다.
  2. scheduler = BasicScheduler(searcher=searcher): BasicScheduler 클래스를 사용하여 스케줄러(scheduler)를 생성합니다. 이 스케줄러는 하이퍼파라미터 탐색기(searcher)를 기반으로 하이퍼파라미터 탐색을 제어하며, 다음에 시도할 하이퍼파라미터 구성을 추천합니다.
  3. tuner = HPOTuner(scheduler=scheduler, objective=hpo_objective_lenet): HPOTuner 클래스를 사용하여 하이퍼파라미터 튜너(tuner)를 생성합니다. 이 튜너는 스케줄러와 목표 함수(objective)를 입력으로 받습니다. 목표 함수는 하이퍼파라미터 탐색 시 목표로 하는 평가 지표(여기서는 검증 오차)를 최소화하기 위해 호출됩니다.
  4. tuner.run(number_of_trials=5): 하이퍼파라미터 탐색을 실행합니다. number_of_trials 매개변수에 지정된 횟수(여기서는 5번)만큼 하이퍼파라미터 탐색을 반복하며, 각 시도에서 목표 함수를 호출하여 검증 오차를 최소화하는 최적의 하이퍼파라미터를 찾습니다.

이렇게 설정된 하이퍼파라미터 탐색 프로세스를 실행하면, 다양한 하이퍼파라미터 조합을 시도하여 모델의 검증 오차를 최적화하려고 노력합니다. 최적의 하이퍼파라미터 구성과 검증 오차의 기록은 tuner 객체에 저장되며, 최종적으로 가장 좋은 하이퍼파라미터 구성을 찾게 됩니다.

 error = 0.9000097513198853, runtime = 62.85189199447632

 

==> 여러 구성으로 여러번 run 하기 때문에 시간이 많이 걸림. 아래는 CoLab에서 돌린 결과. 11분 걸

Below we plot the optimization trajectory of the incumbent to get the any-time performance of random search:

 

아래에서는 무작위 검색의 언제든지 성능을 얻기 위해 기존 기업의 최적화 궤적을 그립니다.

 

board = d2l.ProgressBoard(xlabel="time", ylabel="error")
for time_stamp, error in zip(
    tuner.cumulative_runtime, tuner.incumbent_trajectory
):
    board.draw(time_stamp, error, "random search", every_n=1)

위의 코드는 하이퍼파라미터 탐색 과정에서 검증 오차의 변화를 시각화하는 부분입니다. 코드는 다음과 같이 동작합니다:

  1. board = d2l.ProgressBoard(xlabel="time", ylabel="error"): d2l.ProgressBoard 객체를 생성하여 그래프를 초기화합니다. 이 그래프는 시간(time)에 따른 검증 오차(error)의 변화를 시각화합니다. x축은 시간을 나타내고, y축은 검증 오차를 나타냅니다.
  2. for time_stamp, error in zip(tuner.cumulative_runtime, tuner.incumbent_trajectory):: 하이퍼파라미터 튜닝 과정에서 누적된 시간(time_stamp)과 현재까지의 최적 검증 오차(error)를 반복하면서 그래프를 그립니다.
  3. board.draw(time_stamp, error, "random search", every_n=1): 그래프에 데이터를 추가합니다. 시간(time_stamp)과 검증 오차(error)를 전달하고, "random search"라는 레이블을 지정합니다. every_n=1은 모든 데이터 포인트를 표시하도록 지정하는데, 이 값이 높으면 그래프에 표시되는 데이터 포인트의 수가 감소합니다.

이 코드는 하이퍼파라미터 탐색 과정 중에 검증 오차의 변화를 실시간으로 시각화하여 어떻게 하이퍼파라미터 탐색이 진행되고 있는지를 모니터링할 수 있게 합니다. 그래프는 시간에 따른 검증 오차의 추이를 보여주며, 최적의 하이퍼파라미터 구성을 찾는 과정을 시각적으로 이해하는 데 도움을 줍니다.

 

19.2.6. Comparing HPO Algorithms

Just as with training algorithms or model architectures, it is important to understand how to best compare different HPO algorithms. Each HPO run depends on two major sources of randomness: the random effects of the training process, such as random weight initialization or mini-batch ordering, and the intrinsic randomness of the HPO algorithm itself, such as the random sampling of random search. Hence, when comparing different algorithms, it is crucial to run each experiment several times and report statistics, such as mean or median, across a population of multiple repetitions of an algorithm based on different seeds of the random number generator.

 

학습 알고리즘이나 모델 아키텍처와 마찬가지로 다양한 HPO 알고리즘을 가장 잘 비교하는 방법을 이해하는 것이 중요합니다. 각 HPO 실행은 무작위성의 두 가지 주요 소스, 즉 무작위 가중치 초기화 또는 미니 배치 순서 지정과 같은 훈련 프로세스의 무작위 효과와 무작위 검색의 무작위 샘플링과 같은 HPO 알고리즘 자체의 본질적인 무작위성에 따라 달라집니다. 따라서 다양한 알고리즘을 비교할 때 각 실험을 여러 번 실행하고 난수 생성기의 다양한 시드를 기반으로 하는 알고리즘의 여러 반복 모집단에 대한 평균 또는 중앙값과 같은 통계를 보고하는 것이 중요합니다.

 

To illustrate this, we compare random search (see Section 19.1.2) and Bayesian optimization (Snoek et al., 2012) on tuning the hyperparameters of a feed-forward neural network. Each algorithm was evaluated 50 times with a different random seed. The solid line indicates the average performance of the incumbent across these 50 repetitions and the dashed line the standard deviation. We can see that random search and Bayesian optimization perform roughly the same up to ~1000 seconds, but Bayesian optimization can make use of the past observation to identify better configurations and thus quickly outperforms random search afterwards.

 

이를 설명하기 위해 피드포워드 신경망의 하이퍼파라미터 조정에 대한 무작위 검색(19.1.2절 참조)과 베이지안 최적화(Snoek et al., 2012)를 비교합니다. 각 알고리즘은 서로 다른 무작위 시드를 사용하여 50회 평가되었습니다. 실선은 50회 반복에 걸쳐 재직자의 평균 성과를 나타내고 점선은 표준 편차를 나타냅니다. 무작위 검색과 베이지안 최적화는 최대 1000초까지 거의 동일하게 수행되지만 베이지안 최적화는 과거 관찰을 활용하여 더 나은 구성을 식별할 수 있으므로 나중에 무작위 검색보다 빠르게 성능이 향상된다는 것을 알 수 있습니다.

 

Fig. 19.2.1&nbsp; Example any-time performance plot to compare two algorithms A and B.

 

19.2.7. Summary

This section laid out a simple, yet flexible interface to implement various HPO algorithms that we will look at in this chapter. Similar interfaces can be found in popular open-source HPO frameworks. We also looked at how we can compare HPO algorithms, and potential pitfall one needs to be aware.

 

이 섹션에서는 이 장에서 살펴볼 다양한 HPO 알고리즘을 구현하기 위한 간단하면서도 유연한 인터페이스를 제시했습니다. 인기 있는 오픈 소스 HPO 프레임워크에서도 유사한 인터페이스를 찾을 수 있습니다. 또한 HPO 알고리즘을 비교할 수 있는 방법과 알아야 할 잠재적인 함정도 살펴보았습니다.

 

19.2.8. Exercises

  1. The goal of this exercise is to implement the objective function for a slightly more challenging HPO problem, and to run more realistic experiments. We will use the two hidden layer MLP DropoutMLP implemented in Section 5.6.
    1. Code up the objective function, which should depend on all hyperparameters of the model and batch_size. Use max_epochs=50. GPUs do not help here, so num_gpus=0. Hint: Modify hpo_objective_lenet.
    2. Choose a sensible search space, where num_hiddens_1, num_hiddens_2 are integers in [8,1024], and dropout values lie in [0,0.95], while batch_size lies in [16,384]. Provide code for config_space, using sensible distributions from scipy.stats.
    3. Run random search on this example with number_of_trials=20 and plot the results. Make sure to first evaluate the default configuration of Section 5.6, which is initial_config = {'num_hiddens_1': 256, 'num_hiddens_2': 256, 'dropout_1': 0.5, 'dropout_2': 0.5, 'lr': 0.1, 'batch_size': 256}.
  2. In this exercise, you will implement a new searcher (subclass of HPOSearcher) which makes decisions based on past data. It depends on parameters probab_local, num_init_random. Its sample_configuration method works as follows. For the first num_init_random calls, do the same as RandomSearcher.sample_configuration. Otherwise, with probability 1 - probab_local, do the same as RandomSearcher.sample_configuration. Otherwise, pick the configuration which attained the smallest validation error so far, select one of its hyperparameters at random, and sample its value randomly like in RandomSearcher.sample_configuration, but leave all other values the same. Return this configuration, which is identical to the best configuration so far, except in this one hyperparameter.
    1. Code up this new LocalSearcher. Hint: Your searcher requires config_space as argument at construction. Feel free to use a member of type RandomSearcher. You will also have to implement the update method.
    2. Re-run the experiment from the previous exercise, but using your new searcher instead of RandomSearcher. Experiment with different values for probab_local, num_init_random. However, note that a proper comparison between different HPO methods requires repeating experiments several times, and ideally considering a number of benchmark tasks.
반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/hyperopt-intro.html

 

19.1. What Is Hyperparameter Optimization? — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19.1. What Is Hyperparameter Optimization?

 

As we have seen in the previous chapters, deep neural networks come with a large number of parameters or weights that are learned during training. On top of these, every neural network has additional hyperparameters that need to be configured by the user. For example, to ensure that stochastic gradient descent converges to a local optimum of the training loss (see Section 12), we have to adjust the learning rate and batch size. To avoid overfitting on training datasets, we might have to set regularization parameters, such as weight decay (see Section 3.7) or dropout (see Section 5.6). We can define the capacity and inductive bias of the model by setting the number of layers and number of units or filters per layer (i.e., the effective number of weights).

 

이전 장에서 살펴본 것처럼 심층 신경망에는 훈련 중에 학습되는 수많은 매개변수 또는 가중치가 포함됩니다. 게다가 모든 신경망에는 사용자가 구성해야 하는 추가 하이퍼파라미터가 있습니다. 예를 들어 확률적 경사하강법이 훈련 손실의 국소 최적값으로 수렴되도록 하려면(섹션 12 참조) 학습 속도와 배치 크기를 조정해야 합니다. 훈련 데이터세트에 대한 과적합을 방지하려면 가중치 감소(섹션 3.7 참조) 또는 드롭아웃(섹션 5.6 참조)과 같은 정규화 매개변수를 설정해야 할 수도 있습니다. 레이어 수와 레이어당 단위 또는 필터 수(즉, 유효 가중치 수)를 설정하여 모델의 용량과 유도 편향을 정의할 수 있습니다.

 

Unfortunately, we cannot simply adjust these hyperparameters by minimizing the training loss, because this would lead to overfitting on the training data. For example, setting regularization parameters, such as dropout or weight decay to zero leads to a small training loss, but might hurt the generalization performance.

 

불행하게도 훈련 손실을 최소화함으로써 이러한 하이퍼파라미터를 간단히 조정할 수는 없습니다. 왜냐하면 그렇게 하면 훈련 데이터에 과적합이 발생할 수 있기 때문입니다. 예를 들어, 드롭아웃이나 가중치 감소와 같은 정규화 매개변수를 0으로 설정하면 훈련 손실이 약간 발생하지만 일반화 성능이 저하될 수 있습니다.

 

Fig. 19.1.1&nbsp; Typical workflow in machine learning that consists of training the model multiple times with different hyperparameters.

 

Without a different form of automation, hyperparameters have to be set manually in a trial-and-error fashion, in what amounts to a time-consuming and difficult part of machine learning workflows. For example, consider training a ResNet (see Section 8.6) on CIFAR-10, which requires more than 2 hours on an Amazon Elastic Cloud Compute (EC2) g4dn.xlarge instance. Even just trying ten hyperparameter configurations in sequence, this would already take us roughly one day. To make matters worse, hyperparameters are usually not directly transferable across architectures and datasets (Bardenet et al., 2013, Feurer et al., 2022, Wistuba et al., 2018), and need to be re-optimized for every new task. Also, for most hyperparameters, there are no rule-of-thumbs, and expert knowledge is required to find sensible values.

 

다른 형태의 자동화가 없으면 하이퍼파라미터는 시행착오 방식으로 수동으로 설정해야 하므로 기계 학습 워크플로에서 시간이 많이 걸리고 어려운 부분이 됩니다. 예를 들어, Amazon Elastic Cloud Compute(EC2) g4dn.xlarge 인스턴스에서 2시간 이상 필요한 CIFAR-10의 ResNet(섹션 8.6 참조) 교육을 고려해 보세요. 10개의 하이퍼파라미터 구성을 순차적으로 시도하는 것만으로도 이미 대략 하루가 걸릴 것입니다. 설상가상으로 하이퍼파라미터는 일반적으로 아키텍처와 데이터 세트 간에 직접 전송할 수 없으며(Bardenet et al., 2013, Feurer et al., 2022, Wistuba et al., 2018) 모든 새로운 작업에 대해 다시 최적화해야 합니다. 또한 대부분의 하이퍼파라미터에는 경험 법칙이 없으며, 합리적인 값을 찾기 위해서는 전문 지식이 필요합니다.

 

Hyperparameter optimization (HPO) algorithms are designed to tackle this problem in a principled and automated fashion (Feurer and Hutter, 2018), by framing it as a global optimization problem. The default objective is the error on a hold-out validation dataset, but could in principle be any other business metric. It can be combined with or constrained by secondary objectives, such as training time, inference time, or model complexity.

 

하이퍼파라미터 최적화(HPO) 알고리즘은 이 문제를 전역 최적화 문제로 구성하여 원칙적이고 자동화된 방식으로(Feurer and Hutter, 2018) 해결하도록 설계되었습니다. 기본 목표는 홀드아웃 검증 데이터 세트의 오류이지만 원칙적으로 다른 비즈니스 지표일 수도 있습니다. 이는 훈련 시간, 추론 시간 또는 모델 복잡성과 같은 2차 목표와 결합되거나 제한될 수 있습니다.

 

Recently, hyperparameter optimization has been extended to neural architecture search (NAS) (Elsken et al., 2018, Wistuba et al., 2019), where the goal is to find entirely new neural network architectures. Compared to classical HPO, NAS is even more expensive in terms of computation and requires additional efforts to remain feasible in practice. Both, HPO and NAS can be considered as sub-fields of AutoML (Hutter et al., 2019), which aims to automate the entire ML pipeline.

 

최근 하이퍼파라미터 최적화는 완전히 새로운 신경망 아키텍처를 찾는 것이 목표인 신경 아키텍처 검색(NAS)(Elsken et al., 2018, Wistuba et al., 2019)으로 확장되었습니다. 기존 HPO에 비해 NAS는 계산 측면에서 훨씬 더 비싸며 실제로 실행 가능성을 유지하려면 추가 노력이 필요합니다. HPO와 NAS는 모두 전체 ML 파이프라인 자동화를 목표로 하는 AutoML(Hutter et al., 2019)의 하위 분야로 간주될 수 있습니다.

 

In this section we will introduce HPO and show how we can automatically find the best hyperparameters of the logistic regression example introduced in Section 4.5.

 

이 섹션에서는 HPO를 소개하고 섹션 4.5에 소개된 로지스틱 회귀 예제의 최상의 하이퍼파라미터를 자동으로 찾는 방법을 보여줍니다.

 

19.1.1. The Optimization Problem

We will start with a simple toy problem: searching for the learning rate of the multi-class logistic regression model SoftmaxRegression from Section 4.5 to minimize the validation error on the Fashion MNIST dataset. While other hyperparameters like batch size or number of epochs are also worth tuning, we focus on learning rate alone for simplicity.

 

간단한 장난감 문제부터 시작하겠습니다. Fashion MNIST 데이터세트의 검증 오류를 최소화하기 위해 섹션 4.5에서 다중 클래스 로지스틱 회귀 모델 SoftmaxRegression의 학습률을 검색하는 것입니다. 배치 크기나 에포크 수와 같은 다른 하이퍼파라미터도 조정할 가치가 있지만 단순화를 위해 학습 속도에만 중점을 둡니다.

 

import numpy as np
import torch
from scipy import stats
from torch import nn
from d2l import torch as d2l

 

Before we can run HPO, we first need to define two ingredients: the objective function and the configuration space.

 

HPO를 실행하기 전에 먼저 목적 함수와 구성 공간이라는 두 가지 구성 요소를 정의해야 합니다.

 

19.1.1.1. The Objective Function

The performance of a learning algorithm can be seen as a function f:X→ that maps from the hyperparameter space x∈D to the validation loss. For every evaluation of f(x), we have to train and validate our machine learning model, which can be time and compute intensive in the case of deep neural networks trained on large datasets. Given our criterion f(x) our goal is to find x⋆∈argminx∈Xf(x).

 

학습 알고리즘의 성능은 하이퍼파라미터 공간 x∈D에서 검증 손실로 매핑되는 함수 f:X→ℝ로 볼 수 있습니다. f(x)를 평가할 때마다 기계 학습 모델을 훈련하고 검증해야 하는데, 이는 대규모 데이터 세트에 대해 훈련된 심층 신경망의 경우 시간과 계산 집약적일 수 있습니다. 기준 f(x)가 주어지면 우리의 목표는 x⋆∈argminx∈Xf(x)를 찾는 것입니다.

 

There is no simple way to compute gradients of f with respect to x, because it would require to propagate the gradient through the entire training process. While there is recent work (Franceschi et al., 2017, Maclaurin et al., 2015) to drive HPO by approximate “hypergradients”, none of the existing approaches are competitive with the state-of-the-art yet, and we will not discuss them here. Furthermore, the computational burden of evaluating f requires HPO algorithms to approach the global optimum with as few samples as possible.

 

x에 대한 f의 기울기를 계산하는 간단한 방법은 없습니다. 왜냐하면 전체 훈련 과정을 통해 기울기를 전파해야 하기 때문입니다. 대략적인 "hypergradients"를 통해 HPO를 구동하는 최근 연구(Franceschi et al., 2017, Maclaurin et al., 2015)가 있지만 기존 접근 방식 중 어느 것도 아직 최첨단 기술과 경쟁할 수 없습니다. 여기서는 논의하지 마세요. 더욱이, f를 평가하는 계산 부담으로 인해 HPO 알고리즘은 가능한 적은 샘플을 사용하여 전역 최적에 접근해야 합니다.

 

The training of neural networks is stochastic (e.g., weights are randomly initialized, mini-batches are randomly sampled), so that our observations will be noisy: y∼f(x)+ϵ, where we usually assume that the ϵ∼N(0,σ) observation noise is Gaussian distributed.

 

신경망의 훈련은 확률론적입니다(예: 가중치는 무작위로 초기화되고, 미니 배치는 무작위로 샘플링됩니다). 따라서 우리의 관측값은 시끄러울 것입니다: y∼f(x)+ϵ, 여기서 우리는 일반적으로 ϵ∼N( 0,σ) 관측 잡음은 가우스 분포입니다.

 

Faced with all these challenges, we usually try to identify a small set of well performing hyperparameter configurations quickly, instead of hitting the global optima exactly. However, due to large computational demands of most neural networks models, even this can take days or weeks of compute. We will explore in Section 19.4 how we can speed-up the optimization process by either distributing the search or using cheaper-to-evaluate approximations of the objective function.

 

이러한 모든 문제에 직면했을 때 우리는 일반적으로 전체 최적 상태에 정확히 도달하는 대신 성능이 좋은 소수의 하이퍼파라미터 구성 세트를 신속하게 식별하려고 노력합니다. 그러나 대부분의 신경망 모델의 컴퓨팅 요구량이 많기 때문에 이 작업에도 며칠 또는 몇 주가 걸릴 수 있습니다. 우리는 섹션 19.4에서 검색을 분산하거나 목적 함수의 평가 비용이 더 저렴한 근사치를 사용하여 최적화 프로세스의 속도를 높일 수 있는 방법을 탐색할 것입니다.

 

We begin with a method for computing the validation error of a model.

 

모델의 검증 오류를 계산하는 방법부터 시작합니다.

 

class HPOTrainer(d2l.Trainer):  #@save
    def validation_error(self):
        self.model.eval()
        accuracy = 0
        val_batch_idx = 0
        for batch in self.val_dataloader:
            with torch.no_grad():
                x, y = self.prepare_batch(batch)
                y_hat = self.model(x)
                accuracy += self.model.accuracy(y_hat, y)
            val_batch_idx += 1
        return 1 -  accuracy / val_batch_idx

위의 코드는 하이퍼파라미터 최적화(Hyperparameter Optimization, HPO)를 수행하는 데 사용되는 HPOTrainer 클래스를 정의하는 파트입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. class HPOTrainer(d2l.Trainer):: HPOTrainer 클래스를 정의합니다. 이 클래스는 d2l.Trainer 클래스를 상속받아 하이퍼파라미터 최적화를 위한 훈련 기능을 추가합니다.
  2. def validation_error(self):: 검증 데이터셋을 사용하여 모델의 성능을 평가하고 검증 오차를 계산하는 메서드를 정의합니다.
  3. self.model.eval(): 모델을 평가 모드로 설정합니다. 이 모드에서는 모델이 평가되기만 하고 그라디언트 계산이 비활성화됩니다.
  4. accuracy = 0: 정확도를 초기화합니다. 이 변수는 모든 검증 배치의 정확도를 누적하기 위해 사용됩니다.
  5. val_batch_idx = 0: 검증 배치의 인덱스를 초기화합니다.
  6. for batch in self.val_dataloader:: 검증 데이터셋의 배치들을 반복합니다. self.val_dataloader는 검증 데이터셋을 로드하는 데 사용되는 데이터 로더입니다.
  7. with torch.no_grad():: 그라디언트 계산을 비활성화하는 torch.no_grad() 컨텍스트를 생성합니다. 이 컨텍스트 내에서는 모델이 평가될 때 그라디언트가 계산되지 않습니다.
  8. x, y = self.prepare_batch(batch): 현재 배치를 준비하고 입력 데이터 x와 레이블 y를 가져옵니다.
  9. y_hat = self.model(x): 모델을 사용하여 입력 데이터에 대한 예측을 계산합니다.
  10. accuracy += self.model.accuracy(y_hat, y): 현재 배치의 정확도를 계산하여 누적합니다. self.model.accuracy()는 모델의 예측과 실제 레이블을 사용하여 정확도를 계산하는 메서드입니다.
  11. val_batch_idx += 1: 검증 배치 인덱스를 증가시킵니다.
  12. return 1 - accuracy / val_batch_idx: 검증 데이터셋 전체에 대한 정확도를 계산하고, 1에서 빼서 검증 오차를 계산합니다. 이 오차는 하이퍼파라미터 최적화 과정에서 사용될 수 있습니다.

이렇게 정의된 HPOTrainer 클래스는 모델의 성능을 검증 데이터셋을 사용하여 평가하고 검증 오차를 계산하는 기능을 제공합니다. 이 클래스는 하이퍼파라미터 최적화의 일부로 모델의 성능을 측정하는 데 유용하게 사용될 수 있습니다.

 

We optimize validation error with respect to the hyperparameter configuration config, consisting of the learning_rate. For each evaluation, we train our model for max_epochs epochs, then compute and return its validation error:

 

learning_rate로 구성된 하이퍼파라미터 구성 config에 대한 검증 오류를 최적화합니다. 각 평가에 대해 max_epochs epoch에 대한 모델을 훈련한 다음 검증 오류를 계산하고 반환합니다.

 

def hpo_objective_softmax_classification(config, max_epochs=8):
    learning_rate = config["learning_rate"]
    trainer = d2l.HPOTrainer(max_epochs=max_epochs)
    data = d2l.FashionMNIST(batch_size=16)
    model = d2l.SoftmaxRegression(num_outputs=10, lr=learning_rate)
    trainer.fit(model=model, data=data)
    return trainer.validation_error().detach().numpy()

위의 코드는 하이퍼파라미터 최적화(Hyperparameter Optimization, HPO)를 수행하기 위한 목적 함수인 hpo_objective_softmax_classification를 정의하는 파트입니다. 이 함수는 주어진 하이퍼파라미터 구성을 사용하여 소프트맥스 분류 모델을 훈련하고 검증 오차를 반환합니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. def hpo_objective_softmax_classification(config, max_epochs=8):: 하이퍼파라미터 최적화를 위한 목적 함수를 정의합니다. 함수는 두 개의 매개변수를 입력으로 받습니다. config는 하이퍼파라미터 구성을 나타내며, max_epochs는 모델의 최대 훈련 에폭을 지정하는 매개변수로 기본값은 8입니다.
  2. learning_rate = config["learning_rate"]: 주어진 하이퍼파라미터 구성에서 학습률(learning rate)을 가져옵니다. 이는 하이퍼파라미터 최적화의 일부로 조정될 값입니다.
  3. trainer = d2l.HPOTrainer(max_epochs=max_epochs): 하이퍼파라미터 최적화를 위한 d2l.HPOTrainer 객체를 생성합니다. max_epochs는 모델의 최대 훈련 에폭을 설정합니다.
  4. data = d2l.FashionMNIST(batch_size=16): Fashion MNIST 데이터셋을 로드하고 데이터 로더를 생성합니다. 이 데이터는 모델을 훈련하기 위한 학습 및 검증 데이터로 사용됩니다. batch_size는 한 번에 처리할 데이터의 배치 크기를 설정합니다.
  5. model = d2l.SoftmaxRegression(num_outputs=10, lr=learning_rate): 소프트맥스 회귀(Softmax Regression) 모델을 생성합니다. num_outputs는 출력 클래스(레이블)의 수를 설정하며, lr은 학습률을 설정합니다.
  6. trainer.fit(model=model, data=data): trainer를 사용하여 모델을 학습합니다. 모델과 데이터를 전달하고, 지정된 에폭 수(max_epochs)만큼 훈련을 수행합니다.
  7. return trainer.validation_error().detach().numpy(): 훈련된 모델의 검증 오차를 계산하고 반환합니다. 검증 오차는 trainer.validation_error()를 통해 얻으며, NumPy 배열로 변환하여 반환합니다.

이 함수는 주어진 하이퍼파라미터 구성을 사용하여 모델을 훈련하고 검증 오차를 반환하므로, 하이퍼파라미터 최적화 알고리즘(예: Bayesian Optimization)에 의해 최적의 하이퍼파라미터 구성을 찾는 데 사용됩니다.

 

19.1.1.2. The Configuration Space

Along with the objective function f(x), we also need to define the feasible set x∈X to optimize over, known as configuration space or search space. For our logistic regression example, we will use:

 

목적 함수 objective function f(x)와 함께 구성 공간 configuration space 또는 검색 공간 search space 으로 알려진 최적화를 위한 실행 가능한 집합 x∈X도 정의해야 합니다. 로지스틱 회귀 예제에서는 다음을 사용합니다.

config_space = {"learning_rate": stats.loguniform(1e-4, 1)}

위의 코드는 하이퍼파라미터 최적화를 위한 하이퍼파라미터 공간을 정의하는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. config_space = {"learning_rate": stats.loguniform(1e-4, 1)}: config_space라는 딕셔너리를 정의합니다. 이 딕셔너리는 하이퍼파라미터 공간을 설명하는 엔트리(항목)를 포함합니다.
  2. "learning_rate": 이 항목은 하이퍼파라미터의 이름인 "learning_rate"를 나타냅니다. 이 이름은 해당 하이퍼파라미터를 식별하는 데 사용됩니다.
  3. stats.loguniform(1e-4, 1): "learning_rate" 하이퍼파라미터의 값 범위를 지정합니다. stats.loguniform은 로그 스케일로 분포하는 값을 생성하는 함수입니다. 여기서는 1e-4에서부터 1까지의 로그 스케일 분포를 정의하고 있으므로, "learning_rate" 하이퍼파라미터의 값은 1e-4에서부터 1 사이의 값 중 하나가 될 것입니다.

이 코드는 하이퍼파라미터 최적화 과정에서 어떤 하이퍼파라미터를 탐색할 것인지를 정의하는데 사용됩니다. 여기서는 "learning_rate"라는 하이퍼파라미터의 값 범위를 로그 스케일로 지정하고 있으므로, 최적의 학습률을 찾기 위해 로그 스케일로 값을 탐색할 수 있습니다.

 

Here we use the use the loguniform object from SciPy, which represents a uniform distribution between -4 and -1 in the logarithmic space. This object allows us to sample random variables from this distribution.

 

여기서는 로그 공간에서 -4와 -1 사이의 균일 분포를 나타내는 SciPy의 loguniform 객체를 사용합니다. 이 객체를 사용하면 이 분포에서 무작위 변수를 샘플링할 수 있습니다.

 

Each hyperparameter has a data type, such as float for learning_rate, as well as a closed bounded range (i.e., lower and upper bounds). We usually assign a prior distribution (e.g, uniform or log-uniform) to each hyperparameter to sample from. Some positive parameters, such as learning_rate, are best represented on a logarithmic scale as optimal values can differ by several orders of magnitude, while others, such as momentum, come with linear scale.

 

각 하이퍼파라미터에는 learning_rate의 float와 같은 데이터 유형과 닫힌 경계 범위(예: 하한 및 상한)가 있습니다. 우리는 일반적으로 샘플링할 각 하이퍼파라미터에 사전 분포(예: 균일 또는 로그 균일)를 할당합니다. learning_rate와 같은 일부 양수 매개변수는 최적의 값이 여러 차수만큼 다를 수 있으므로 로그 척도로 가장 잘 표현되는 반면, 모멘텀과 같은 다른 매개변수는 선형 척도로 제공됩니다.

 

Below we show a simple example of a configuration space consisting of typical hyperparameters of a multi-layer perceptron including their type and standard ranges.

 

아래에서는 유형 및 표준 범위를 포함하여 다층 퍼셉트론의 일반적인 하이퍼 매개변수로 구성된 구성 공간의 간단한 예를 보여줍니다.

 

: Example configuration space of multi-layer perceptron

 

: 다층 퍼셉트론의 구성 공간 예시

 

Table 19.1.1 label:tab_example_configspaceNameTypeHyperparameter Rangeslog-scale

learning rate float :math:` [10^{-6},10^{-1}]` yes
batch size integer [8,256] yes
momentum float [0,0.99] no
activation function categorical :mat h:{textrm{tanh} , textrm{relu}}
  •  
number of units integer [32,1024] yes
number of layers integer [1,6] no

In general, the structure of the configuration space X can be complex and it can be quite different from ℝ**d. In practice, some hyperparameters may depend on the value of others. For example, assume we try to tune the number of layers for a multi-layer perceptron, and for each layer the number of units. The number of units of the l-th layer is relevant only if the network has at least l+1 layers. These advanced HPO problems are beyond the scope of this chapter. We refer the interested reader to (Baptista and Poloczek, 2018, Hutter et al., 2011, Jenatton et al., 2017).

 

일반적으로 구성 공간 X의 구조는 복잡할 수 있으며 ℝ**d와 상당히 다를 수 있습니다. 실제로 일부 하이퍼파라미터는 다른 하이퍼파라미터의 값에 따라 달라질 수 있습니다. 예를 들어, 다층 퍼셉트론의 레이어 수와 각 레이어의 단위 수를 조정하려고 한다고 가정합니다. l번째 레이어의 단위 수는 네트워크에 l+1개 이상의 레이어가 있는 경우에만 관련이 있습니다. 이러한 고급 HPO 문제는 이 장의 범위를 벗어납니다. 관심 있는 독자에게는 (Baptista and Poloczek, 2018, Hutter et al., 2011, Jenatton et al., 2017)을 참조하시기 바랍니다.

 

The configuration space plays an important role for hyperparameter optimization, since no algorithms can find something that is not included in the configuration space. On the other hand, if the ranges are too large, the computation budget to find well performing configurations might become infeasible.

 

구성 공간은 구성 공간에 포함되지 않은 것을 어떤 알고리즘도 찾을 수 없기 때문에 하이퍼파라미터 최적화에 중요한 역할을 합니다. 반면에 범위가 너무 크면 성능이 좋은 구성을 찾기 위한 계산 예산이 실행 불가능해질 수 있습니다.

 

19.1.2. Random Search

Random search is the first hyperparameter optimization algorithm we will consider. The main idea of random search is to independently sample from the configuration space until a predefined budget (e.g maximum number of iterations) is exhausted, and to return the best observed configuration. All evaluations can be executed independently in parallel (see Section 19.3), but here we use a sequential loop for simplicity.

 

무작위 검색은 우리가 고려할 첫 번째 하이퍼파라미터 최적화 알고리즘입니다. 무작위 검색의 주요 아이디어는 미리 정의된 예산(예: 최대 반복 횟수)이 소진될 때까지 구성 공간에서 독립적으로 샘플링하고 가장 잘 관찰된 구성을 반환하는 것입니다. 모든 평가는 독립적으로 병렬로 실행될 수 있지만(19.3절 참조) 여기서는 단순화를 위해 순차 루프를 사용합니다.

 

errors, values = [], []
num_iterations = 5

for i in range(num_iterations):
    learning_rate = config_space["learning_rate"].rvs()
    print(f"Trial {i}: learning_rate = {learning_rate}")
    y = hpo_objective_softmax_classification({"learning_rate": learning_rate})
    print(f"    validation_error = {y}")
    values.append(learning_rate)
    errors.append(y)

위의 코드는 하이퍼파라미터 최적화 과정을 반복적으로 실행하고, 각 반복에서 얻은 검증 오차와 하이퍼파라미터 값을 기록하는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. errors, values = [], []: 검증 오차와 하이퍼파라미터 값을 저장할 빈 리스트 errors와 values를 초기화합니다.
  2. num_iterations = 5: 하이퍼파라미터 최적화를 몇 번 반복할지를 나타내는 변수를 설정합니다. 여기서는 5번 반복합니다.
  3. for i in range(num_iterations):: num_iterations 횟수만큼 반복하는 루프를 시작합니다.
  4. learning_rate = config_space["learning_rate"].rvs(): 하이퍼파라미터 공간에서 "learning_rate" 하이퍼파라미터의 값을 랜덤하게 선택합니다. 이렇게 선택된 학습률 값을 learning_rate 변수에 저장합니다.
  5. print(f"Trial {i}: learning_rate = {learning_rate}"): 현재 반복의 정보를 출력합니다. 이 부분은 각 반복에서 어떤 하이퍼파라미터 값이 선택되었는지 확인하는 데 사용됩니다.
  6. y = hpo_objective_softmax_classification({"learning_rate": learning_rate}): 선택된 하이퍼파라미터 값을 사용하여 hpo_objective_softmax_classification 함수를 호출하여 검증 오차를 계산합니다. 계산된 검증 오차는 y에 저장됩니다.
  7. print(f" validation_error = {y}"): 계산된 검증 오차를 출력합니다. 이 부분은 각 반복에서 얻은 검증 오차를 확인하는 데 사용됩니다.
  8. values.append(learning_rate): 선택된 하이퍼파라미터 값(학습률)을 values 리스트에 추가합니다. 이렇게 하이퍼파라미터 값들이 기록됩니다.
  9. errors.append(y): 계산된 검증 오차를 errors 리스트에 추가합니다. 이렇게 검증 오차들이 기록됩니다.

이 코드는 하이퍼파라미터 최적화의 각 반복에서 랜덤하게 선택된 하이퍼파라미터 값을 사용하여 검증 오차를 계산하고, 이를 기록하여 최적의 하이퍼파라미터 조합을 찾기 위한 실험을 수행합니다.

 

 validation_error = 0.17070001363754272

 

 

The best learning rate is then simply the one with the lowest validation error.

 

가장 좋은 학습률은 검증 오류가 가장 낮은 학습률입니다.

 

best_idx = np.argmin(errors)
print(f"optimal learning rate = {values[best_idx]}")

위의 코드는 하이퍼파라미터 최적화 실험 결과에서 최적의 학습률(learning rate)을 선택하는 부분입니다. 코드의 목적과 각 부분에 대한 설명은 다음과 같습니다:

  1. best_idx = np.argmin(errors): 검증 오차(errors 리스트) 중에서 가장 작은 값을 가지는 인덱스를 찾습니다. np.argmin() 함수는 배열에서 최솟값을 가지는 원소의 인덱스를 반환합니다. 이를 통해 최적의 학습률을 선택할 때 해당 인덱스를 사용할 것입니다.
  2. print(f"optimal learning rate = {values[best_idx]}"): 최적의 학습률을 출력합니다. values 리스트에서 best_idx 인덱스에 해당하는 학습률 값을 가져와서 출력합니다. 이 값은 검증 오차가 가장 작을 때의 학습률을 나타냅니다.

즉, 이 코드는 여러 번의 하이퍼파라미터 최적화 실험을 통해 얻은 검증 오차를 분석하여, 검증 오차가 가장 작은 학습률을 최적의 학습률로 선택하고 출력합니다. 이렇게 찾은 최적의 하이퍼파라미터 값을 모델 학습에 사용할 수 있습니다.

optimal learning rate = 0.09844872561810249

 

Due to its simplicity and generality, random search is one of the most frequently used HPO algorithms. It does not require any sophisticated implementation and can be applied to any configuration space as long as we can define some probability distribution for each hyperparameter.

 

단순성과 일반성으로 인해 무작위 검색은 가장 자주 사용되는 HPO 알고리즘 중 하나입니다. 정교한 구현이 필요하지 않으며 각 하이퍼파라미터에 대한 확률 분포를 정의할 수 있는 한 모든 구성 공간에 적용할 수 있습니다.

 

Unfortunately random search also comes with a few shortcomings. First, it does not adapt the sampling distribution based on the previous observations it collected so far. Hence, it is equally likely to sample a poorly performing configuration than a better performing configuration. Second, the same amount of resources are spent for all configurations, even though some may show poor initial performance and are less likely to outperform previously seen configurations.

 

불행하게도 무작위 검색에는 몇 가지 단점도 있습니다. 첫째, 지금까지 수집한 이전 관측치를 기반으로 샘플링 분포를 조정하지 않습니다. 따라서 성능이 더 좋은 구성보다 성능이 낮은 구성을 샘플링할 가능성이 동일합니다. 둘째, 일부 구성은 초기 성능이 좋지 않고 이전 구성보다 성능이 떨어질 가능성이 있더라도 모든 구성에 동일한 양의 리소스가 사용됩니다.

 

In the next sections we will look at more sample efficient hyperparameter optimization algorithms that overcome the shortcomings of random search by using a model to guide the search. We will also look at algorithms that automatically stop the evaluation process of poorly performing configurations to speed up the optimization process.

 

다음 섹션에서는 검색을 안내하는 모델을 사용하여 무작위 검색의 단점을 극복하는 더 효율적인 하이퍼파라미터 최적화 알고리즘 샘플을 살펴보겠습니다. 또한 최적화 프로세스 속도를 높이기 위해 성능이 낮은 구성의 평가 프로세스를 자동으로 중지하는 알고리즘도 살펴보겠습니다.

 

19.1.3. Summary

In this section we introduced hyperparameter optimization (HPO) and how we can phrase it as a global optimization by defining a configuration space and an objective function. We also implemented our first HPO algorithm, random search, and applied it on a simple softmax classification problem.

 

이 섹션에서는 하이퍼파라미터 최적화(HPO)를 소개하고 구성 공간과 목적 함수를 정의하여 이를 전역 최적화로 표현하는 방법을 소개했습니다. 또한 첫 번째 HPO 알고리즘인 무작위 검색을 구현하고 이를 간단한 소프트맥스 분류 문제에 적용했습니다.

 

While random search is very simple, it is the better alternative to grid search, which simply evaluates a fixed set of hyperparameters. Random search somewhat mitigates the curse of dimensionality (Bellman, 1966), and can be far more efficient than grid search if the criterion most strongly depends on a small subset of the hyperparameters.

 

무작위 검색은 매우 간단하지만, 단순히 고정된 하이퍼파라미터 세트를 평가하는 그리드 검색보다 더 나은 대안입니다. 무작위 검색은 차원의 저주를 어느 정도 완화하며(Bellman, 1966), 기준이 하이퍼 매개변수의 작은 하위 집합에 가장 크게 의존하는 경우 그리드 검색보다 훨씬 더 효율적일 수 있습니다.

 

19.1.4. Exercises

  1. In this chapter, we optimize the validation error of a model after training on a disjoint training set. For simplicity, our code uses Trainer.val_dataloader, which maps to a loader around FashionMNIST.val.
    1. Convince yourself (by looking at the code) that this means we use the original FashionMNIST training set (60000 examples) for training, and the original test set (10000 examples) for validation.
    2. Why could this practice be problematic? Hint: Re-read Section 3.6, especially about model selection.
    3. What should we have done instead?
  2. We stated above that hyperparameter optimization by gradient descent is very hard to do. Consider a small problem, such as training a two-layer perceptron on the FashionMNIST dataset (Section 5.2) with a batch size of 256. We would like to tune the learning rate of SGD in order to minimize a validation metric after one epoch of training.
    1. Why cannot we use validation error for this purpose? What metric on the validation set would you use?
    2. Sketch (roughly) the computational graph of the validation metric after training for one epoch. You may assume that initial weights and hyperparameters (such as learning rate) are input nodes to this graph. Hint: Re-read about computational graphs in Section 5.3.
    3. Give a rough estimate of the number of floating point values you need to store during a forward pass on this graph. Hint: FashionMNIST has 60000 cases. Assume the required memory is dominated by the activations after each layer, and look up the layer widths in Section 5.2.
    4. Apart from the sheer amount of compute and storage required, what other issues would gradient-based hyperparameter optimization run into? Hint: Re-read about vanishing and exploding gradients in Section 5.4.
    5. Advanced: Read (Maclaurin et al., 2015) for an elegant (yet still somewhat unpractical) approach to gradient-based HPO.
  3. Grid search is another HPO baseline, where we define an equi-spaced grid for each hyperparameter, then iterate over the (combinatorial) Cartesian product in order to suggest configurations.
    1. We stated above that random search can be much more efficient than grid search for HPO on a sizable number of hyperparameters, if the criterion most strongly depends on a small subset of the hyperparameters. Why is this? Hint: Read (Bergstra et al., 2011).

 

 

 

 

 

반응형


반응형

https://d2l.ai/chapter_hyperparameter-optimization/index.html

 

19. Hyperparameter Optimization — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

19. Hyperparameter Optimization

Aaron Klein (Amazon), Matthias Seeger (Amazon), and Cedric Archambeau (Amazon)

 

 

The performance of every machine learning model depends on its hyperparameters. They control the learning algorithm or the structure of the underlying statistical model. However, there is no general way to choose hyperparameters in practice. Instead, hyperparameters are often set in a trial-and-error manner or sometimes left to their default values by practitioners, leading to suboptimal generalization.

 

모든 기계 학습 모델의 성능은 하이퍼파라미터에 따라 달라집니다. 학습 알고리즘이나 기본 통계 모델의 구조를 제어합니다. 그러나 실제로 하이퍼파라미터를 선택하는 일반적인 방법은 없습니다. 대신 초매개변수는 종종 시행착오 방식으로 설정되거나 때로는 실무자가 기본값으로 남겨두어 차선책 일반화로 이어집니다.

 

Hyperparameter optimization provides a systematic approach to this problem, by casting it as an optimization problem: a good set of hyperparameters should (at least) minimize a validation error. Compared to most other optimization problems arising in machine learning, hyperparameter optimization is a nested one, where each iteration requires training and validating a machine learning model.

 

하이퍼파라미터 최적화는 이 문제를 최적화 문제로 캐스팅하여 이 문제에 대한 체계적인 접근 방식을 제공합니다. 좋은 하이퍼파라미터 세트는 (적어도) 유효성 검사 오류를 최소화해야 합니다. 기계 학습에서 발생하는 대부분의 다른 최적화 문제와 비교할 때 하이퍼파라미터 최적화는 중첩된 문제로, 각 반복에는 기계 학습 모델을 훈련하고 검증해야 합니다.

 

In this chapter, we will first introduce the basics of hyperparameter optimization. We will also present some recent advancements that improve the overall efficiency of hyperparameter optimization by exploiting cheap-to-evaluate proxies of the original objective function. At the end of this chapter, you should be able to apply state-of-the-art hyperparameter optimization techniques to optimize the hyperparameter of your own machine learning algorithm.

 

이번 장에서는 먼저 하이퍼파라미터 최적화의 기본 사항을 소개합니다. 또한 원래 목적 함수의 평가하기 쉬운 프록시를 활용하여 하이퍼파라미터 최적화의 전반적인 효율성을 향상시키는 몇 가지 최근 발전 사항을 제시할 것입니다. 이 장을 마치면 최첨단 하이퍼파라미터 최적화 기술을 적용하여 자체 머신러닝 알고리즘의 하이퍼파라미터를 최적화할 수 있게 됩니다.

 

Hyperparameter Optimization 이란? (GPT 답변)

 

**하이퍼파라미터 최적화(Hyperparameter Optimization, HPO)**는 기계 학습 모델의 성능을 최대화하기 위해 모델의 하이퍼파라미터를 선택하는 과정을 가리킵니다. 하이퍼파라미터는 모델 자체가 아니라 모델을 구성하거나 교육하는 동안 조정할 수 있는 매개변수입니다. 이러한 하이퍼파라미터를 올바르게 선택하면 모델의 성능이 향상되며, 과적합(overfitting) 또는 과소적합(underfitting)과 같은 문제를 방지할 수 있습니다.

 

하이퍼파라미터 최적화 과정은 다음 단계로 진행됩니다:

 

  1. 하이퍼파라미터 공간 정의: 먼저 어떤 하이퍼파라미터를 조정할지 결정하고, 각 하이퍼파라미터의 유효한 범위 또는 가능한 값의 집합을 정의합니다. 예를 들어, 학습률(learning rate), 배치 크기(batch size), 은닉층의 수, 정규화 가중치 등의 하이퍼파라미터를 선택합니다.
  2. 목적 함수 정의: 하이퍼파라미터 최적화의 목표는 모델의 성능을 최대화하는 것이므로, 성능을 측정할 목적 함수(또는 손실 함수)를 정의해야 합니다. 이 목적 함수는 하이퍼파라미터 설정에 대한 모델의 성능을 측정합니다.
  3. 최적화 알고리즘 선택: 하이퍼파라미터 최적화를 위해 사용할 최적화 알고리즘을 선택합니다. 일반적으로 랜덤 서치(Random Search), 베이지안 최적화(Bayesian Optimization), 유전 알고리즘(Genetic Algorithm) 등의 다양한 알고리즘이 사용됩니다.
  4. 하이퍼파라미터 최적화 실행: 선택한 최적화 알고리즘을 사용하여 목적 함수를 최대화하는(또는 최소화하는) 하이퍼파라미터 조합을 찾습니다. 이러한 최적화 과정은 목적 함수를 여러 번 평가하며 진행됩니다.
  5. 최적의 하이퍼파라미터 설정 도출: 최적화 과정이 완료되면 최적의 하이퍼파라미터 설정을 얻게 됩니다. 이 설정을 사용하여 모델을 훈련하고 성능을 확인합니다.

하이퍼파라미터 최적화는 기계 학습 모델의 품질을 향상시키고, 모델을 더 효과적으로 조정하며, 과적합과 같은 문제를 방지하는 데 중요한 역할을 합니다. 그러나 주의할 점은 최적화 과정 자체가 계산적으로 비용이 많이 들 수 있으며, 하이퍼파라미터 공간이 크고 목적 함수가 불연속 또는 미분 불가능한 경우에 도전적일 수 있습니다. 따라서 하이퍼파라미터 최적화를 수행할 때는 최적화 알고리즘 선택, 하이퍼파라미터 공간 정의 등을 신중하게 고려해야 합니다.

 

 

반응형
이전 1 다음