24년 1월 30일에 새로이 update된 Pytorch 2.2는 여러 변경사항이 존재한다.

 

📌 목차

1. TorchRL
2. TorchVision - Transform v2

3. TorchVision - torch.compile()

 

🧐  Summary

Pytorch 2.2는 여러 도메인에서 아래와 같은 Update가 있었다:

 

 

 

 

 

 

 


1. TorchRL

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


2. TorchVision - Transform v2

torchvision.transform.v2

transform v2가 드디어 오픈되었다.
간단한 소개?정도와 내용을 조금만 알아보려 한다.



∙ V2  API  Reference



Examples

 Classification

import torch
from torchvision.transforms import v2

H, W = 32, 32
img = torch.randint(0, 256, size=(3, H, W), dtype=torch.uint8)

transforms = v2.Compose([
    v2.RandomResizedCrop(size=(224, 224), antialias=True),
    v2.RandomHorizontalFlip(p=0.5),
    v2.ToDtype(torch.float32, scale=True),
    v2.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
img = transforms(img)


∙ Detection

# Detection (re-using imports and transforms from above)
from torchvision import tv_tensors

img = torch.randint(0, 256, size=(3, H, W), dtype=torch.uint8)
boxes = torch.randint(0, H // 2, size=(3, 4))
boxes[:, 2:] += boxes[:, :2]
boxes = tv_tensors.BoundingBoxes(boxes, format="XYXY", canvas_size=(H, W))

transforms = v2.Compose(
    [
        v2.ToImage(),
        v2.RandomPhotometricDistort(p=1),
        v2.RandomZoomOut(fill={tv_tensors.Image: (123, 117, 104), "others": 0}),
        v2.RandomIoUCrop(),
        v2.RandomHorizontalFlip(p=1),
        v2.SanitizeBoundingBoxes(),
        v2.ToDtype(torch.float32, scale=True),
    ]
)

# The same transforms can be used!
img, boxes = transforms(img, boxes)
# And you can pass arbitrary input structures
output_dict = transforms({"image": img, "boxes": boxes})

아래 Reference Code참고) Pytorch Starting with Transform V2
 

Transforming and augmenting images — Torchvision main documentation

Shortcuts

pytorch.org

 

 

 

 

 

 

 

 

 


3.  TorchVision - torch.compile( )

torch.compile()

torch.compile()의 update는 점점 그래프나누기를 줄이고 동적형태를 허용한다.
transform측면에서 대부분 저수준커널(ex. resize, crop, 등)은
그래프 중단없이 동적으로 compile되어야한다.


사용목적:

∙ Tensorflow의 model.compile:

함수 인자로 Optimizer, Loss, Metric을 사용한다.
model.compile(optimizer="Adam", loss="mse", metrics=["mae"])


∙ Pytorch의 torch.compile:

기존 학습코드자체는 그대로 유지.
Pytorch가 기존에 작동하던 C++베이스→Python상에서 구동되게 함.

[적용되는 기술들]:
  • TorchDynamo : Python frame evaluation hooks를 사용해 pytorch 안정성에 기여.
    정확히는 아직 잘 모르겠지만 역전파 같은 graph capture에서 도움이 된다.

  • AOTAutograd : 기존 pytorch의 Autograd 엔진을 오버로딩한다.
    미리 연산된 역연산 trace를 생성하기 위해 자동미분을 예측한다.

  • PrimTorch : 완벽한 PyTorch 백엔드를 구축하기 위해 개에 달하는
    pytorch 연산들을 개의 기본 연산들로 canonicalize한다.

  • TorchInductor : 여러 액셀러레이터 및 백엔드용 고속 코드를 생성하는 딥러닝 컴파일러.
    NVIDIA GPU의 경우 OpenAI Triton을 주요 구성 요소로 사용함.
위의 그래프는 pytorch개발자들이 진행한 실험의 결과그래프이다.
(구체적으로 46개의 HuggingFace Transformer 모델들, 61개의 TIMM model들 그리고 56개의 TorchBench 모델들)로 실험을 진행.

[결과]:
단순히 torch.compile으로 wrapping해준 것만으로 모델 Training이 43%빠른속도로 동작했다.
(다만, 이는 A100으로 측정된 결과이고, 3090같은 시리즈는 잘 동작하지 않고 심지어 더 느릴 수 있다 언급:
Caveats: On a desktop-class GPU such as a NVIDIA 3090, we’ve measured that speedups are lower than on server-class GPUs such as A100. As of today, our default backend TorchInductor supports CPUs and NVIDIA Volta and Ampere GPUs. It does not (yet) support other GPUs, xPUs or older NVIDIA GPUs.)

이를 2.2버전에서는 좀 더 완성시킨 것이다!

pytorch개발자분들은 버전이 2.x로 넘어가면서 compile함수에 좀 더 집중한다하였다.
아마 점점 학습속도를 빠르게하는 면을 강화하고, 이를 점차 확대할 것 같다.
(이번에 저수준커널에도 적용한 걸 보면 거의 확실시 되는듯하다.)



개발동기:

17년 시작된 이후, Eager Execution성능향상을 위해 코드 대부분을 C++로 옮기게 되었다.
(Pytorch 대부분의 소스코드가 C++기반임을 근거로 알 수 있다.)
(eager execution: 그래프생성없이 연산을 즉시실행하는 환경)

이런 방식을 사용자들의 코드기여도(hackability)를 낮추는 진입장벽이 되어버렸다.
이런 eager execution의 성능향상에 한계가 있다 판단하여 compiler를 만들게 되었다.
목적은 속도는 빠르게하나 pytorch experience를 해치지 않는다는 것이다.

 

🤔 How to use?

torch.compile()은 기존 모델에 한줄만 추가하면 된다.
import torch
import torchvision.models as models

model = models.resnet18().cuda()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
compiled_model = torch.compile(model)

x = torch.randn(16, 3, 224, 224).cuda()
optimizer.zero_grad()
out = compiled_model(x)
out.sum().backward()
optimizer.step()

compiled_model은 신경망의 forward를 좀 더 최적화시켜 속도를 빠르게 한다.

def torch.compile(model: Callable,
  *,
  mode: Optional[str] = "default",
  dynamic: bool = False,
  fullgraph:bool = False,
  backend: Union[str, Callable] = "inductor",
  # advanced backend options go here as kwargs
  **kwargs
) -> torch._dynamo.NNOptimizedModule

∙ mode:

torch.compile(model)

torch.compile(model, mode="reduce-overhaed")

torch.compile(model, mode="max-autotune")
[default]:
너무 오래걸리지 않으면서 메모리를 많이 사용하지 않는 선에서 효율적인 컴파일 진행

[reduce-overhead]:
메모리를 좀 더 사용, overhead를 줄여줌

[max-autotune]:
가장 빠른 모델생성을 위해 최적화되어있다.
다만, 컴파일에 매우 오랜시간이 걸린다.


∙ dynamic:

dynamic shape에 대해 code path를 enabling할 지 결정하는 boolean 변수이다. Compiler 최적화 과정이 프로그램을 dynamic shape 프로그램에 적용될 수 없게 만드는 경우가 있는데, 이를 조절함으로써 본인이 원하는 방향대로 컴파일을 할 수 있게 해준다. 이 부분은 아직 완벽히 이해가 되지는 않지만 데이터 shape가 변하는 상황에서 graph를 유동적으로 컴파일할 수 있게끔 하는 것과 관련이 있을 것 같다.

∙ fullgraph:

Numba의 nopython과 유사하다. 전체 프로그램을 하나의 그래프로 컴파일하고, 만약 실패한다면 왜 불가능한지 설명해주는 error 메세지를 띄운다. 굳이 쓰지 않아도 상관없는 옵션.

∙ backend:

어떤 compiler backend를 적용할 지 결정하게 된다. 디폴트로 정해진 값은 앞서 설명했던 TorchInductor가 사용되지만, 다른 옵션들도 존재한다고 한다(제대로 알아보진 않았다).


❗️ 유의점:

compile된 모델 저장 시, state_dict만 저장가능하다.

∙ 아래는 가능!
torch.save(opt_model.state_dict(), "best.pt")
torch.save(model.state_dict(), "best.pt")
torch.save(model, "best.pt")


∙ 아래는 불가능!
torch.save(opt_model, "best.pt")

 

 

Compile 이후 사용가능한 기능:

 

∙ TorchDynamo

Eager Mode의 가장 용이한 점: 
학습도중 model_weight에 접근하거나 값을 그대로 읽어올 수 있다.
model.conv1.weight

TorchDynamo
는 이를 인지하고 만약 attribute가 변한것을 감지하면
자동으로 해당부분에 대한 변화를 다시 컴파일해준다.



∙ Inference

compile함수로 compiled_model을 생성한 후 warm-up step은 초반 latency를 줄여준다.
다만, 이부분도 차차 개선시킨다 하였다.
exported_model = torch._dynamo.export(model, input)
torch.save(exported_model, "foo.pt")

 

 

 

 

📊 다양한 시각화 방법

대표적으로 WandB는 학습log 시각화를 주로 사용한다.

대표적으로 다음과 같다.

  • Loss, Accuracy 그래프
  • Model parameter(gradient) 그래프
  • pred_img 시각화
  • sweep 그래프
  • Confusion Matrix
  • ROC, PR Curve

 

 

 

 

1.  Loss, Accuracy 그래프

💻 코드

wandb.log({'loss':loss}, step=epoch)
wandb.log({'val_loss': val_loss,
           'val_acc': val_accuracy })

 

📊 시각화


 

 

2.  Model parameter(gradient) 그래프

💻 코드

wandb.watch(model, criterion, log="all", log_freq=10)

log="all"을 주면 gradient와 parameter, bias를 모두 기록할 수 있다.

 

📊 시각화

 

 


3.  Pred_Img 시각화

💻 코드

ex_images.append(wandb.Image(data[0], 
                                  caption="Pred:{} Truth:{}".format(pred[0].item(), target[0])
                                  ))
  
 wandb.log({"Image": ex_images})

 

📊 시각화

cf) index바를 조절해 학습진행경과확인이 가능하다.

 


4.  sweep 그래프

💻 코드

sweep_id = wandb.sweep(sweep_config, project="mnist", entity='v2llain')
wandb.agent(sweep_id, run_sweeep, count=6)

 

📊 시각화

X축: configuration된 parameter이름

y축: 변경된 값

맨 우측: 성능측정값

 


5.  Confusion Matrix

💻 코드

sweep실행❌)

