Doby's Lab

체계적인 프로젝트를 위한 WandB (1) - 기록하기, 기초 본문

TEMP (애매한 글들 모음)

체계적인 프로젝트를 위한 WandB (1) - 기록하기, 기초

도비(Doby) 2023. 7. 12. 07:55

✅ Intro

모델을 학습시키면서 최적의 결과를 찾기 위해 하이퍼파라미터 튜닝을 진행합니다. 이러한 과정에서 값들에 대한 로그를 따로 문서화시켜 정리하거나 노트를 해두면 편하지만, 이는 간단하면서도 까다로웠던 경험이 있습니다. 이런 부분을 해소할 수 있는 툴, WandB를 알게 되었습니다.

 

WandB(Weights & Biases)는 프로젝트의 실험을 관리하고, 하이퍼 파라미터의 튜닝을 체계적으로 기록할 수 있도록 하고, 뿐만 아니라 최적의 하이퍼파라미터를 위해 여러 값들을 통해 실험해 볼 수 있는 기능(Sweep)등 여러 편리함들을 제공합니다. 이번 포스팅에서는 기초적인 기록에 대해서만 알아보겠습니다.


✅ How

(💡 아래 코드는 WandB에서 제공하는 QuickStart의 코드이며, 이번 포스팅에서 전반적으로 사용된 코드입니다. 문제가 될 시에 삭제 조치하겠습니다.)

import wandb
import random

wandb.login()

# Launch 5 simulated experiments
total_runs = 5
for run in range(total_runs):
    # 🐝 1️⃣ Start a new run to track this script
    wandb.init(
      # Set the project where this run will be logged
        project="basic-intro", 
      # We pass a run name (otherwise it’ll be randomly assigned, like sunshine-lollypop-10)
        name=f"experiment_{run}", 
      # Track hyperparameters and run metadata
        config={
            "learning_rate": 0.02,
            "architecture": "CNN",
            "dataset": "CIFAR-100",
            "epochs": 10,
        })
    wandb.define_metric("loss", summary="min")
    wandb.define_metric("acc", summary="max")
  # This simple block simulates a training loop logging metrics
    epochs = 10
    offset = random.random() / 5
    for epoch in range(2, epochs):
        acc = 1 - 2 ** -epoch - random.random() / epoch - offset
        loss = 2 ** -epoch + random.random() / epoch + offset
      
      # 🐝 2️⃣ Log metrics from your script to W&B
        wandb.log({"acc": acc, "loss": loss})
      
  # Mark the run as finished
    wandb.finish()

📄 wandb.login()

우선, wandb와 연결하기 위해서 노트북에서 import 한 뒤에 로그인을 통해 wandb 웹페이지에서 발급한 API Key를 입력해 줍니다. 이제 wandb를 사용할 수 있는 상태가 됩니다.

import wandb
wandb.login()

📄 wandb.init()

init의 설명에 앞서 wandb의 구조에 대해 간단히 알아보고 가야 합니다.

wandb에는 Project 단위로 어떠한 프로젝트들이 있는가를 나타내고, 한 프로젝트 안에 속한 하나 혹은 여러 개의 Run들로 구성이 됩니다. 하나의 Run에서 훈련이 어떻게 진행되었는지, 어떤 값들이 로그로 남겨져있는지 나타낼 수 있습니다.

위의 그림에서는 basic-intro가 프로젝트의 이름이고, experiment_? 가 각 Run을 지칭하는 이름으로 알 수 있습니다.

 

wandb.init()은 하나의 Run에 대해서 어떤 프로젝트 하위의 Run인지, 무슨 이름으로 할 건지, Configuration을 어떻게 할 건지에 대한 초기화와 Run을 시키는 필수적인 요소입니다.

 

이에 대해 간단한 코드로 나타내면, 아래와 같습니다.

wandb.init(
    project='basic-intro',
    name=f'experiment_{run}',
    config={
        'learning_rate': 0.02,
        'architecture': 'CNN',
        'dataset': 'CIFAR-100',
        'epochs': 10
    }
)

project parameter는 어떤 프로젝트에 속하는지를 나타내며 기존에 없는 프로젝트일 경우 새로운 프로젝트를 wandb에서 만들어냅니다. 반대로 어떠한 이름도 지정하지 않은 경우에는 'Uncategorized'로 빠지게 됩니다.

