국문과 유목민

[일일리포트] Day 07 본문

IT 견문록/2022_부스트캠프 AITech 3기(100일)

[일일리포트] Day 07

논곰 2022. 1. 25. 23:27

해당 일일리포트에서는 네이버 커넥트에서 진행하는 '부스트캠프 AI Tech 3기'에서 배운 내용을 다루고 있습니다. 저작권 이슈 때문에 관련 자료를 올릴 수 없어, 핵심 이론과 코드 위주로 정리하고 있기에 내용이 부족할 수 있습니다. 감사합니다.

▶ Today I Learned (핵심 요약 정리)

Autograd and Optimizer

Basic

  • Layer: 딥러닝 모델을 구성하는 기본 단위이며, 뉴런과 가중치(weight), 바이어스(bias)로 구성된다.
    • 딥러닝을 큰 레고로 정의할 때, 레고 블록 하나를 layer라고 볼 수 있다. 이 layer들을 모아서 연결하고, 연산하고, 역전 파하는 과정을 딥러닝이라고 할 수 있다.
    • Layer들을 쌓아서 블록을 만들고, 그 블록을 다른 layer 안에 넣을 수도 있다.
  • torch.nn.Module: pytorch에서 딥러닝을 구성하는 Layer의 base class이다.
    • input, output, forward, backward가 정의되며, 학습의 대상이 되는 parameter(tensor)도 정의한다.
  • nn.Parameter: nn.Module 내에 attribute가 될 때는 required_grad=True로 지정되어 학습 대상이 되는 Tensor (AutoGrad) 우리가 직접 지정할 일은 잘 없으며, 대부분의 layer에는 weigths의 값이 이미 지정되어 있다.
class BaseLinear(nn.Module):
    def __init__(self, in_features, out_features, bias=True): ## feature의 개수를 맞춰줘야 한다.
        super().__init__()
        self.in_features = in_features
        self.out_features = out_features
        
        # 보통은 Parameter까지 정의할 일은 많이 없다.
        self.weights = nn.Parameter(
                torch.randn(in_features, out_features))
        
        self.bias = nn.Parameter(torch.randn(out_features))

    def forward(self, x : Tensor): # x @ w + b
        return x @ self.weights + self.bias
  • backward: Layer에 있는 parameter들의 미분을 수행한다
    • forward의 결과값과 실제값 간의 차이에 대해 자동으로 미분을 수행하며, 해당 값으로 파라미터 업데이트
  • 모델 프로세스: 파이토치의 딥러닝 모델은 간단하게 아래와 같은 프로세스로 진행된다. 
import numpy as np

# 1) 초기 데이터 생성
x_values = [i for i in range(11)]
x_train = np.array(x_values, dtype=np.float32)
x_train = x_train.reshape(-1, 1)

y_values = [2*i + 1 for i in x_values]
y_train = np.array(y_values, dtype=np.float32)
y_train = y_train.reshape(-1, 1)

# 2) 모델 정의 (선형회귀 모델 예시)
import torch
from torch.autograd import Variable
class LinearRegression(torch.nn.Module):
    def __init__(self, inputSize, outputSize):
        super(LinearRegression, self).__init__()
        self.linear = torch.nn.Linear(inputSize, outputSize) # LinearRegression
        
    def forward(self, x):
        out = self.linear(x)
        return out
        
# 3) 모델 객체 생성 및 설정
inputDim = 1        # takes variable 'x' 
outputDim = 1       # takes variable 'y'
learningRate = 0.01 
epochs = 100
model = LinearRegression(inputDim, outputDim)
if torch.cuda.is_available(): # GPU 사용
    model.cuda()
    
# 4) 변수설정 (loss, optimizer)
criterion = torch.nn.MSELoss() 
optimizer = torch.optim.SGD(model.parameters(), lr=learningRate) # optimizer에 관한 함수, 모델 및 대상 지정

# 5) 모델 학습
for epoch in range(epochs):
    # Converting inputs and labels to Variable
    if torch.cuda.is_available():
        inputs = Variable(torch.from_numpy(x_train).cuda())
        labels = Variable(torch.from_numpy(y_train).cuda())
    else:
        inputs = Variable(torch.from_numpy(x_train))
        labels = Variable(torch.from_numpy(y_train))

    # Backward단계에서는 아래와 같은 4개의 과정이 반드시 일어난다. 
    # [1] zero_grad: 이전의 그레디언트 값이 이번 그레디언트 계산에 영향을 주지 않게 하기 위해
    optimizer.zero_grad()

    # [2] y^값: 주어진 input에 대한 예측값
    outputs = model(inputs)

    # [3] 예측된 값에 대한 loss 계산
    loss = criterion(outputs, labels)
    print(loss)
    # [4] 그레디언트 계산_자동 미분 (t gradients w.r.t to parameters)
    loss.backward()

    # update parameters
    optimizer.step()
    print('epoch {}, loss {}'.format(epoch, loss.item()))
  • Backward from the scratch:
    • 실제 backward는 Module 단계에서 직접 지정가능하며, Module에서 backward와 optimizer를오버라이딩할 수 있다.
    • optimizer와 backward는 아래와 같이 이해하면된다.
      • optimize는 업데이트가 일어난다.
      • backward는 미분이 일어난다. 