wandb.sklearn.plot_confusion_matrix(y_test, y_pred, 
                                    labels=classes_name)

 

sweep실행⭕️)

wandb.log({
      "Confusion Matrix":
      wandb.plot.confusion_matrix(preds=best_all_preds,
                                  y_true=best_all_labels,
                                  class_names=classes_name
                                  )})

 

📊 시각화

좌) sweep X.   우) sweep진행 시, 색별로 sweep구분가능.

 


6. ROC, PR Curve

💻 코드

wandb.log({'roc': wandb.plots.ROC(y_test, y_prob_pred, cnb.classes_)})
wandb.log({'pr': wandb.plots.precision_recall(y_test, y_prob_pred, cnb.classes_)})

 

📊 시각화

두 그래프 모두 상단에 위치할수록 좋은 그래프 (∵AUC가 클수록 좋기 때문.)

 

 

🧹 Sweep이란?

0. Overview

단 1%라도 성능을 올리기위해 많은 사람들이 부단한 노력을 한다. (ex. paperswithcode)

결국, 모델의 성능을 최대로 끌어올리기 위해서는 Hyper-parameter를 변경하며 최적의 값을 찾기위해 이에 대해서도 부단히 노력을 기울여야 하지만, 이는 매우 피곤하고 Cost를 많이 들게 만든다.

