머신러닝 실험 관리의 필요성
머신러닝 모델을 학습하기 위해서 설정해야 하는 변수하이퍼파라미터는 한두 개가 아닙니다. 학습률이나 모멘텀처럼 연속적인 숫자는 이론 상 시도할 수 있는 경우의 수가 무한입니다. 게다가 옵티마이저, 손실함수 등을 여러가지 적용해본다면 실험은 더욱 복잡해지고, 개별 실험을 기록하고 비교하는 과정은 만만치 않을 것입니다.

머신러닝 실험 관리가 용이하도록 도와주는 툴은 많이 있습니다. 입문하는 과정에서 자주 들어볼 법한 시각화 툴로는 텐서보드TensorBoard가 있습니다. 이외에도 넵튠, WandB은 머신러닝 실험을 위한 대시보드 시각화, 파라미터 튜닝 자동화 등 다양한 기능을 제공합니다. 링크에는 15가지 머신러닝 관리 툴을 소개합니다.
WandB
WandB는 머신러닝 실험 관리 툴로 다음과 같은 특징이 있습니다.
- 무료 : 무료 버전은 개인 프로젝트만 관리할 수 있다. 100GB의 저장 공간을 지원해주고, Private 혹은 Public으로 관리할 수 있습니다.
- Web UI : 웹 브라우저에서 모든 기능을 이용할 수 있습니다.

WandB에서 제공하는 기능은 크게 5가지입니다.

- Experiments : 학습 실험의 경과를 추적하고 로그를 남깁니다.
- Arfifacts : 데이터셋이나 모델의 버전을 관리합니다.
- Tables : 여러 실험 결과를 테이블로 정리해 비교할 수 있습니다.
- Sweeps : 여러가지 설정 값을 시도하면서 모델을 최적화합니다.
- Reports : 실험 리포트를 작성할 수 있습니다. 대시보드를 쉽게 불러올 수 있어 효과적입니다. 팀 단위로 프로젝트를 진행하는 경우 동료와 실험 내용을 공유할 수 있습니다.본 글에서는 Weights & Biases를 소개하고 Experiments와 Sweep의 기초 사용법을 설명합니다. 공식 Quick Start 가이드는 여기에서 확인하시길 바랍니다.
Experiments Tracking
wandb 회원가입을 하고 아래 가이드를 봐주세요.
Set Up Wandb
- Login
# Command line
pip install wandb
wandb login
# Notebook
import wandb
wandb.login()
작업 환경에서 wandb 라이브러리를 설치하고 로그인합니다. 이후 https://wandb.ai/authorize 혹은 아래 이미지처럼 설정의 API Key를 복사/붙여넣기 합니다.


Start a new run
import wandb
wandb.init(entity="username", # 사용자 이름
project="my-project", # 프로젝트 이름
name="test") # run 이름
학습을 시작하기에 앞서 작업wandbrun을 초기화initialize 해야 하고, 실험 결과를 넘길 사용자, 프로젝트 등을 입력해야 합니다. 추가로 실험run의 이름을 name 파라미터로 지정할 수 있습니다. 이외에도 다양한 추가 설정이 있으니, wandb 공식 설명을 참고하길 바랍니다.
Configuration
wandb.init(config={"epochs": 4, "batch_size": 32})
# later
wandb.config.update({"lr": 0.1, "channels": 16})
# argparse.Namespace Configuration
wandb.init()
parser = argparse.ArgumentParser()
parser.add_arguemnt('-e', '--epochs', type=int, default=10)
parser.add_argument('-b', '--batch-size', type=int, default=8, metavar='N',
help='input batch size for training (default: 8)')
parser.add_argument('-l', '--learning-rate', type=float, default=1e-4)
args = parser.parse_args()
wandb.config.update(args) # adds all of the arguments as config variables
모델 학습할 때 설정 값을 추적하기 위해 Configuration을 등록해야 합니다. 등록한 Configuration은 웹 UI의 Overview나 테이블에서 확인할 수 있고, 주로 모델을 구분하거나 비교할 때 사용합니다. 설정 변수와 값을 파이썬 dictionary나 argparser Namespace로 정의해 wandb.init이나 wandb.config를 이용해 등록할 수 있습니다. .py 파일을 실행할 때는 argparse를 이용하고, notebook에서는 dictionary를 이용하는 것이 좋습니다.

