Weights & Biases를 통한 데이터 과학(Data Science) 실험 관리
BroutonLab 팀의 W&B 활용법에 관한 이 리포트를 접했을 때 저희는 전율을 느꼈습니다. 이제 여러분께 이 리포트를 소개하고자 합니다!
Created on June 24|Last edited on June 24
Comment
서론
모든 데이터 과학자들은 아마도 다음과 같은 상황에 직면해왔을 겁니다. 죽, 여러분께서는 다양한 매개변수 또는 심지어 전체 아키텍처를 실험하기 위해 수많은 모델을 생성하고, 또는 옵티마이저(optimizer) 선택, 학습률, 에포크(epoch) 수 등을 실험하고자 할 수도 있습니다. 따라서, 여러분께서는 수많은 다양한 실험을 하게 될 것이고, 이러한 결과를 구조화하는 것은 점점 더 어려워질 것입니다. 이번 글에서 저희는 ML 및 DL 실험을 적절하고 쉽게 관리 및 로그하는 법에 대해 여러분께 소개하고자 합니다.
오늘날에는 Weights & Biases, MlFlow, Neptune, Comet.ml 등 간편한 실험 관리를 가능케 해주는 다양한 툴이 존재합니다.
MlFlow 는 머신 학습 사��클 관리 오픈 소스 플랫폼입니다. 이 플랫폼은 단일 용도에 적합하나, 대규모 팀에서 사용하거나 실험 횟수가 상당히 많은 경우에는 적합하지 않습니다.
Neptune 은 머신 러닝 실행의 추적을 위한 가벼운 실행 관리 툴입니다. 3가지 타입의 구독 옵션을 제공하며, 이 중 2가지는 유료입니다. 개인적으로 이 서비스를 사용하고자 하신다면, 무료 액세스를 얻으실 수 있습니다.
Weights & Biases 개요
W&B는 데이터 과학자의 모델, 데이터세트, 시스템 정보 등의 추적을 지원하는 플랫폼입니다. 코드 몇 줄을 통해 이러한 기능에 대한 모든 것들을 추적할 수 있습니다. 개인 사용의 경우 무료입니다. 팀 사용의 경우 일반적으로 유료 유틸리티지만, 학습용 목적으로 이용하고자 하는 팀의 경우 무료입니다. 또한 여러분께서는 TensorFlow, Keras, PyTorch, Sklearn, fastai와 같은 여러분들이 선호하는 다양한 프레임워크와 함께 W&B를 사용하실 수 있습니다.
모든 추적 정보는 W&B UI의 전용 페이지로 전송되며, 여기서 고품질 시각화 열기, 정보 집계 및 모델 또는 매개변수 비교를 하실 수 있습니다. 원격 실험 정보 저장의 장점 중 하나는 팀원들과 동일 프로젝트를 공동으로 작업하고 그 결과를 공유할 수 있다는 점에 있습니다.
W&B는 다음의 4가지 유용한 툴을 제공합니다:
- 대시보드(Dashboard): 실험 추적
- 아티팩트(Artifacts): 데이터세트 버저닝(versioning), 모델 버저닝(versioning)
- 스윕(Sweep): 초매개변수(Hyperparameter) 최적화
- 리포트(Report): 재현 가능 결과의 저장 및 공유
모든 이 유틸리티에 대해서는 이 튜토리얼 후반부에서 살펴보겠습니다

