Tutorial Lengkap Weights & Biases: ML Experiment Tracking dan Visualization
Weights & Biases (W&B) adalah platform MLOps yang powerful untuk experiment tracking, visualisasi model, dan kolaborasi. W&B membantu tim ML melacak eksperimen, memvisualisasikan hasil, dan berbagi temuan dengan logging otomatis dan dashboard yang menarik.
Mengapa Weights & Biases?
Keunggulan W&B:- Automatic logging: Track metrics, hyperparameters, code
- Beautiful visualizations: Interactive dashboards
- Collaboration: Share experiments dengan tim
- Model registry: Version dan deploy models
- Sweeps: Hyperparameter optimization
- Experiment tracking
- Hyperparameter tuning
- Model comparison
- Team collaboration
- Production monitoring
Instalasi
pip install wandb
Login ke W&B
wandb login
Verify installation
python -c "import wandb; print(wandb.version)"
Quick Start
1. Basic Logging
import wandb
Initialize run
wandb.init(
project="my-ml-project",
name="experiment-1",
config={
"learningrate": 0.001,
"epochs": 100,
"batchsize": 32
}
)
Log metrics
for epoch in range(100):
loss = 1.0 / (epoch + 1)
accuracy = epoch / 100
wandb.log({
"epoch": epoch,
"loss": loss,
"accuracy": accuracy
})
Finish run
wandb.finish()
2. Dengan PyTorch
import wandb
import torch
import torch.nn as nn
wandb.init(project="pytorch-example")
model = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10)
)
Watch model
wandb.watch(model, log="all", logfreq=100)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(10):
for batchidx, (data, target) in enumerate(trainloader):
optimizer.zerograd()
output = model(data.view(-1, 784))
loss = criterion(output, target)
loss.backward()
optimizer.step()
wandb.log({
"batchloss": loss.item(),
"epoch": epoch
})
# Log epoch metrics
wandb.log({
"epoch": epoch,
"trainloss": epochloss,
"valaccuracy": valaccuracy
})
wandb.finish()
3. Dengan scikit-learn
import wandb
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import loadiris
from sklearn.modelselection import traintestsplit
from sklearn.metrics import accuracyscore, classificationreport
wandb.init(project="sklearn-example")
Load data
X, y = loadiris(returnXy=True)
Xtrain, Xtest, ytrain, ytest = traintestsplit(X, y, testsize=0.2)
Log config
config = {
"nestimators": 100,
"maxdepth": 10,
"randomstate": 42
}
wandb.config.update(config)
Train model
model = RandomForestClassifier(*config)
model.fit(Xtrain, ytrain)
Evaluate
ypred = model.predict(Xtest)
accuracy = accuracyscore(ytest, ypred)
wandb.log({
"accuracy": accuracy,
"classificationreport": classificationreport(ytest, ypred)
})
Log model
wandb.sklearn.plotclassifier(
model, Xtrain, Xtest, ytrain, ytest,
ypred, model.predictproba(Xtest),
labels=["setosa", "versicolor", "virginica"]
)
wandb.finish()
Configuration
1. Config Management
import wandb
Method 1: Pass ke init
wandb.init(
project="my-project",
config={
"learningrate": 0.001,
"architecture": "resnet50",
"dataset": "imagenet"
}
)
Method 2: Update config
wandb.config.update({
"optimizer": "adam",
"batchsize": 32
})
Method 3: Menggunakan argparse
import argparse
parser = argparse.ArgumentParser()
parser.addargument("--lr", type=float, default=0.001)
parser.addargument("--epochs", type=int, default=100)
args = parser.parseargs()
wandb.init(config=args)
Akses config
print(wandb.config.learningrate)
print(wandb.config["batchsize"])
2. Run Naming
import wandb
Auto-generated name
wandb.init(project="my-project")
Custom name
wandb.init(project="my-project", name="resnet50-lr0.001-bs32")
Tags
wandb.init(
project="my-project",
tags=["baseline", "production", "v2"]
)
Notes
wandb.init(
project="my-project",
notes="Testing strategi data augmentation baru"
)
Group related runs
wandb.init(
project="my-project",
group="experiment-1",
jobtype="train"
)
Logging
1. Metrics Logging
import wandb
import numpy as np
wandb.init(project="logging-demo")
Simple logging
wandb.log({"loss": 0.5, "accuracy": 0.85})
Dengan step
for step in range(1000):
wandb.log({"loss": 1/step}, step=step)
Multiple metrics
wandb.log({
"train/loss": 0.5,
"train/accuracy": 0.85,
"val/loss": 0.6,
"val/accuracy": 0.80
})
Histogram
wandb.log({"gradients": wandb.Histogram(np.random.randn(1000))})
Summary metrics (final values)
wandb.run.summary["bestaccuracy"] = 0.95
wandb.run.summary["totalepochs"] = 100
2. Media Logging
import wandb
import numpy as np
from PIL import Image
wandb.init(project="media-demo")
Log images
image = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
wandb.log({"image": wandb.Image(image, caption="Random image")})
Log PIL image
pilimage = Image.open("photo.jpg")
wandb.log({"photo": wandb.Image(pilimage)})
Log multiple images
images = [wandb.Image(img, caption=f"Image {i}") for i, img in enumerate(imagelist)]
wandb.log({"examples": images})
Log dengan masks (segmentation)
wandb.log({
"segmentation": wandb.Image(
image,
masks={
"predictions": {"maskdata": mask, "classlabels": classlabels}
}
)
})
Log audio
wandb.log({"audio": wandb.Audio(audioarray, samplerate=22050)})
Log video
wandb.log({"video": wandb.Video(videoarray, fps=30)})
Log 3D objects
wandb.log({"pointcloud": wandb.Object3D(pointcloudarray)})
3. Tables dan Charts
import wandb
import pandas as pd
wandb.init(project="tables-demo")
Log table
data = [
["kucing", 0.9, "correct"],
["anjing", 0.8, "correct"],
["burung", 0.3, "incorrect"]
]
columns = ["label", "confidence", "status"]
table = wandb.Table(data=data, columns=columns)
wandb.log({"predictions": table})
Dari pandas
df = pd.DataFrame({
"epoch": range(10),
"loss": [1/i for i in range(1, 11)],
"accuracy": [i/10 for i in range(1, 11)]
})
wandb.log({"trainingdata": wandb.Table(dataframe=df)})
Custom charts
wandb.log({
"customchart": wandb.plot.lineseries(
xs=list(range(10)),
ys=[[1/i for i in range(1, 11)], [i/10 for i in range(1, 11)]],
keys=["loss", "accuracy"],
title="Training Progress",
xname="epoch"
)
})
Confusion matrix
wandb.log({
"confmat": wandb.plot.confusionmatrix(
ytrue=ytrue,
preds=ypred,
classnames=["kucing", "anjing", "burung"]
)
})
Artifacts
1. Simpan Artifacts
import wandb
wandb.init(project="artifacts-demo")
Buat artifact
artifact = wandb.Artifact("my-dataset", type="dataset")
Tambahkan files
artifact.addfile("data/train.csv")
artifact.adddir("data/images/")
Tambahkan reference (untuk file besar)
artifact.addreference("s3://bucket/large-file.parquet")
Log artifact
wandb.logartifact(artifact)
Simpan model sebagai artifact
modelartifact = wandb.Artifact("model-v1", type="model")
modelartifact.addfile("model.pth")
modelartifact.addfile("config.json")
wandb.logartifact(modelartifact)
2. Gunakan Artifacts
import wandb
wandb.init(project="artifacts-demo")
Download artifact
artifact = wandb.useartifact("my-dataset:latest")
artifactdir = artifact.download()
Gunakan versi spesifik
artifact = wandb.useartifact("my-dataset:v3")
Gunakan by alias
artifact = wandb.useartifact("my-dataset:production")
Akses files
with artifact.file("train.csv").open() as f:
data = f.read()
Link artifacts
wandb.run.linkartifact(artifact, "my-portfolio/my-dataset")
3. Model Registry
import wandb
wandb.init(project="model-registry")
Log model ke registry
artifact = wandb.Artifact("my-model", type="model")
artifact.addfile("model.pth")
artifact.addfile("config.yaml")
Tambah metadata
artifact.metadata["accuracy"] = 0.95
artifact.metadata["framework"] = "pytorch"
Log dengan aliases
wandb.logartifact(artifact, aliases=["latest", "production"])
Promote model
run = wandb.init(project="model-registry")
artifact = run.useartifact("my-model:latest")
artifact.aliases.append("staging")
artifact.save()
Sweeps (Hyperparameter Tuning)
1. Define Sweep
# sweep.yaml
program: train.py
method: bayes
metric:
name: valaccuracy
goal: maximize
parameters:
learningrate:
distribution: loguniformvalues
min: 0.0001
max: 0.1
batchsize:
values: [16, 32, 64, 128]
epochs:
value: 50
optimizer:
values: ["adam", "sgd", "rmsprop"]
dropout:
distribution: uniform
min: 0.1
max: 0.5
2. Buat dan Run Sweep
import wandb
Define sweep config
sweepconfig = {
"method": "bayes",
"metric": {"name": "valaccuracy", "goal": "maximize"},
"parameters": {
"learningrate": {"distribution": "loguniformvalues", "min": 1e-4, "max": 1e-1},
"batchsize": {"values": [16, 32, 64]},
"epochs": {"value": 50}
}
}
Buat sweep
sweepid = wandb.sweep(sweepconfig, project="my-project")
Define training function
def train():
wandb.init()
config = wandb.config
model = createmodel(config.learningrate)
for epoch in range(config.epochs):
trainloss = trainepoch(model, config.batchsize)
valaccuracy = evaluate(model)
wandb.log({
"trainloss": trainloss,
"valaccuracy": valaccuracy
})
Jalankan sweep agent
wandb.agent(sweepid, train, count=20)
3. Early Termination
sweepconfig = {
"method": "bayes",
"metric": {"name": "val
loss", "goal": "minimize"},
"earlyterminate": {
"type": "hyperband",
"miniter": 5,
"eta": 3
},
"parameters": {...}
}
Reports
import wandb
Buat report secara programmatic
api = wandb.Api()
Get runs
runs = api.runs("my-project")
Filter runs
bestruns = [run for run in runs if run.summary.get("accuracy", 0) > 0.9]
Buat comparison table
for run in bestruns:
print(f"Run: {run.name}")
print(f" Accuracy: {run.summary['accuracy']}")
print(f" Config: {run.config}")
Integrasi
1. PyTorch Lightning
import pytorchlightning as pl
from pytorch
lightning.loggers import WandbLogger
wandblogger = WandbLogger(
project="lightning-example",
name="resnet50-run",
logmodel=True
)
trainer = pl.Trainer(
logger=wandblogger,
maxepochs=100
)
Log hyperparameters
wandblogger.loghyperparams({
"learningrate": 0.001,
"batchsize": 32
})
trainer.fit(model, datamodule)
2. Hugging Face Transformers
from transformers import TrainingArguments, Trainer
import wandb
wandb.init(project="transformers-example")
trainingargs = TrainingArguments(
outputdir="./results",
reportto="wandb",
loggingsteps=10,
evaluationstrategy="epoch",
savestrategy="epoch",
loadbestmodelatend=True
)
trainer = Trainer(
model=model,
args=trainingargs,
traindataset=traindataset,
evaldataset=evaldataset
)
trainer.train()
wandb.finish()
3. Keras
import wandb
from wandb.keras import WandbCallback
wandb.init(project="keras-example")
model.fit(
Xtrain, ytrain,
validationdata=(Xval, yval),
epochs=100,
callbacks=[WandbCallback(
savemodel=True,
monitor="valaccuracy",
logweights=True
)]
)
Best Practices
1. Organize Projects
# Gunakan naming yang konsisten
wandb.init(
project="image-classification",
group="resnet-experiments",
jobtype="train",
name="resnet50-augmented-v2",
tags=["production", "augmented", "v2"]
)
2. Log Everything
wandb.init(project="complete-logging")
Log code
wandb.run.logcode(".")
Log environment
wandb.config.update({
"pythonversion": sys.version,
"torchversion": torch.version,
"cudaavailable": torch.cuda.isavailable()
})
Log git info (otomatis)
Log system metrics (otomatis)
3. Offline Mode
import os
os.environ["WANDBMODE"] = "offline"
Atau
wandb.init(mode="offline")
Sync nanti
wandb sync wandb/offline-run-
Kesimpulan
Weights & Biases adalah essential untuk ML experiment tracking dengan:
Key takeaways:
- Log semua untuk reproducibility
- Gunakan artifacts untuk data dan model versioning
- Sweeps untuk systematic hyperparameter search
- Organize dengan projects, groups, dan tags
- Enable team collaboration dengan reports