Datasets & Dataloaders

모델에 데이터를 넣어주는 과정: $Data > DataSet > DataLoader > Model$

  • Dataset: '__init__()', '__len__()', '__getitem__()'
    • 데이터 입력 형태를 정의하는 클래스이며, 데이터를 입력하는 방식의 표준화(Image, Text, Audio 등)에 따른 다른 입력을 정의한다.
    • 데이터 형태에 따라서 각 함수를 다르게 정의해야 하지만, 반드시 데이터 생성 시점에 처리할 필요는 없다.
      • ex. Image의 Tensor Transform은 학습 필요 시점에 변환
      • Transforms: Dataset에 들어가기 전에 이미지를 텐서로 바꾸는 등의 작업을 한다.
  • DataLoader: Model에 넣어주기 전에 Dataset을 만들어서 넣어주는 것
    • Dataset의 Batch를 생성이나 학습 직전에 데이터의 변환을 책임지는 클래스이다.
      • Tensor로 변환, Batch 처리가 메인 업무이다.
    • DataLoader에는 다양한 매개변수가 존재한다.
      • sampler & batch_sampler: sampler는 index를 컨트롤하는 방법으로, 데이터의 index를 원하는 방식대로 조정한다. index를 컨트롤하기 때문에 shuffle 파라미터는 False(기본값)여야 한다. 다음과 같이 미리 정의된 Sampler를 활용할 수 있다.
      • [SequentialSampler, RandomSampler, SubsetRandomSampler, WeigthRandomSampler, BatchSampler, DistributedSampler ]
      • DataLoader의 매개변수: https://subinium.github.io/pytorch-dataloader/ 
  • collate_fn: map-style 데이터셋에서 sample list를 batch 단위로 바꾸기 위해 필요한 기능. zero-padding이나 Variable Size 데이터 등 데이터 사이즈를 맞추기 위해 많이 사용하는데, 특히 시퀀스형 데이터를 다룰 때 사용한다.

기본과제 (Custom Model 제작)

기본과제의 경우 코드나 문제보다는 참고한 사이트와 기억해야 하는 부분들에 대해서 정리합니다.

Containers: https://pytorch.org/docs/stable/nn.html#containers

# Containers
class Add(nn.Module):
	def __init__(self, value):
    	pass
	def forward(self, x):
    	pass

# Sequential
nn.Sequential(Add(3), Add(2), Add(5))

# ModuleList
class Calculator(nn.Module):
    def __init__(self):
        super().__init__()
        self.add_list = nn.ModuleList([Add(2), Add(3), Add(5)])

# ModuleDict
class Calculator(nn.Module):
    def __init__(self):
        super().__init__()
        self.add_dict = nn.ModuleDict({'add2': Add(2),
                                       'add3': Add(3),
                                       'add5': Add(5)})
  • extra_repr() 사용방법: Module안에 새로 함수를 정의해줘야 한다.
class Function_repr(nn.Module):
    def __init__(self, name):
        super().__init__()
        self.name = name
	# Definition
    def extra_repr(self):
      return f"name={self.name}"
    def forward(self, x):
    	pass

▶ Review (생각)

 오늘은 어제에 이어 기본과제 1을 다 끝내고, 2챕터 강의를 다 들었다. 이렇게 써놓고보니 별로 공부하지 않은 것처럼 보이는데 기본과제 1의 양이 상당했다. 그만큼 배운 내용도 많았던 것 같고, 파이토치의 기본을 너무 깊이 들어가서 나중에는 다른 강의에서의 코드가 비교적 쉽다(?)고 느껴질 정도였던 것 같다. 과제 1과 2챕터를 다 끝내고 과제 2와 3챕터 강의를 어느 정도 들었는데, 강의를 다 듣고, 과제를 수행하는 것도 괜찮을 것 같다는 생각이 들었다. 강의와 과제가 서로 상호보완적인 것 같아서 생각해볼 필요가 있을 것 같다.

 

 과제를 풀면서 항상 느끼고 있는 것은 강의를 통해 개념적으로 아는 것과 실제 주어진 문제를 직접 구현하는 것은 확실히 다르다는 것이다. 모듈의 흐름을 익히고, hook이나 apply 등의 기법을 배우는 과정은 직접 구현하면서 하지 않았다면 이해하기 힘들었을 것 같다. '현재 과제 중에서 이게 과연 쓰일까?' 라는 생각이 드는 부분도 있기는 하지만 결국 누군가는 사용할 것들이고, 프레임워크를 다루는 입장에서 다른 사람의 코드를 접할 일이 많기에 언젠가는 마주칠 것 같기도 하다. 결국 현재 주어진 문제를 충실히 해내야겠다는 결론을 내릴 수밖에 없다.

 

아무튼 내일은 기본과제2를 끝내고, 강의를 다 들은 후 심화과제를 건드려봐야겠다. 

'IT 견문록 > 2022_부스트캠프 AITech 3기(100일)' 카테고리의 다른 글

[일일리포트] Day 09  (0) 2022.01.26
[일일리포트] Day 08  (0) 2022.01.26
[일일리포트] Day 06  (0) 2022.01.24
[1주차] 학습 정리 및 회고  (0) 2022.01.21
[일일리포트] Day 05  (0) 2022.01.21
Comments