이를 위해 등장한 것이 바로 W&B의 Sweep이다!

 

 

 

1. Sweep이란?

기본적으로 Hyper-parameter를 자동으로 최적화주는 Tool

Hyper-parameter Seach방식으로 다음 3가지가 존재한다.

  • Grid 방식
  • Random 방식
  • Bayes 방식

선택한 search 방식으로 하이퍼 파라미터 튜닝이 완료 되면 WandB의 웹에서 제공되는 dashboard로 시각화된 모습을 볼 수 있다.

이렇게 시각화된 모습은 위의 그림과 같다. Sweep은 자동으로 tuning해주는 기능 뿐만 아니라,

각각의 hyper parameter들이 metric(accuracy, loss 등)에 얼마나 중요한 지 알려주고 상관관계를 보여주기에 필수적이라 할 수 있다.

(대시보드)

 

 

 

 

 

🧹 Sweep 사용법❗️

 

Tune Hyperparameters | Weights & Biases Documentation

Hyperparameter search and model optimization with W&B Sweeps

docs.wandb.ai

Sweep은 필히 2개의 단계(Initialize the Sweep, Run the Sweep Agent)가 필요하다.

 

 

1. Initialize the Sweep 

 ∙ Sweep Configuration를 정의

Sweep Initialize를 위해 먼저 구성요소(configuration)를 정의해야한다.

