W&B Sweep은 하이퍼파라미터 값을 탐색하는 전략과 그 값을 평가하는 코드를 결합합니다. 이 전략은 모든 옵션을 하나씩 시도하는 단순한 방식일 수도 있고, 베이즈 최적화와 Hyperband(BOHB)처럼 복잡한 방식일 수도 있습니다.
sweep 설정은 Python 딕셔너리 또는 YAML 파일로 정의할 수 있습니다. sweep 설정을 어떻게 정의할지는 sweep을 어떤 방식으로 관리하려는지에 따라 달라집니다.
명령줄에서 sweep을 초기화하고 sweep agent를 시작하려면 YAML 파일에 sweep 설정을 정의하세요. Python 스크립트 또는 노트북 내에서 sweep을 완전히 초기화하고 시작하려면 Python 딕셔너리에 sweep을 정의하세요.
다음 가이드에서는 sweep 설정 형식을 설명합니다. 최상위 sweep 설정 키의 전체 목록은 Sweep configuration options에서 확인하세요.
두 가지 sweep 설정 형식 옵션(YAML 및 Python 딕셔너리)은 모두 키-값 쌍과 중첩 구조를 사용합니다.
sweep 설정의 최상위 키를 사용해 sweep 이름(name 키), 검색할 매개변수(매개변수 키), 매개변수 공간을 검색하는 방법(method 키) 등 sweep 검색의 속성을 정의하세요.
예를 들어, 다음 코드 스니펫은 YAML 파일과 Python 딕셔너리에 정의된 동일한 sweep 설정을 보여줍니다. 이 sweep 설정에는 program, name, method, metric, parameters의 다섯 가지 최상위 키가 지정되어 있습니다.
명령줄(CLI)에서 대화형으로 sweeps를 관리하려면 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, epoch, optimizer 키가 중첩되어 있습니다. 지정한 각 중첩 키에는 하나 이상의 값, 분포, 확률 등을 제공할 수 있습니다. 자세한 내용은 Sweep configuration options의 매개변수 섹션을 참조하세요.
Sweep 설정은 중첩된 매개변수를 지원합니다. 중첩 매개변수를 정의하려면 최상위 매개변수 이름 아래에 parameters 키를 하나 더 추가하세요.
다음 예시는 nested_category_1, nested_category_2, nested_category_3의 세 가지 중첩 매개변수가 포함된 Sweep 설정을 보여줍니다. 각 중첩 매개변수에는 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]
}
}
}
}
}
sweep 설정에 정의된 중첩 매개변수는 W&B run 설정에 지정된 키를 덮어씁니다.예를 들어, 중첩된 기본값으로 run을 초기화하는 train.py 스크립트가 있다고 가정해 보겠습니다.def main():
with wandb.init(config={"nested_param": {"manual_key": 1}}) as run:
# 여기에 트레이닝 코드를 작성합니다
sweep 설정에서는 최상위 "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)
sweep run 중에는 run.config["nested_param"]에
sweep(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 Operator를 추가하세요. 그러면 값이 부동소수점 수로 캐스팅됩니다. 예를 들어 min: !!float 1e-5와 같습니다. 명령어 예시를 참조하세요.
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의 최소 또는 최대 반복 횟수를 지정하는 방법을 보여줍니다:
이 예제의 브래킷은 [3, 3*eta, 3*eta*eta, 3*eta*eta*eta]이며, [3, 9, 27, 81]와 같습니다.early_terminate:
type: hyperband
min_iter: 3
이 예제의 브래킷은 [27/eta, 27/eta/eta]이며, [9, 3]과 같습니다.early_terminate:
type: hyperband
max_iter: 27
s: 2
더 복잡한 명령줄 인수의 경우, 매크로를 사용해 환경 변수, Python 인터프리터, 추가 인수를 전달할 수 있습니다. W&B는 사전 정의된 매크로와 sweep 설정에서 지정할 수 있는 맞춤형 명령줄 인수를 지원합니다.
예를 들어, 다음 sweep 설정(sweep.yaml)은 Python 스크립트(run.py)를 실행하는 명령을 정의하며, sweep이 실행될 때 ${env}, ${interpreter}, ${program} 매크로가 적절한 값으로 대체됩니다.
--batch_size=${batch_size}, --test=True, --optimizer=${optimizer} 인수는 맞춤형 매크로를 사용해 sweep 설정에 정의된 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 Run 초기화
with wandb.init('test-project') as run:
run.log({'validation_loss':1})
Sweep 설정에서 사용할 수 있는 미리 정의된 매크로 목록은 Sweep 설정 옵션의 Command 매크로 섹션을 참조하세요.
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')