그림 1. W&B 기능. 출처: Weights & Biases docs.
튜토리얼
우선, W&B 웹사이트에서 무료 계정을 생성해야 합니다. 그럼 간단한 Keras 분류기(classifier) 모델을 통하여 Jupyter-notebook을 생성해보겠습니다.
!pop install wandb -qimport wandb!wandb login
이제 W&B에서 새 프로젝트를 생성하고 첫 번째 실험을 위한 초매개변수와 함께 config를 설정하겠습니다.
project_name = 'first_steps'group_name = 'cnn'experiment_name = '2_conv'wandb.init(project=project_name,group=group_name,name=experiment_name,config={"conv_1": 32,"activation_1": "relu","kernel_size": (3, 3),"pool_size": (2, 2),"dropout": 0.3,"conv_2": 64,"activation_out": "softmax","optimizer": "adam","loss": "sparse_categorical_crossentropy","metric": "accuracy","epoch": 6,"batch_size": 32})config = wandb.config
보시다시피 config는 초매개변수가 포함된 사전(dictionary)입니다. 또한, .yaml 포맷의 cofig파일을로드할 수도 있습니다. wandb.init은 W&B에 새 실행을 생성하고 백그라운드 프로세스를 실행하여 데이터를 동기화합니다
다음 단계는 데이터 로딩 및 간단한 CNN 모델 정의입니다.
from wandb.keras import WandbCallbackmnist = tf.keras.datasets.mnist(x_train, y_train), (x_test, y_test) = mnist.load_data()our_model = cnn_mnist()class_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']our_model.fit(x_train, y_train, epochs=config.epoch, batch_size=config.batch_size,validation_data=(x_test, y_test),callbacks=[WandbCallback(data_type="image",labels=class_names)])wandb.finish()
저희는 Keras 콜백(callback)을 사용하여 자동으로 our_model.fit에서 추적된 모든 메트릭과 손실 값을 자동으로 저장했습니다. WandCallback() 클래스는 data_type, labels와 같은 수많은 옵션을 지원합니다.
대시보드(Dashboards)
이제, 결과를 살펴보겠습니다. 저희가 수행한 실행은 지금 저희가 나열한 그룹 및 실험 저희 프로젝트의 이름과 함께 왼쪽에 나타납니다. 그리고 W&B가 자동으로 기록한 수많은 정보에 액세스할 수 있습니다.