이를 위해 required와 option으로 나뉜다.

 program(어디에서) method(무엇을) parameters(어떻게)
최적화를 할 것인지 정의해야한다.

이때, 최적화 방법으로 3가지가 존재한다.
  • Grid 방식 : 가능한 모든 조합 탐색 (= Cost↑)
  • Random 방식 : random하게 선택 (= Cost↓, opt찾을확률↓)
  • Bayes 방식 : 이전에 시도한 hyper-parameter조합의 결과를 사용, 다음시도조합 추론시 사용 
    → 모델성능을 최대로 향상시킬 수 있는 hyper-parameter조합을 찾는다. (= 초기탐색이 느림)

 


이때, 특히나 parameters 파트가 중요하기에 좀 더 살펴보자.


values  value
Hyper-parameter에 대해 특정 값을 설정해서 우리가 원하는 값만 선택하게 해줌.
(value는 1가지 값을 설정해줄 때 사용)


distribution
values와 대조되는 방식.
특정 값을 설정하는 대신 원하는 분포 안에서 값을 선택.
Sweep에서는 uniform, normal, q_log_uniform과 같이 다양한 분포를 제공.
또한 선택된 분포를 min, max와 mu, sigma, q를 통해 자유롭게 변형가능.

min, max
분포의 최소∙최대값을 설정.

mu
  sigma

평균과 표준편차를 나타내는 값, 정규분포(normal)의 모양을 결정.

q

Quantization의 약자로 distribution에서 나온 값 X를 양자화.
ex) q를 2로 설정한다면 X는 2의 배수로 바뀜.
(ex. 식 round(X / q) *q를 적용하면, -2.96은 -2로 13.27은 14로 8.43은 8로 바뀜.)=

 ∙ project에 사용하기위해 Sweep API로 초기화

Sweep의 config가 제대로 정의가 됐다면 이제 프로젝트에 적용을 해줘야한다.

 

sweep 초기화 코드:

sweep_id = wandb.sweep(config.sweep_config)


위에서 정의된 config 변수를 입력으로 받고 sweep id를 출력해준다.

이 id는 다음 step에서 sweep을 실행시킬 때 고유한 identifier로 사용된다.

 

 

 

 

 

 

