W&B 스윕은 하이퍼파라미터 값을 탐색하는 전략과 해당 값을 평가하는 코드를 결합한 것입니다. 전략은 가능한 모든 옵션을 시도하는 것만큼 단순할 수도 있고, Bayesian Optimization과 Hyperband (BOHB)만큼 복잡할 수도 있습니다.
스윕 구성은 Python dictionary 또는 YAML 파일로 정의할 수 있습니다. 스윕 구성을 어떻게 정의할지는 스윕을 어떻게 관리할지에 따라 달라집니다.
명령줄에서 스윕을 초기화하고 스윕 에이전트를 시작하려면 YAML 파일로 스윕 구성을 정의하십시오. 스윕을 초기화하고 시작하는 전체 과정을 Python 스크립트나 노트북 내에서만 수행하려면 Python dictionary로 스윕 구성을 정의하십시오.
다음 가이드는 스윕 구성의 형식을 지정하는 방법을 설명합니다. 최상위 스윕 구성 키의 전체 목록은 스윕 구성 옵션을 참조하십시오.
두 가지 Sweep 구성 형식 옵션(YAML 및 Python 딕셔너리)은 모두 키-값 쌍과 중첩 구조를 사용합니다.
Sweep 구성의 최상위 키를 사용하여 Sweep 검색의 이름(name 키), 검색할 파라미터(parameters 키), 파라미터 공간을 탐색하는 방법(method 키) 등 Sweep 검색의 특성을 정의합니다.
예를 들어, 다음 코드 스니펫은 동일한 Sweep 구성을 YAML 파일과 Python 딕셔너리로 각각 정의한 것입니다. Sweep 구성 내에는 program, name, method, metric, parameters 총 다섯 개의 최상위 키가 지정되어 있습니다.
명령줄(CLI)에서 상호작용 방식으로 Sweep을 관리하려면 YAML 파일로 Sweep 구성을 정의하십시오.program: train.py
name: sweepdemo
method: bayes
metric:
goal: minimize
name: validation_loss
parameters:
learning_rate:
min: 0.0001
max: 0.1
batch_size:
values: [16, 32, 64]
epochs:
values: [5, 10, 15]
optimizer:
values: ["adam", "sgd"]
Python 스크립트나 노트북에서 학습 알고리즘을 정의하는 경우 Python 딕셔너리 자료 구조로 Sweep을 정의하십시오.다음 코드 스니펫은 sweep_configuration이라는 변수에 Sweep 구성을 저장합니다:sweep_configuration = {
"name": "sweepdemo",
"method": "bayes",
"metric": {"goal": "minimize", "name": "validation_loss"},
"parameters": {
"learning_rate": {"min": 0.0001, "max": 0.1},
"batch_size": {"values": [16, 32, 64]},
"epochs": {"values": [5, 10, 15]},
"optimizer": {"values": ["adam", "sgd"]},
},
}
최상위 parameters 키 내부에는 learning_rate, batch_size, epochs, optimizer 키가 중첩되어 있습니다. 지정한 각 중첩 키마다 하나 이상의 값, 분포, 확률 등을 제공할 수 있습니다. 자세한 내용은 Sweep configuration options의 parameters 섹션을 참조하십시오.
스윕(Sweep) 구성은 중첩 파라미터를 지원합니다. 중첩 파라미터를 정의하려면 최상위 파라미터 이름 아래에 추가 parameters 키를 포함하세요.
다음 예시는 nested_category_1, nested_category_2, nested_category_3라는 세 개의 중첩 파라미터가 있는 스윕 구성을 보여줍니다. 각 중첩 파라미터에는 momentum과 weight_decay라는 두 개의 추가 파라미터가 포함됩니다.
nested_category_1, nested_category_2, nested_category_3는 플레이스홀더입니다. 사용 사례에 맞는 이름으로 바꿔서 사용하세요.
다음 코드 스니펫은 YAML 파일과 Python 딕셔너리에서 각각 중첩 파라미터를 정의하는 방법을 보여줍니다.
program: sweep_nest.py
name: nested_sweep
method: random
metric:
name: loss
goal: minimize
parameters:
optimizer:
values: ['adam', 'sgd']
fc_layer_size:
values: [128, 256, 512]
dropout:
values: [0.3, 0.4, 0.5]
epochs:
value: 1
learning_rate:
distribution: uniform
min: 0
max: 0.1
batch_size:
distribution: q_log_uniform_values
q: 8
min: 32
max: 256
nested_category_1:
parameters:
momentum:
distribution: uniform
min: 0.0
max: 0.9
weight_decay:
values: [0.0001, 0.0005, 0.001]
nested_category_2:
parameters:
momentum:
distribution: uniform
min: 0.0
max: 0.9
weight_decay:
values: [0.1, 0.2, 0.3]
nested_category_3:
parameters:
momentum:
distribution: uniform
min: 0.5
max: 0.7
weight_decay:
values: [0.2, 0.3, 0.4]
{
"program": "sweep_nest.py",
"name": "nested_sweep",
"method": "random",
"metric": {
"name": "loss",
"goal": "minimize"
},
"parameters": {
"optimizer": {
"values": ["adam", "sgd"]
},
"fc_layer_size": {
"values": [128, 256, 512]
},
"dropout": {
"values": [0.3, 0.4, 0.5]
},
"epochs": {
"value": 1
},
"learning_rate": {
"distribution": "uniform",
"min": 0,
"max": 0.1
},
"batch_size": {
"distribution": "q_log_uniform_values",
"q": 8,
"min": 32,
"max": 256
},
"nested_category_1": {
"parameters": {
"momentum": {
"distribution": "uniform",
"min": 0.0,
"max": 0.9
},
"weight_decay": {
"values": [0.0001, 0.0005, 0.001]
}
}
},
"nested_category_2": {
"parameters": {
"momentum": {
"distribution": "uniform",
"min": 0.0,
"max": 0.9
},
"weight_decay": {
"values": [0.1, 0.2, 0.3]
}
}
},
"nested_category_3": {
"parameters": {
"momentum": {
"distribution": "uniform",
"min": 0.5,
"max": 0.7
},
"weight_decay": {
"values": [0.2, 0.3, 0.4]
}
}
}
}
}
스윕 구성에서 정의한 중첩 매개변수는 W&B 실행 구성에서 지정한 키를 덮어씁니다.예를 들어, 중첩된 기본값으로 실행을 초기화하는 train.py 스크립트가 있다고 가정해 보겠습니다:def main():
with wandb.init(config={"nested_param": {"manual_key": 1}}) as run:
# Your training code here
스윕 구성에서는 최상위 "parameters" 키 아래에 중첩 매개변수를 정의합니다:sweep_configuration = {
"method": "grid",
"metric": {"name": "score", "goal": "minimize"},
"parameters": {
"top_level_param": {"value": 0},
"nested_param": {
"parameters": {
"learning_rate": {"value": 0.01},
"double_nested_param": {
"parameters": {"x": {"value": 0.9}, "y": {"value": 0.8}}
},
}
},
},
}
sweep_id = wandb.sweep(sweep=sweep_configuration, project="<project>")
wandb.agent(sweep_id, function=main, count=4)
스윕 실행 시 run.config["nested_param"]에는 스윕 구성에서 정의한
(learning_rate, double_nested_param) 서브트리만 반영되며,
wandb.init(config=...)에서 정의한 manual_key는 포함되지 않습니다.
다음 템플릿은 매개변수를 구성하고 검색 제약 조건을 지정하는 방법을 보여줍니다. hyperparameter_name을(를) 사용 중인 하이퍼파라미터의 이름으로 바꾸고, <>로 둘러싸인 값들도 모두 실제 값으로 교체하세요.
program: <insert>
method: <insert>
parameter:
hyperparameter_name0:
value: 0
hyperparameter_name1:
values: [0, 0, 0]
hyperparameter_name:
distribution: <insert>
value: <insert>
hyperparameter_name2:
distribution: <insert>
min: <insert>
max: <insert>
q: <insert>
hyperparameter_name3:
distribution: <insert>
values:
- <list_of_values>
- <list_of_values>
- <list_of_values>
early_terminate:
type: hyperband
s: 0
eta: 0
max_iter: 0
command:
- ${Command macro}
- ${Command macro}
- ${Command macro}
- ${Command macro}
숫자 값을 지수 표기법으로 표현하려면 YAML의 !!float 태그를 추가하여 값을 부동 소수점 숫자로 변환하십시오. 예를 들어, min: !!float 1e-5와 같이 작성합니다. 자세한 내용은 Command example을 참조하십시오.
program: train.py
method: random
metric:
goal: minimize
name: loss
parameters:
batch_size:
distribution: q_log_uniform_values
max: 256
min: 32
q: 8
dropout:
values: [0.3, 0.4, 0.5]
epochs:
value: 1
fc_layer_size:
values: [128, 256, 512]
learning_rate:
distribution: uniform
max: 0.1
min: 0
optimizer:
values: ["adam", "sgd"]
sweep_config = {
"method": "random",
"metric": {"goal": "minimize", "name": "loss"},
"parameters": {
"batch_size": {
"distribution": "q_log_uniform_values",
"max": 256,
"min": 32,
"q": 8,
},
"dropout": {"values": [0.3, 0.4, 0.5]},
"epochs": {"value": 1},
"fc_layer_size": {"values": [128, 256, 512]},
"learning_rate": {"distribution": "uniform", "max": 0.1, "min": 0},
"optimizer": {"values": ["adam", "sgd"]},
},
}
program: train.py
method: bayes
metric:
goal: minimize
name: val_loss
parameters:
dropout:
values: [0.15, 0.2, 0.25, 0.3, 0.4]
hidden_layer_size:
values: [96, 128, 148]
layer_1_size:
values: [10, 12, 14, 16, 18, 20]
layer_2_size:
values: [24, 28, 32, 36, 40, 44]
learn_rate:
values: [0.001, 0.01, 0.003]
decay:
values: [1e-5, 1e-6, 1e-7]
momentum:
values: [0.8, 0.9, 0.95]
epochs:
value: 27
early_terminate:
type: hyperband
s: 2
eta: 3
max_iter: 27
아래 탭에서는 early_terminate에 대해 반복 횟수의 최소값 또는 최대값을 지정하는 방법을 보여줍니다:
이 예제에서의 브래킷(bracket)은 다음과 같습니다: [3, 3*eta, 3*eta*eta, 3*eta*eta*eta], 이는 [3, 9, 27, 81]과 같습니다.early_terminate:
type: hyperband
min_iter: 3
이 예제에서의 브래킷(bracket)은 [27/eta, 27/eta/eta]이며, 이는 [9, 3]과 같습니다.early_terminate:
type: hyperband
max_iter: 27
s: 2
더 복잡한 명령줄 인자가 필요한 경우 매크로를 사용해 환경 변수, Python 인터프리터, 그리고 추가 인자를 전달할 수 있습니다. W&B는 미리 정의된 매크로와 스위프 설정에서 지정할 수 있는 사용자 정의 명령줄 인자를 지원합니다.
예를 들어, 다음 스위프 설정(sweep.yaml)은 Python 스크립트(run.py)를 실행하는 명령을 정의하며, ${env}, ${interpreter}, ${program} 매크로는 스위프가 실행될 때 적절한 값으로 치환됩니다.
--batch_size=${batch_size}, --test=True, --optimizer=${optimizer} 인자는 스위프 설정에 정의된 batch_size, test, optimizer 파라미터 값을 전달하기 위해 사용자 정의 매크로를 사용합니다.
program: run.py
method: random
metric:
name: validation_loss
parameters:
learning_rate:
min: 0.0001
max: 0.1
command:
- ${env}
- ${interpreter}
- ${program}
- "--batch_size=${batch_size}"
- "--optimizer=${optimizer}"
- "--test=True"
관련 Python 스크립트(run.py)는 그런 다음 argparse 모듈을 사용해 이러한 명령줄 인자를 파싱할 수 있습니다.
# run.py
import wandb
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--batch_size', type=int)
parser.add_argument('--optimizer', type=str, choices=['adam', 'sgd'], required=True)
parser.add_argument('--test', type=str2bool, default=False)
args = parser.parse_args()
# W&B 실행 초기화
with wandb.init('test-project') as run:
run.log({'validation_loss':1})
스위프 구성에서 사용할 수 있는 사전 정의 매크로 목록은 스위프 구성 옵션의 Command macros 섹션을 참조하세요.
argparse 모듈은 기본적으로 불리언 인자를 직접 지원하지 않습니다. 불리언 인자를 정의하려면 action 파라미터를 사용하거나, 불리언 값의 문자열 표현을 불리언 타입으로 변환하는 사용자 정의 함수를 사용할 수 있습니다.
예를 들어, 아래 코드 스니펫을 사용하여 불리언 인자를 정의할 수 있습니다. ArgumentParser에 store_true 또는 store_false를 인자로 전달하십시오.
import wandb
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', action='store_true')
args = parser.parse_args()
args.test # --test가 전달되면 True, 그렇지 않으면 False
불리언 값의 문자열 표현을 실제 불리언 타입으로 변환하는 사용자 정의 함수를 정의할 수도 있습니다. 예를 들어, 다음 코드 스니펫에서는 문자열을 불리언 값으로 변환하는 str2bool 함수를 정의합니다.
def str2bool(v: str) -> bool:
"""문자열을 불리언으로 변환합니다. argparse가 기본적으로
불리언 인수를 지원하지 않으므로 이 함수가 필요합니다.
"""
if isinstance(v, bool):
return v
return v.lower() in ('yes', 'true', 't', '1')