> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-serverless-sft-revamp.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Experiments 추적

export const ColabLink = ({url}) => <a href={url} target="_blank" rel="noopener noreferrer" className="colab-link">
    <svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
      <path d="M14.25.18l.9.2.73.26.59.3.45.32.34.34.25.34.16.33.1.3.04.26.02.2-.01.13V8.5l-.05.63-.13.55-.21.46-.26.38-.3.31-.33.25-.35.19-.35.14-.33.1-.3.07-.26.04-.21.02H8.77l-.69.05-.59.14-.5.22-.41.27-.33.32-.27.35-.2.36-.15.37-.1.35-.07.32-.04.27-.02.21v3.06H3.17l-.21-.03-.28-.07-.32-.12-.35-.18-.36-.26-.36-.36-.35-.46-.32-.59-.28-.73-.21-.88-.14-1.05-.05-1.23.06-1.22.16-1.04.24-.87.32-.71.36-.57.4-.44.42-.33.42-.24.4-.16.36-.1.32-.05.24-.01h.16l.06.01h8.16v-.83H6.18l-.01-2.75-.02-.37.05-.34.11-.31.17-.28.25-.26.31-.23.38-.2.44-.18.51-.15.58-.12.64-.1.71-.06.77-.04.84-.02 1.27.05zm-6.3 1.98l-.23.33-.08.41.08.41.23.34.33.22.41.09.41-.09.33-.22.23-.34.08-.41-.08-.41-.23-.33-.33-.22-.41-.09-.41.09zm13.09 3.95l.28.06.32.12.35.18.36.27.36.35.35.47.32.59.28.73.21.88.14 1.04.05 1.23-.06 1.23-.16 1.04-.24.86-.32.71-.36.57-.4.45-.42.33-.42.24-.4.16-.36.09-.32.05-.24.02-.16-.01h-8.22v.82h5.84l.01 2.76.02.36-.05.34-.11.31-.17.29-.25.25-.31.24-.38.2-.44.17-.51.15-.58.13-.64.09-.71.07-.77.04-.84.01-1.27-.04-1.07-.14-.9-.2-.73-.25-.59-.3-.45-.33-.34-.34-.25-.34-.16-.33-.1-.3-.04-.25-.02-.2.01-.13v-5.34l.05-.64.13-.54.21-.46.26-.38.3-.32.33-.24.35-.2.35-.14.33-.1.3-.06.26-.04.21-.02.13-.01h5.84l.69-.05.59-.14.5-.21.41-.28.33-.32.27-.35.2-.36.15-.36.1-.35.07-.32.04-.28.02-.21V6.07h2.09l.14.01.21.03zm-6.47 14.25l-.23.33-.08.41.08.41.23.33.33.23.41.08.41-.08.33-.23.23-.33.08-.41-.08-.41-.23-.33-.33-.23-.41-.08-.41.08z" />
    </svg>
    Try in Colab
  </a>;

<ColabLink url="https://colab.research.google.com/github/wandb/examples/blob/master/colabs/intro/Intro_to_Weights_&_Biases.ipynb" />