2. Run the Sweep Agent

  • 함수나 프로그램을 W&B서버에서 실행.

이제 본격적인 실행만이 남았다.

위에서 정의해준 configuration을 사용해 sweep을 진행하자.

 

sweep 진행코드:

wandb.agent(sweep_id, function=train, count=count)

이때, 위에서 출력된 sweep_id를 입력으로 넣어준다.

또한, function에 우리가 정의한 train함수를 넣어주고

sweep을 몇번 진행할 지 숫자를 count에 입력해준다.

성공적으로 Sweep 실행시 출력되는 화면.

 

 

 

 

 

cf). yaml 파일로 실행하는 방법.

project와 entity를 기입 가능한 곳

  • config 설정 하는 파일 (config.py 혹은 config.yaml)
  • wandb.sweep()
  • wandb.init()
  • wandb.agent()

config를 .py파일로 정의하는 방식과 .yaml파일로 정의하는 방식이 존재.yaml파일로 실행하는 방법에 대해 알아보자.


1. config.yaml 파일 생성

 

 

 

 

2. . yaml 파일, Sweep에 입력

wandb sweep config.yaml

 

 

3. Sweep id를 Agent에 입력

wandb agent SWEEP_ID

 

 

 

cf) wandb terminal에서 명령어로 지정하기.

∙ sweep 횟수 제한

wandb agent --count [LIMIT_NUM] [SWEEPID]

 

 

∙ Multi-GPU sweep 사용

CUDA_VISIBLE_DEVICES=0 wandb agent sweep_id
CUDA_VISIBLE_DEVICES=1 wandb agent sweep_id

 

 

 

 


 

 

 

🧹 W&B Sweep 실행을 위한 예시코드

from dataset import SweepDataset
from model import ConvNet
from optimize import build_optimizer
from utils import train_epoch

import wandb
import config

parser = argparse.ArgumentParser()
parser.add_argument('--batch-size', type=int, default=8, metavar='N')
parser.add_arguemnt('--epochs', type=int, default=10)                     
args = parser.parse_args()                   

wandb.config.update(args)

def train():
    wandb.init(config=config.hyperparameter_defaults)
    w_config = wandb.config

    loader = SweepDataset(w_config.batch_size, config.train_transform)
    model = ConvNet(w_config.fc_layer_size, w_config.dropout).to(config.DEVICE)
    optimizer = build_optimizer(model, w_config.optimizer, w_config.learning_rate)

    wandb.watch(model, log='all')

    for epoch in range(w_config.epochs):
        avg_loss = train_epoch(model, loader, optimizer, wandb)
        print(f"TRAIN: EPOCH {epoch + 1:04d} / {w_config.epochs:04d} | Epoch LOSS {avg_loss:.4f}")
        wandb.log({'Epoch': epoch, "loss": avg_loss, "epoch": epoch})     
        
sweep_id = wandb.sweep(config.sweep_config)
wandb.agent(sweep_id, train, count=2)

sweep을 위한 config 파일은 config.py에 구현되어 있습니다. 코드를 순서대로 설명하면 다음과 같습니다.

1. hyper parameter의 초기값을 wandb.init에 입력으로 넣어줍니다.
2. w_config는 sweep을 할 대상 hyper parameter입니다.
3. loader, model, optimizer 함수에 w_config를 매개변수로 전달해줍니다.
4. model을 정의하면 wandb.watch 함수로 gradient를 추적합니다.
5. epoch 별로 나오는 log를 wandb.log에 저장합니다.
6. config 파일에 정의해둔 구성 요소를 wandb.sweep에 입력합니다.
7. wandb.sweep에서 나온 id와 위에 구현된 train 함수, 그리고 횟수를 wandb.agent에 입력하고 sweep을 실행시킵니다.

 

참고) https://pebpung.github.io/wandb/2021/10/10/WandB-2.html

 

 

 


🧹 Sweep 시각화

