네이버 부스트캠프/LEVEL-1

[부스트캠프][WK03 / Day13] PyTorch 구조 학습하기 2

1. 강의 내용

모델 불러오기 (최성철 교수님)

1) model.save()

  • 학습의 결과를 저장하기 위한 함수
  • 모델 형태(architecture)와 파라미터를 저장
  • 모델 학습 중간 과정의 저장을 통해 최선의 결과모델을 선택
  • 만들어진 모델을 외부 연구자와 공유하여 학습 재연성 향상
# state_dict: 모델의 파라메터를 표시
print("Model's state_dict:")
for param_tensor in model.state_dict():
    print(param_tensor, "\t", model.state_dict()[param_tensor].size())

# 모델의 파라메터를 저장
torch.save(model.state_dict(), os.path.join(MODEL_PATH, "model.pt"))


# 같은 모델의 형태에서 파라메터만 load
new_model = TheModelClass()
new_model.load_state_dict(torch.load(os.path.join(MODEL_PATH, "model.pt")))

# 모델의 architecture와 함께 저장
torch.save(model, os.path.join(MODEL_PATH, "model.pt"))
# 모델의 architecture와 함께 load
model = torch.load(os.path.join(MODEL_PATH, "model.pt"))

2) checkpoints

  • 학습의 중간 결과를 저장하여 최선의 결과를 선택
  • earlystopping 기법 사용시 이전 학습의 결과물을 저장
  • loss와 metric 값을 지속적으로 확인 저장
  • 일반적으로 epoch, loss, metric을 함께 저장하여 확인
  • colab에서 지속적인 학습을 위해 필요
torch.save({
    'epoch': e, # 모델의 정보를 epoch과 함께 저장
    'model_state_dict': model.state_dict(),
    'optimizer_state_dict': optimizer.state_dict(),
    'loss': epoch_loss,
    }, f"saved/checkpoint_model_{e}_{epoch_loss/len(dataloader)}_{epoch_acc/len(dataloader)}.pt")


checkpoint = torch.load(PATH)
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']
loss = checkpoint['loss']

3) pretrained model Transfer learning

  • 다른 데이터셋으로 만든 모델을 현재 데이터에 적용
  • 일반적으로 대용량 데이터셋으로 만들어진 모델의 성능이 높음
  • 현제의 DeepLearning에서는 가장 일반적인 학습 기법
  • backbone architecture가 잘 학습된 모델에서 일부분만 변경하여 학습을 수행함
vgg = models.vgg16(pretrained=True).to(device) # vgg16 모델을 vgg에 할당하기

class MyNewNet(nn.Module):   
    def __init__(self):
        super(MyNewNet, self).__init__()
        self.vgg19 = models.vgg19(pretrained=True)
        self.linear_layers = nn.Linear(1000, 1)
        # 모델에 마지막 Linear Layer 추가

    # Defining the forward pass    
    def forward(self, x):
        x = self.vgg19(x)        
        return self.linear_layers(x)

# 마지막 레이어를 제외하고 frozen        
for param in my_model.parameters():
    param.requires_grad = False
for param in my_model.linear_layers.parameters():
    param.requires_grad = True

Freezing
pretrained model을 활용시 모델의 변경되면 안되는 일부분을 frozen 시키는 방법


Monitoring tools for PyTorch (최성철 교수님)

1) Tensorboard

  • TensorFlow의 프로젝트로 만들어진 시각화 도구
  • 학습 그래프, metric, 학습 결과의 시각화 지원
  • PyTorch도 연결 가능 -> DeepLearning 시각화 핵심 도구

구성요소

  • scalar : metric 등 상수 값의 연속(epoch)을 표시
  • graph : 모델의 computational graph 표시
  • histogram : weight 등 값의 분포를 표현
  • Image, Text : 예측 값과 실제 값을 비교 표시
  • mesh : 3d 형태의 데이터를 표현하는 도구
# Tensorboard 기록을 위한 directory 생성
import os
logs_base_dir = "logs"
os.makedirs(logs_base_dir, exist_ok=True)

# 기록 생성 객체 SummaryWriter 생성
from torch.utils.tensorboard import SummaryWriter
import numpy as np

# add_scalar: scalar 값을 기록
# Loss/train: loss category 안에 있는 train 값
# n_iter: x축의 값
# 실험프로젝트명/실험이름
exp  = f"{logs_base_dir}/ex3"
writer = SummaryWriter(exp)
for n_iter in range(100):
    writer.add_scalar('Loss/train', np.random.random(), n_iter)
    writer.add_scalar('Loss/test', np.random.random(), n_iter)
    writer.add_scalar('Accuracy/train', np.random.random(), n_iter)
    writer.add_scalar('Accuracy/test', np.random.random(), n_iter)
writer.flush() # 값 기록 (disk에 쓰기)

# jupyter 상에서 tensorboard 수행
%load_ext tensorboard
# 파일 위치 지정(logs_base_dir)
%tensorboardtensorboard-- logdirlogdir{logs_base_dir dir}
# 같은 명령어를 콘솔에서도 사용가능

2) weight & biases

  • 머신러닝 실험을 원활히 지원하기 위한 상용도구
  • 협업, code versioning, 실험 결과 기록 등 제공
  • MLOps의 대표적인 툴로 저변 확대 중
# config 설정
config={"epochs": EPOCHS, "batch_size": BATCH_SIZE, "learning_rate" : LEARNING_RATE}

wandb.init(project="my-test-project", config=config)
# wandb.config.batch_size = BATCH_SIZE
# wandb.config.learning_rate = LEARNING_RATE
# config={"epochs": EPOCHS, "batch_size": BATCH_SIZE, "learning_rate" : LEARNING_RATE}

for e in range(1, EPOCHS+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()        
        # ...

        loss.backward()
        optimizer.step()

        epoch_loss += loss.item()
        epoch_acc += acc.item()


    train_loss = epoch_loss/len(train_dataset)
    train_acc = epoch_acc/len(train_dataset)
    print(f'Epoch {e+0:03}: | Loss: {train_loss:.5f} | Acc: {train_acc:.3f}')

    wandb.log({'accuracy': train_acc, 'loss': train_loss})

2. 과제 수행 과정 / 결과물 정리

Custom Dataset 및 DataLoader 생성 과제를 마무리했습니다.
Iris, MNIST, Titanic, AG_NEWS 데이터셋을 직접 구현하고 테스트 했습니다. 이 중 AG_NEWS 데이터셋을 구현하며 encoder와 decoder를 구현하는데 어려움을 겪었지만 마무리해서 제출했습니다.


3. 피어세션 정리

피어세션: https://hackmd.io/bVf-ouk_QY-cwpQVKP_91Q?view
멘토링: https://hackmd.io/8HofGOb2TU6OuyeveeurpQ?view


4. 학습 회고

평소 애써 무시했던 파이토치의 구현 문제에 대해 돌아보고 앞으로 꾸준히 공부해나가야 겠다는 생각이 듭니다. 아직 부덕이의 custom model 제작 과정을 완벽히 돌아보지 못해 앞으로 답을 채우고 공부해 나갈 생각을 하니 설레네요 ㅎㅎ

 

모델을 저장하고, 로그를 기록하며 transfer learning을 하는 등의 학습과정에서 필수적인 요소들을 정확히 정립하였습니다. 또한 Monitoring tools인 tensor board와 wandb를 활용해 학습 과정을 손쉽게 시각화해 보는 기능을 알게되었습니다.