기계학습 실험 트래킹, 모델 체크포인트 생성, 팀과의 협업 등을 위해 [W\&B](https://wandb.ai/site)를 사용해 보세요.

이 노트북에서는 간단한 PyTorch 모델을 사용하여 기계학습 실험을 생성하고 트래킹해 보겠습니다. 노트북을 마칠 때쯤이면 팀원들과 공유하고 커스터마이징할 수 있는 대화형 프로젝트 대시보드를 갖게 될 것입니다. [여기에서 대시보드 예시를 확인하세요](https://wandb.ai/wandb/wandb_example).

## 사전 준비 사항

W\&B Python SDK를 설치하고 로그인합니다:

```shell theme={null}
!pip install wandb -qU
```

```python theme={null}
# W&B 계정에 로그인
import wandb
import random
import math
```

```python theme={null}
wandb.login()
```

## W\&B로 기계학습 실험 시뮬레이션 및 트래킹하기

기계학습 실험을 생성, 트래킹 및 시각화합니다. 방법은 다음과 같습니다:

1. [run](/models/runs/)을 초기화하고 트래킹하려는 하이퍼파라미터를 전달합니다.
2. 트레이닝 루프 내에서 정확도(accuracy) 및 손실(loss)과 같은 메트릭을 로그합니다.

```python theme={null}
import wandb
import random

project="basic-intro"
config = {
    "learning_rate": 0.02,
    "architecture": "CNN",
    "dataset": "CIFAR-100",
    "epochs": 10,
}

with wandb.init(project=project, config=config) as run:
  # 이 블록은 메트릭을 로그하는 트레이닝 루프를 시뮬레이션합니다.
  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. 스크립트에서 W&B로 메트릭 로그
      run.log({"acc": acc, "loss": loss})    
```

W\&B 프로젝트에서 기계학습 결과가 어떻게 나왔는지 확인해 보세요. 이전 셀에서 출력된 URL 링크를 복사하여 붙여넣습니다. 해당 URL은 모델의 성능을 보여주는 그래프가 포함된 대시보드가 있는 W\&B 프로젝트로 리다이렉트됩니다.

다음 이미지는 대시보드의 모습입니다:

<Frame>
  <img src="https://mintcdn.com/wb-21fd5541-serverless-sft-revamp/k60V_Bn1-o89Fhr9/images/tutorials/experiments-1.png?fit=max&auto=format&n=k60V_Bn1-o89Fhr9&q=85&s=b40a00996a0adfcd3a52598715ce8a8c" alt="W&B experiment tracking dashboard" width="2966" height="1256" data-path="images/tutorials/experiments-1.png" />
</Frame>

이제 가상의 기계학습 트레이닝 루프에 W\&B를 통합하는 방법을 알았으니, 기본적인 PyTorch 신경망을 사용하여 기계학습 실험을 트래킹해 보겠습니다. 다음 코드는 모델 체크포인트를 W\&B에 업로드하여 조직의 다른 팀원들과 공유할 수 있도록 합니다.

## PyTorch를 사용하여 기계학습 실험 트래킹하기

다음 코드 셀은 간단한 MNIST 분류기를 정의하고 트레이닝합니다. 트레이닝 중에 W\&B가 URL을 출력하는 것을 볼 수 있습니다. 프로젝트 페이지 링크를 클릭하면 결과가 W\&B 프로젝트로 실시간 스트리밍되는 것을 확인할 수 있습니다.

W\&B runs는 자동으로 [메트릭](/models/runs/#workspace-tab), 시스템 정보, [하이퍼파라미터](/models/runs/#overview-tab), [터미널 출력](/models/runs/#logs-tab)을 로그하며, 모델 입력 및 출력값이 포함된 [대화형 테이블](/models/tables/)을 볼 수 있습니다.

### PyTorch Dataloader 설정하기

다음 셀은 기계학습 모델을 트레이닝하는 데 필요한 유용한 함수들을 정의합니다. 이 함수들 자체는 W\&B 고유의 기능이 아니므로 여기서는 자세히 다루지 않겠습니다. [forward 및 backward 트레이닝 루프](https://pytorch.org/tutorials/beginner/nn_tutorial.html) 정의 방법, 트레이닝 데이터를 로드하기 위한 [PyTorch DataLoaders](https://pytorch.org/tutorials/beginner/basics/data_tutorial.html) 사용법, [`torch.nn.Sequential` 클래스](https://pytorch.org/docs/stable/generated/torch.nn.Sequential.html)를 사용한 PyTorch 모델 정의 방법은 PyTorch 문서를 참조하세요.

```python theme={null}
import wandb
import torch, torchvision
import torch.nn as nn
from torchvision.datasets import MNIST
import torchvision.transforms as T

MNIST.mirrors = [
    mirror for mirror in MNIST.mirrors if "http://yann.lecun.com/" not in mirror
]

device = "cuda:0" if torch.cuda.is_available() else "cpu"


def get_dataloader(is_train, batch_size, slice=5):
    "트레이닝 데이터로더 가져오기"
    full_dataset = MNIST(
        root=".", train=is_train, transform=T.ToTensor(), download=True
    )
    sub_dataset = torch.utils.data.Subset(
        full_dataset, indices=range(0, len(full_dataset), slice)
    )
    loader = torch.utils.data.DataLoader(
        dataset=sub_dataset,
        batch_size=batch_size,
        shuffle=True if is_train else False,
        pin_memory=True,
        num_workers=2,
    )
    return loader


def get_model(dropout):
    "단순한 모델"
    model = nn.Sequential(
        nn.Flatten(),
        nn.Linear(28 * 28, 256),
        nn.BatchNorm1d(256),
        nn.ReLU(),
        nn.Dropout(dropout),
        nn.Linear(256, 10),
    ).to(device)
    return model


def validate_model(model, valid_dl, loss_func, log_images=False, batch_idx=0):
    "검증 데이터셋에서 모델 성능을 계산하고 wandb.Table 로그"
    model.eval()
    val_loss = 0.0
    with torch.inference_mode():
        correct = 0
        for i, (images, labels) in enumerate(valid_dl):
            images, labels = images.to(device), labels.to(device)

            # Forward 패스 ➡
            outputs = model(images)
            val_loss += loss_func(outputs, labels) * labels.size(0)

            # 정확도 계산 및 누적
            _, predicted = torch.max(outputs.data, 1)
            correct += (predicted == labels).sum().item()

            # 대시보드에 이미지 한 배치를 로그, 항상 동일한 batch_idx 사용.
            if i == batch_idx and log_images:
                log_image_table(images, predicted, labels, outputs.softmax(dim=1))
    return val_loss / len(valid_dl.dataset), correct / len(valid_dl.dataset)
```

### 예측값과 실제값을 비교하기 위한 테이블 생성하기

다음 셀은 W\&B만의 고유한 기능이므로 자세히 살펴보겠습니다.

이 셀에서는 `log_image_table`이라는 함수를 정의합니다. 엄밀히 말하면 선택 사항이지만, 이 함수는 W\&B Table 오브젝트를 생성합니다. 이 테이블 오브젝트를 사용하여 모델이 각 이미지에 대해 무엇을 예측했는지 보여주는 테이블을 만들 것입니다.

구체적으로 각 행은 모델에 입력된 이미지와 예측값, 그리고 실제값(레이블)으로 구성됩니다.

```python theme={null}
def log_image_table(images, predicted, labels, probs):
    "wandb.Table에 (이미지, 예측값, 타겟, 점수) 로그"
    # 이미지, 레이블, 예측값을 로그할 wandb Table 생성
    table = wandb.Table(
        columns=["image", "pred", "target"] + [f"score_{i}" for i in range(10)]
    )
    for img, pred, targ, prob in zip(
        images.to("cpu"), predicted.to("cpu"), labels.to("cpu"), probs.to("cpu")
    ):
        table.add_data(wandb.Image(img[0].numpy() * 255), pred, targ, *prob.numpy())

    with wandb.init() as run:
        run.log({"predictions_table": table}, commit=False)
```

### 모델 트레이닝 및 체크포인트 업로드

다음 코드는 모델을 트레이닝하고 프로젝트에 모델 체크포인트를 저장합니다. 평소와 같이 모델 체크포인트를 사용하여 트레이닝 중 모델의 성능을 평가하세요.

W\&B를 사용하면 저장된 모델과 모델 체크포인트를 팀 또는 조직의 다른 구성원과 쉽게 공유할 수 있습니다. 팀 외부 구성원과 모델 및 모델 체크포인트를 공유하는 방법은 [W\&B Registry](/models/registry/)를 참조하세요.

```python theme={null}
import wandb

config = {
    "epochs": 5,
    "batch_size": 128,
    "lr": 1e-3,
    "dropout": random.uniform(0.01, 0.80),
}

project = "pytorch-intro"

# wandb run 초기화
with wandb.init(project=project, config=config) as run:

    # 선택적으로 설정(config) 복사
    config = run.config

    # 데이터 가져오기
    train_dl = get_dataloader(is_train=True, batch_size=config.batch_size)
    valid_dl = get_dataloader(is_train=False, batch_size=2 * config.batch_size)
    n_steps_per_epoch = math.ceil(len(train_dl.dataset) / config.batch_size)

    # 단순한 MLP 모델
    model = get_model(config.dropout)

    # 손실 함수 및 옵티마이저 생성
    loss_func = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=config.lr)

    # 트레이닝
    example_ct = 0
    step_ct = 0
    for epoch in range(config.epochs):
        model.train()
        for step, (images, labels) in enumerate(train_dl):
            images, labels = images.to(device), labels.to(device)

            outputs = model(images)
            train_loss = loss_func(outputs, labels)
            optimizer.zero_grad()
            train_loss.backward()
            optimizer.step()

            example_ct += len(images)
            metrics = {
                "train/train_loss": train_loss,
                "train/epoch": (step + 1 + (n_steps_per_epoch * epoch))
                / n_steps_per_epoch,
                "train/example_ct": example_ct,
            }

            if step + 1 < n_steps_per_epoch:
                # wandb에 트레이닝 메트릭 로그
                run.log(metrics)

            step_ct += 1

        val_loss, accuracy = validate_model(
            model, valid_dl, loss_func, log_images=(epoch == (config.epochs - 1))
        )

        # wandb에 트레이닝 및 검증 메트릭 로그
        val_metrics = {"val/val_loss": val_loss, "val/val_accuracy": accuracy}
        run.log({**metrics, **val_metrics})

        # wandb에 모델 체크포인트 저장
        torch.save(model, "my_model.pt")
        run.log_model(
            "./my_model.pt",
            "my_mnist_model",
            aliases=[f"epoch-{epoch+1}_dropout-{round(run.config.dropout, 4)}"],
        )

        print(
            f"Epoch: {epoch+1}, Train Loss: {train_loss:.3f}, Valid Loss: {val_loss:3f}, Accuracy: {accuracy:.2f}"
        )

    # 테스트 세트가 있는 경우, 이를 Summary 메트릭으로 로그하는 방법
    run.summary["test_accuracy"] = 0.8
```

이제 W\&B를 사용하여 첫 번째 모델을 트레이닝했습니다. 위의 링크 중 하나를 클릭하여 메트릭을 확인하고, W\&B 앱 UI의 Artifacts 탭에서 저장된 모델 체크포인트를 확인해 보세요.

## (선택 사항) W\&B Alert 설정하기

[W\&B Alerts](/models/runs/alert/)를 생성하여 Python 코드에서 Slack이나 이메일로 알림을 보낼 수 있습니다.

코드에서 트리거되는 Slack 또는 이메일 알림을 처음 보내려면 다음 2단계를 따르세요:

1. W\&B [User Settings](https://wandb.ai/settings)에서 Alerts를 켭니다.
2. 코드에 `run.alert()`를 추가합니다. 예:

```python theme={null}
run.alert(title="Low accuracy", text=f"Accuracy is below the acceptable threshold")
```

다음 셀은 `run.alert()` 사용법을 보여주는 간단한 예시입니다.

```python theme={null}
import wandb

# wandb run 시작
with wandb.init(project="pytorch-intro") as run:

    # 모델 트레이닝 루프 시뮬레이션
    acc_threshold = 0.3
    for training_step in range(1000):

        # 정확도를 위한 난수 생성
        accuracy = round(random.random() + random.random(), 3)
        print(f"Accuracy is: {accuracy}, {acc_threshold}")

        # wandb에 정확도 로그
        run.log({"Accuracy": accuracy})

        # 정확도가 임계값보다 낮으면 W&B Alert를 발생시키고 run 중지
        if accuracy <= acc_threshold:
            # wandb Alert 전송
            run.alert(
                title="Low Accuracy",
                text=f"Accuracy {accuracy} at step {training_step} is below the acceptable threshold, {acc_threshold}",
            )
            print("Alert triggered")
            break
```

자세한 내용은 [W\&B Alerts 개요](/models/runs/alert/)를 참조하세요.

## 다음 단계

다음 튜토리얼에서는 W\&B Sweeps를 사용하여 하이퍼파라미터 최적화를 수행하는 방법을 배웁니다:
[PyTorch를 사용한 Hyperparameter sweeps](https://colab.research.google.com/github/wandb/examples/blob/master/colabs/pytorch/Organizing_Hyperparameter_Sweeps_in_PyTorch_with_W%26B.ipynb)
