본문 바로가기

Programming

[monitoring tools] wandb (weights & biases)

728x90
반응형

개념

  • 머신러닝 실험을 원활히 지원하기 위한 사용도구
  • 협업, code versioning, 실험 결과 기록 등을 제공

사용

  • 가입
    1. https://wandb.ai/home
    2. Setting → API keys 복사
    3. 새 프로젝트 생성 (Create new project)
  • 코드
import wandb
wandb.init(project='my-test-project', entity='sherryjeon') # 프로젝트명 입력

import torch
import torchvision
from torchvision import datasets, models, transforms

import torch.nn as nn
import torch.optim as optim
import os

import numpy as np
import matplotlib.pyplot as plt
DATA_PATH = "https://download.pytorch.org/tutorial/hymenoptera_data.zip"

import urllib
import os
import shutil
from zipfile import ZipFile

urllib.request.urlretrieve(DATA_PATH, "hymenoptera_data.zip")

with ZipFile("hymenoptera_data.zip", 'r') as zipObj:
  zipObj.extractall()
  
  
  
data_dir = "./hymenoptera_data"

# custom transform to flatten the image tensors
class ReshapeTransform:
  def __init__(self, new_size):
    self.new_size = new_size

  def __call__(self, img):
    result = torch.reshape(img, self.new_size)
    return result

  
data_transforms = {
    'train': transforms.Compose([
        transforms.Resize(224),
        transforms.CenterCrop(224),
        transforms.ToTensor()
    ]),
    'val': transforms.Compose([
        transforms.Resize(224),
        transforms.CenterCrop(224),
        transforms.ToTensor()
    ])
}


# load the corresponding folders
#(ImageFolder : 계층적인 폴더구조를 가지고 있는 데이터를 불러올 때 사용할 수 있음 => 각 데이터가 
# 본인 레이블 폴더안에 들어있는 경우)
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x])
for x in ['train', 'val']}

# load the entire dataset
train_dataset = torch.utils.data.DataLoader(image_datasets['train'],
                                            batch_size=len(image_datasets['train']),
                                            shuffle=True)

모델 정의

class MyCNNModel(nn.Module):
  def __init__(self):
    super(MyCNNModel, self).__init__()
    self.layer1 = nn.Sequential(
        nn.Conv2d(3, 16, kernel_size=3, stride=2, padding=0),
        nn.BatchNorm2d(16),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )
    self.layer2 = nn.Sequential(
        nn.Conv2d(16, 32, kernel_size=3, stride=2, padding=0),
        nn.BatchNorm2d(32),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.layer3 = nn.Sequential(
        nn.Conv2d(32, 64, kernel_size=3, stride=2, padding=0),
        nn.BatchNorm2d(64),
        nn.ReLU(),
        nn.MaxPool2d(kernel_size=2, stride=2)
    )

    self.drop_out = nn.Dropout()
    self.fc1 = nn.Linear(3*3*64, 1000)
    self.fc2 = nn.Linear(1000, 1)

  def forward(self, x):
    out = self.layer1(x)
    out = self.layer2(out)
    out = self.layer3(out)

    out = out.view(out.size(0), -1)
    out = self.drop_out(out)
    out = self.fc1(out)
    out = self.fc2(out)
    return out

학습을 위한 파라미터 설정

def binary_acc(y_pred, y_test):
  y_pred_tag = torch.round(torch.sigmoid(y_pred))
  correct_result_sum = (y_pred_tag==y_test).sum().float()
  acc = correct_result_sum/y_test.shape[0]
  acc = torch.round(acc * 100)
  return acc

EPOCHS = 100
BATCH_SIZE = 64
LEARNING_RATE = 0.01

config = {"epoch":EPOCH, "batch_size":BATCH_SIZE, "learning_rate":LEARNING_RATE}

model = MyCNNModel()

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)

criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)

wandb 설정 및 학습

wandb.init(project="my-test-project", config=config)

for e in range(1, EPOCH+1):
  epoch_loss = 0
  epoch_acc = 0
  for X_batch, y_batch in train_dataset:
    X_batch, y_batch = X_batch.to(device), y_batch.to(device).type(torch.cuda.FloatTensor)
    optimizer.zero_grad()
    y_pred = model(X_batch)

    loss = criterion(y_pred, y_batch.unsqueeze(1))
    acc = binary_acc(y_pred, y_batch.unsqueeze(1))

    loss.backward()
    optimizer.step()

    epoch_loss += loss
    epoch_acc += acc

  train_loss = epoch_loss / len(train_dataset)
  train_acc = epoch_acc/ len(train_dataset)

  print(f"Epoch {e:03} : | Loss : {train_loss: .5f} | ACC: {train_acc: .3f}")
  wandb.log({"accuracy": train_acc, "loss": train_loss})

결과

728x90
반응형