Track Metrics
wandb.log({
"Step": global_step,
"train_l1_loss": train_l1_loss,
"train sync loss": train_sync_loss,
"train perceptual loss": train_perceptual_loss,
"train disc_real_loss": train_disc_real_loss,
"valid_l1_loss": valid_l1_loss,
"valid sync loss": valid_sync_loss,
"valid perceptual loss": valid_perceptual_loss,
"valid disc_real_loss": valid_disc_real_loss
})
모델 학습 중 손실 함숫값, 정확도 등 다양한 지표를 활용해 학습 진행 상황을 살펴봅니다. wandb의 log 기능을 이용해 간단하게 여러 정보를 지정된 사용자의 프로젝트로 넘길 수 있으며, 웹 UI에 자동으로 실시간 대시보드를 생성합니다.

학습 코드 예시
**# 작동하지 않는 Pytorch pseudocode입니다.**
import argparse
import wandb
import torch
parser = argparse.ArgumentParser()
parser.add_arguemnt('-e', '--epochs', type=int, default=10)
parser.add_argument('-b', '--batch-size', type=int, default=8, metavar='N',
help='input batch size for training (default: 8)')
parser.add_argument('-l', '--learning-rate', type=float, default=1e-4)
args = parser.parse_args()
**# wandb initilization : Start a new run**
**wandb.init(entity='username',
project='my-project',
run='test-run')
# wandb configuration
wandb.config.update(args)** # adds all of the arguments as config variables
model = MyModel()
optimizer = Adam()
loss_fn = CrossEntropy()
for epoch in range(args.epochs):
# Train
running_loss = 0
log_dict = {}
for inputs, targets in train_loader:
outputs = model(inputs)
train_loss = loss_fn(ouptuts, targets)
optimizer.zero_grad()
train_loss.backward()
optimizer.step()
running_loss += float(train_loss)
log_dict['step'] = epoch
log_dict['train loss'] = running_loss / len(train_loader.dataset)
# Validation
if epoch % 5 == 0:
running_loss = 0
acc = []
for inputs, targets in test_loader:
with torch.no_grad():
outputs = model(inputs)
valid_loss = loss_fn(outputs, targets)
running_loss += float(valid_loss)
acc.append((outputs.argmax(1) == targets))
acc = torch.cat(acc)
acc = acc.sum() / acc.numel()
log_dict['valid loss'] = running_loss / len(test_loader.dataset)
log_dict['accuracy'] = acc = acc.sum() / acc.numel()
# wandb log : track metrics
wandb.log(log_dict)
Sweep 하이퍼 파라미터 튜닝 자동화
세부 설정 가이드는 공식 문서를 참고하시길 바랍니다.
Jupyter Notebook
아래 코드는 jupyter notebook에서 sweep하는 예시입니다.
**# 작동하지 않는 Pytorch pseudocode입니다.**
import wandb
import torch
def get_loader(config):
# your data loader getting code here
return train_loader, test_loader
def get_model(config):
# your model making code here
return model
def get_optim(config):
# your optimizer getting code here
return optimizer
def train(model, loader, optimizer):
# your model training code here
return loss
def validation(model, loader):
# your model validation code here
return loss
def main(): # no arguments
with wandb.init() as run:
config = wandb.config
print("epochs :", config.epochs)
print("learning_rate :", config.learning_rate)
train_loader, test_loader = get_loader(config)
model = get_model(config)
optimizer = get_optim(config)
for epoch in range(config["epochs"]):
train_loss = train(model, loader, optimizer)
valid_loss = validation(model, loader)
wandb.log({"train loss": train_loss,
"valid loss": valid_loss,
"epoch": epoch})
sweep_config = {
"name" : "my-sweep",
"method" : "bayes",
"metric" : {
"name": "valid loss"
"goal": "minimize"
}
"parameters" : {
"epochs" : {
"values" : [10, 20, 50]
},
"learning_rate" :{
"min": 0.0001,
"max": 0.1
}
}
}
sweep_id = wandb.sweep(sweep_config)
wandb.agent(sweep_id,
function=main, # 학습 함수
count=5, # number of runs to execute
entity='username', 'project='my-project') # entity, project를 wandb.sweep에 입력합니다.
여기서는 bayes search로 val_loss를 최소화minimize하는 파라미터epoch,learningrate 조합 도출을 시도합니다. epoch은 10, 20, 50 중에 하나를, 학습률은 0.0001과 0.1 사이의 값을 선택해 조합합니다.
💡 참고
GPU를 사용할 때 Jupyter notebook 환경과 함께 wandb.agent를 사용하시면 수행 중 멈출 수 있습니다.
프레임워크에 의한 GPU/CUDA 리소스 초기화 방식 때문에 wandb.agent 및 jupyter 환경에 나쁜 상호 작용이 있을 수 있습니다
임시 해결책이상호작용을수정할때까지으로 에이전트 실행을 위해 python 인터페이스를 사용하지 않는 것입니다. 대신, 스윕 구성에서 program 키를 설정하여 명령줄 인터페이스를 사용하고 다음을 notebook에서 수행합니다
Yaml file
작성 중