WandB실행 이후, 시각화된 결과를 분석해보자. (대시보드)

이를 위해서는 Sweep workspace의 구성방식에 대해 알아봐야한다.

 

좌측 그래프: y축은 metric, X축은 생성된 날짜를 의미.

우측 표: hyper parameter가 metric(accuracy, loss 등)에 얼마나 중요한 지와 상관관계가 어느정도 인지도 알려줌.

 


 

위 그림은 hyper-parameter선택과정을 시각적으로 보여준 그림이다.

 ∙ X축: config에서 설정한 hyper-parameter의 종류

 ∙ y축: config에서 설정한 hyper-parameter의 범위

 

추가적으로 마우스를 가져다 놓으면 해당 그래프에서의 값을 알 수 있다.

📌 WandB가 왜 필요할까?

1. Model Experiment Pipeline

https://ml-ops.org/content/mlops-principles

위 그림을 보면 알 수 있듯, MLOps과정은 크게 3단계로 나뉜다.

 ∙ Project Design

 ∙ Experiment & Development

 ∙ 배포 및 운영

 

이중, 2단계인 "실험에 도움을 주는 Tool"중 하나가 바로 WandB이다.

(cf. TensorBoard도 존재.)

 

 

 

2. Configuration

ML구축을 위한 필수구성요소로 대표적인 예시는 다음과 같다.
∙ Dataset
∙ Metric
∙ Model
∙ Hyper-parameter

 

Training과정에서, 이 Configuration값을 적절하게 선택해줘야한다.

🧐 Batch size에 대하여
Data나 Model의 종류에 따라 적절한 Batch_size가 존재하기에
batch_size를 너무 작은값이나 큰값을 쓰면 오히려 학습이 잘 안되는 경향이 존재한다.

cf) 특정한 가설하에 연역적으로 증명가능할 때,
batch size를 2배 증가시키면 step size는 √2배 증가시켜야한다. 

cf) batch size를 증가시켰는데도 총 epoch수를 그대로 두면
한 epoch당 iteration수가 줄어들기에
그만큼 gradient로 parameter update를 덜 시키는 것이므로
Loss감소속도가 느려져 학습이 잘 안될 수도 있다.

그렇기에 적절한 Configuration설정은 준필수적이다.

 

특히, Dataset은 Data Augmentation

Metric은 추가하거나 교체하고, Model도 구조를 변경시키는 시간은 상대적으로 적은 시간이 들지만

 

Hyper-parameter Tuning의 경우 적절한 값을 찾기 위해서는 상당히 많은 시간을 할애해야한다.

Model의 parameter 최적화를 위해 Hyper-parameter를 적절히 조절해야하고, 이는 Hyper-parameter를 변경시키며 다양한 실험을 해야하기 때문이다.

 

이를 사람이 일일히 한다면?

즉, Hyper-parameter를 사람이 직접 일일히 tuning하는 작업은

매우 비효율적이고, 기록이 누락될수도 있고 이를 수기로 정리까지 해야하는, 

종합고민3종세트라 할 수 있겠다.

 

 

 

 

 

 

📌 WandB?

WandB(Weights & Biases)는 더 최적화된 모델을 빠른시간내에 만들 수 있게 도와주는, ML Experiment Tracking Tool이다.

주요기능

W&B Platform

  • Experiments: 머신러닝 모델 실험을 추적하기 위한 Dashboard 제공.
  • Artifacts: Dataset version 관리와 Model version 관리.
  • Tables: Data를 loging하여 W&B로 시각화하고 query하는 데 사용.
  • Sweeps: Hyper-parameter를 자동으로 tuning하여 최적화 함.
  • Reports: 실험을 document로 정리하여 collaborators와 공유.

 

 

 

📌 W&B Experiments. 함수 및 예제

모델학습 시, 모델 학습 log를 추적하여 Dashboard를 통해 시각화
이를 통해 학습이 잘 되고 있는지 빠르게 파악할 수 있다.

 