name parameter는 Run이 어떤 이름으로 나타나는지를 나타내며 지정하지 않을 경우, 랜덤으로 이름이 생기게 됩니다.

config parameter는 이번 Run에서 '이런 값들로 훈련을 시킬 거다'와 같은 기록이 필요한 값들을 파이썬 딕셔너리 형태로 담을 수 있습니다.

Configuration은 Run의 Overview에서 아래와 같이 확인이 가능합니다.

📄 wandb.log()

Configuration과 비슷한 개념입니다. Configuration은 '이번 Run에서는 이렇게 구성을 해봤다'라면, log는 '이렇게 구성을 했더니 과정들이 이렇게 그려지더라'를 나타내는 함수입니다.

wandb.log({
    'acc': acc,
    'loss': loss
})

함수에 딕셔너리를 전달함으로써 WandB에서는 Charts에서 확인이 가능합니다.

또한, log로 남긴 metric에 대해서 Summary에서도 확인이 가능합니다. Summary도 Configuration이 있는 Overview에서 확인이 가능합니다.

하지만, Summary에 남은 값들은 모두 최댓값, 최솟값과 같은 일반적으로 원하는 값들이 아닌 마지막으로 측정된 값들입니다. Summary에 원하는 방향의 값들로 남기기 위해서는 log에 남기기 전, metric에 대한 정의가 필요합니다.

wandb.define_metric("loss", summary="min")
wandb.define_metric("acc", summary="max")

wandb.log({"acc": acc, "loss": loss})

위 코드에 대한 결과는 Summary에서 아래와 같이 나타납니다.

Charts에 관해서는 다양한 그래프(plots, histogram)들로도 시각화가 가능하고, Axis에 관해서도 커스텀할 수 있으니 이를 참고하면, 더 유용하게 사용할 수 있습니다.

(Ref. https://docs.wandb.ai/guides/track/log)

📄 wandb.summary

wandb.log()를 통해서 Overview에 있는 Summary에 해당 Run에 대한 요약을 할 수 있지만, 직접적으로 원하는 (단일)값을 Summary에 띄울 수 있습니다. 딕셔너리에 새로운 Key : Value 형태로 다룰 수 있습니다.

wandb.summary['test_accuracy'] = test_acc

📄 wandb.alert()

학습을 하는 도중에 어떤 특이점에서 이메일이나 슬랙을 통해서 알림을 받고 싶다면, wandb.alert()를 사용하면 됩니다. User Setting에서 알림을 허용하도록 하고, 간단하게 조건문을 작성해 주면 원하는 조건에서 알림을 받을 수 있습니다.

if value <= threshold:
    wandb.alert(
        title='Alert! Alert!',
        text='Value is lower than Threshold'
    )

📄 wandb.finish()

Run을 끝낼 때, 필요한 코드입니다. 없어도 Run이 정상적으로 종료되는 것은 맞지만 여러 개의 Run을 한 번에 돌릴 때, 오류를 피하기 위해서 작성할 필요가 있습니다.

wandb.finish()

✅ Outro

기본적인 기록을 위해 기초적인 부분들만 다루어보았습니다. WandB에는 이외에도 Sweep과 같은 하이퍼파라미터 자동화 튜닝이 있지만, 한 번에 다루기에는 길고, 부족한 부분이 많아서 다음 포스팅에서 다루어보겠습니다.

또한, 코드로는 이해가 가지만, Tensorflow와 Pytorch에서는 어떻게 적용을 시킬 수 있을까도 디깅을 해보아야겠습니다.

이 포스팅에 사용된 코드들은 전부 WandB의 Quickstart에서 긁어왔습니다. (문제가 될 시 삭제 조치 하겠습니다.)


✅ Reference

https://minimin2.tistory.com/186

 

[MLOps] WandB 사용방법 (pytorch에서 사용하기)

Weights & Biases란?wandb는 MLOps 플랫폼으로 머신러닝, 딥러닝을 학습하는데 필요한 다양한 기능들을 제공한다. 대표적으로 아래의 기능등을 갖추고 있다.실험관리하이퍼파라미터 튜닝데이터, 모델

minimin2.tistory.com

https://docs.wandb.ai/guides/track/config#set-up-an-experiment-configuration

 

Configure Experiments | Weights & Biases Documentation

Use a dictionary-like object to save your experiment configuration

docs.wandb.ai

 

728x90