다음과 같은 여러 섹션이 있습니다:
- 차트(Charts) - 손실(loss), 정확도(accuracy) 등에 대한 정보를 포함하고 있으며, 또한 여기에는 데이터로부터의 몇 가지 예시도 포함됩니다.
- 시스템(System) - 메모리 사용량, CPU 사용량, GPU 온도와 같은 시스템 로드 정보를 포함하고 있습니다. GPU 사용 제어 및 최적 배치 크기를 선택할 수 있어 매우 유용합니다.
- 모델(Model) - 모델 구조 (그래프)에 대한 정보를 포함합니다.
- 로그(Logs) - Keras 기본 로깅(default logging)이 포함됩니다.
- 파일(Files) - config, 최적 모델, 출력 로그, 요구 사항과 같은 실험 중에 생성된 모든 파일을 포함합니다. 특정 실험을 재생성하려면 라이브러리의 특정 버전을 설치해야 하므로 이 요구사항 파일(requirements file)은 매우 중요합니다.
이러한 모든 로그 및 파일은 실험 재생성 시 필요하며, 이제 이러한 로그 및 파일의 생성을 자동화하여 시간을 아낄 수 있습니다. 이곳에서 이 프로젝트에 대한 저희 대시보드를 살펴보시기 바랍니다.
Sweeps
스윕은 단 몇 줄의 코드만으로 정확히 여러분이 원하는 대로 스윕을 구성할 수 있는 효과적인 레버를 제공하는 초매개변수 및 모델 최적화 툴입니다. 초매개변수 최적화(hyperparameters optimization) 테크닉에 대해 더 알고 싶으시다면, 최적화 메커니즘에 대하여 상세하게 다루고 있는 Efficient Hyperparameter Optimization with Optuna Framework에서 확인하실 수 있습니다.
우선, 여러분께서 최적화할 초매개변수와 함께 config를 정의해야 합니다. 또한, 임의 검색(random search) 또는 그리드 검색(grid search)과 같은 초매개변수 최적화 전략을 선택하셔야 합니다. 그다음, 최적화할 메트릭을 선택합니다.
sweep_config = {'method': 'random', #grid, random'metric': {'name': 'accuracy','goal': 'maximize'},'parameters': {'epoch': {'values': [5, 10]},'dropout': {'values': [0.3, 0.4, 0.5]},'conv_1': {'values': [16, 32, 64]},'conv_2': {'values': [16, 32, 64]},'optimizer': {'values': ['adam', 'nadam', 'sgd', 'rmsprop']},'activation_1': {'values': ['relu', 'elu', 'selu','sigmoid']},'kernel_size': {'values': [(3, 3), (5, 5), (7, 7)]}}}
그런 다음 스윕을 생성하고train 함수(train function)를 정의해보겠습니다. 이 스윕은 여러 세트의 초매개변수와 함께 이 함수를 호출합니다.
sweep_id = wandb.sweep(sweep_config, entity=user_name, project="first_steps")def train():# Default values for hyperparameters we're going to sweep overconfig_defaults = {"conv_1": 32,a"activation_1": "relu","kernel_size": (3, 3),"pool_size": (2, 2),"dropout": 0.1,"conv_2": 64,"activation_out": "softmax","optimizer": "adam","loss": "sparse_categorical_crossentropy","metric": "accuracy","epoch": 6,"batch_size": 32}# Initialize a new wandb runwandb.init(config=config_defaults, group='first_sweeps')# config is a variable that holds and saves hyperparameters and inputsconfig = wandb.configmodel = cnn_mnist(config=config)model.fit(x_train, y_train, epochs=config.epoch, batch_size=config.batch_size,validation_data=(x_test, y_test),callbacks=[wandb.keras.WandbCallback()])wandb.agent(sweep_id,train)
저희는 다음과 같은 출력(output)을 얻었습니다:

Run set
24
각 스윕의 결과를 살펴보고 모델에 가장 적절한 초매개변수를 선택해보겠습니다. 여러분께서는 관심 파라미터 세트에 따라 어떻게 정확도가 변하는지 확인하실 수 있습니다. 이러한 차트 외에도, 여러분께 가장 중요한 차트를 만드실 수 있습니다. 예를 들면, 모델의 예측치(predictions)를 로그하여 모델이 가장 자주 실수하는 예시를 찾을 수 있습니다.
아티팩트(Artifacts)
스윕 및 대시보드 이외에도, W&B는 사용자가 데이터 및 모델을 로그할 수 있게끔 하는 아티팩트라는 유용한 유틸리티를 제공합니다. 이러한 컨텍스트 상에서, 아티팩트는 생성된 객체(objects), (즉, 프로세스 출력), 데이터세트 및 모델입니다. 이제, 이전 예시의 데이터세트 로깅을 통해 아티팩트 사용법을 보여드리겠습니다.
우선 원시(raw) 데이터세트를 로드하고, 새로운 아티팩트를 생성하겠습니다.
def load_and_log():with wandb.init(project=project_name, job_type="load-data") as run:datasets = load_data()names = ["training", "validation", "test"]# Artifactraw_data = wandb.Artifact("mnist-raw", type="dataset",description="Raw MNIST dataset, splitted",metadata={"source": "keras.datasets.mnist","train_data": len(datasets[0].x),"valid_data": len(datasets[1].x),"test_daata": len(datasets[2].x)})for name, data in zip(names, datasets):# Save our datasetswith raw_data.new_file(name + ".npz", mode="wb") as file:np.savez(file, x=data.x, y=data.y)#save Artifactrun.log_artifact(raw_data)load_and_log()
다음은 아티팩트 관리에 대한 몇 가지 모범사례입니다.
- job_type 은 설명적이어야 하며 파이프라인의 단일 단계에 해당하여야 합니다 (저희는 사전처리 데이터(preprocessing data)에서 로딩 데이터를 분리하였습니다)
- 아티팩트의 이름은 설명적이어야 합니다
- 아티팩트의 유형(type)은 설명적이어야 하며 단순해야 합니다 (“dataset” 또는 “model”)
- 아티팩트에 대한 메타데이터 정보를 충분히 작성하시기 바랍니다
이러한 모든 방법은 여러분과 여러분의 팀원들이 파이프라인 구조를 적절하게 구성하는 데 있어 도움이 될 것입니다.
실행(run) 페이지와 아티팩트(Artifacts) 탭으로 이동하시면, 다음을 확인하실 수 있습니다:

"mnist-raw" 는 다음을 포함하는 출력 아티팩트입니다:
- 메타데이터(Metadata) – 현재 아티팩트에 대한 설명. 저희의 경우, 저희의 데이터세트 (소스, 분할 크기(split size))에 대한 설명입니다.
- 파일(Files) – 데이터세트
- 그래프 보기(Graph view) – 아티팩트 그래프 (입력, 출력, 프로세스)
그러면, 데이터 사전처리(data preprocessing)에 대해 설명하는 새 아티팩트를 추가해보겠습니다:
def preprocess_and_log(preprocess_steps):with wandb.init(project=project_name, job_type="data_preprocessing", name="preprocess_simple") as run:processed_data = wandb.Artifact("mnist-preprocessed", type="dataset",description="Preprocessed MNIST dataset",metadata=preprocess_steps)# which Artifact we will useraw_data_artifact = run.use_artifact('mnist-raw:latest')# download Artifactraw_dataset = raw_data_artifact.download()for split in ["training", "validation", "test"]:datafile = split + ".npz"data = np.load(os.path.join(raw_dataset, datafile))raw_split = Dataset(x=data["x"], y=data["y"])processed_dataset = preprocess_dataset(raw_split, **preprocess_steps)with processed_data.new_file(split + ".npz", mode="wb") as file:np.savez(file, x=processed_dataset.x, y=processed_dataset.y)run.log_artifact(processed_data)
우선, 새 아티팩트를 생성하고 이름을 지정합니다. 그다음, 사용할 아티팩트, mnist-raw:latest를 선택하겠습니다. 그런 다음, 각 데이터 분할에 대하여 preprocess_dataset가 적용됩니다. 마지막으로, 결과가 새 아티팩트에 저장됩니다. 그럼 이제 실행해봅시다.
steps = {"normalize": True,"expand_dims": True,"to_categorical" : True}preprocess_and_log(steps)

보시다시피, "mnist-raw"와 "mnist-prepocessed" 두 가지 아티팩트를 갖게 되었습니다. 그래프 보기(Graphview)는 파이프라인 단계에 대한 사용자 친화적인 인터페이스를 제공합니다. 사각형은 입력/출력(input/output) 아티팩트이며, 원은 아티팩트 간의 프로세스입니다. 그래프 보기를 사용하시면, 작업 과정에서 파이프라인이 어떻게 변하였는지 쉽게 추적하실 수 있습니다.
리포트(Reports)
리포트를 사용하여 시각화 구성, 결과 설명, 팀원과 업데이트 내용 공유 등을 간편하게 하실 수 있습니다. 리포트에서 여러분은 중요하다고 생각되는 모든 항목, 다양한 그래픽, 종속성(dependencies), 향후 플랜을 나타낼 수 있습니다. Latex 또는 Markdown을 통해 리포트를 편집하실 수 있습니다.
새 리포트 생성은 아주 간단합니다. wandb.ai의 작업 공간(workspace)으로 이동하여 Create Report(리포트 생성)를 클릭하시면 됩니다. 한 프로젝트 또는 한 그룹에 대한 리포트를 생성하실 수 있으며, 또는 두 프로젝트에서의 실행을 비교하는 교차 프로젝트 리포트를 생성할 수 있습니다. W&B는 몇 가지 템플릿을 제공하고 있으며, 사용자 지정 빈 리포트(custom blank report)를 생성할 수도 있습니다. 여러분께서 읽고 계신 이 게시물은 리포트의 한 예입니다.

그림 3. 리포트 템플릿. 출처: Weights & Biases doc.
- 스냅샷(Snapshot)은 현재 데이터/시간을 제목에 추가하고, 실행 세트(run set)에 필터를 추가합니다. 즉, 이는 현재 시각이 스냅샷에 포함되기 전에 생성된 실행만을 의미합니다.
- 대시보드(Dashboard)는 리포트에 “Project Dashboard”라는 제목을 지정하고 필터를 추가하여 선택된 실행의 현재 세트와 정확히 일치시킵니다.
- 업데이트(Update)는 리포트에 “<today’s date> Project Update”라는 제목을 지정하고 작업 영역(workspace)에서 선택된 정확한 실행 세트에 필터를 추가합니다.
- 공백(Blank)은 새 패널 그리드(fresh panel grid) 및 시각화를 추가 또는 본인을 위한 메모 공간을 제공합니다.

그림 4. 리포트 예시
이제 팀원들과 결과를 공유할 수 있습니다. 리포트 사용을 통해 오늘 실험에 대하여 얻은 정보를 요약을 보다 쉽게 할 수 있었습니다. 앞으로는 각 실험의 결과를 별도로 검색할 필요가 없으므로 해당 리포트를 여는 것만으로 충분해 보입니다.
결론
이 튜토리얼에서 저희는 Weights & Biases를 통해 실험을 효과적으로 관리하고 로그하는 방법에 대해 여러분께 소개했습니다. 저희는 이 플랫폼의 메인 툴을 검토해봤습니다. 고급 연구의 경우, 공식 문서를 참조하시기 바랍니다. 이 가이드가 여러분의 향후 작업에 유용하게 쓰이기를 바랍니다.
Add a comment