1. config setting

W&B실행을 위해 config파일이 필요하기에 

Hyper-parameter, Data명 등 학습에 필요한 구성들을 그룹화한다.

또한, 이 config파일은 sweep에 중요하게 사용된다.

config  = {
    'dataset': 'MNIST',
    'batch_size': 128,
    'epochs': 5,
    
    'architecture': 'CNN',
    'classes':10,
    'kernels': [16, 32],
    
    'weight_decay': 0.0005,
    'learning_rate': 1e-3,
    
    'seed': 42
}

 

 

 

 

 

 

2. Dataset with DataLoader

def make_loader(batch_size, train=True):
    full_dataset = datasets.MNIST(root='./data/MNIST', train=train, download=True,  transform=transforms.ToTensor())

    loader = DataLoader(dataset=full_dataset,
                        batch_size=batch_size,
                        shuffle=True, pin_memory=True, num_workers=2)
    return loader

 

 

 

 

 

3. CNN Model

class ConvNet(nn.Module):
    def __init__(self, kernels, classes=10):
        super(ConvNet, self).__init__()

        self.layer1 = nn.Sequential(
            nn.Conv2d(1, kernels[0], kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.layer2 = nn.Sequential(
            nn.Conv2d(16, kernels[1], kernel_size=5, stride=1, padding=2),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=2))
        self.fc = nn.Linear(7 * 7 * kernels[-1], classes)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out = out.reshape(out.size(0), -1)
        out = self.fc(out)
        return out

추가적으로 W&B는 모델의 weights와 bias같은 parameter를 추적할 수 있다.

이를 통해 학습 도중 weights의 histogram이나 distribution을 통해 원활한 학습방향수정이 가능하다.

 

 

 

 

 

4. Train 함수

def train(model, loader, criterion, optimizer, config):
    wandb.watch(model, criterion, log="all", log_freq=10)

    example_ct = 0
    for epoch in tqdm(range(config.epochs)):
        cumu_loss = 0
        for images, labels in loader:

            images, labels = images.to(device), labels.to(device)

            outputs = model(images)
            loss = criterion(outputs, labels)
            cumu_loss += loss.item()

            optimizer.zero_grad()
            loss.backward()

            optimizer.step()

            example_ct +=  len(images)

        avg_loss = cumu_loss / len(loader)
        wandb.log({"loss": avg_loss}, step=epoch)
        print(f"TRAIN: EPOCH {epoch + 1:04d} / {config.epochs:04d} | Epoch LOSS {avg_loss:.4f}")

wandb.log()함수를 통해 loss함수를 시각화 할 수 있음.

이때, step을 epoch으로 받아 avg_loss값을 기록하는 것을 알 수 있다.

 

wandb.watch()는 Dashboard에서 실험 log를 시각화하는 역할을 수행.

 

 

5. Run 함수

def run(config=None):
    wandb.init(project='MNIST', entity='계정명', config=config)

    config = wandb.config

    train_loader = make_loader(batch_size=config.batch_size, train=True)
    test_loader = make_loader(batch_size=config.batch_size, train=False)

    model = ConvNet(config.kernels, config.classes).to(device)
    criterion = nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=config.learning_rate)

    train(model, train_loader, criterion, optimizer, config)
    test(model, test_loader)
    return model

wandb.int()으로 wandb web서버와 연결.

 

cf) project와 entity를 기입 가능한 곳

  • config 설정 하는 파일 (config.py 혹은 config.yaml)
  • wandb.sweep()
  • wandb.init()
  • wandb.agent()

 

 

 

 

6. 결과

실험결과, 각 에폭마다 해당 Layer에 전파되는 Gradient값들을 확인할 수 있다.

추가적으로 해당 epoch에 대한 gradient distribution의 경우 마우스를 가져다 놓으면 위의 그림처럼 확인가능하다.

+ Recent posts