부스트캠프 AI Tech 2기 - 12
torch.nn.Module
딥러닝을 구성하는 Layer의 Base class
Input, Output. Forward, Backward 정의
학습의 대상이 되는 parameter(tensor) 정의
torch.nn.Parameter
Tensor 객체의 상속 객체
nn.Module 내에 attribute가 될 때는 required_grad=True로 지정되어 학습 대상이 되는 Tensor
우리가 직접 지정할 일은 잘 없음
: 대부분의 layer에는 weight 값들이 지정되어 있음
class MyLiner(nn.Module):
def __init__(self, in_features, outfeatures, bias=True):
super().__init__()
self.in_features = in_feartures
self.out_features = out_features
self.weights = nn.Parameter(
torch.rand(infeatures, out_featrues))
self.bias = nn.Parameter(torch.randn(out_features))
def forward(self, x : Tensor):
return x @ self.weights + self.bias
Backward
Layer에 있는 Parameter들의 미분을 수행
Forward의 결과값 (model의 output = 예측치) 과 실제값간의 차이(loss) 에 대해 미분을 수행
해당 값으로 Parameter 업데이트
for epoch in range(epochs):
# Clear gradient buffers because we don't want any gradient from previous epoch to carry forward
optimizer.zero_grad()
# get output from the model, given the inputs
outputs = model(inputs) # y^
# get loss for the predicted output
loss = criterion(outputs, labels) # y^ , y
print(loss)
# get gradient w.r.t to parameters
loss.backward()
# update paramteters
optimizer.step()
Backward from the scratch
실제 backward는 module 단계에서 직접 지정가능
Module에서 backward 와 optimizer 오버라이딩
사용자가 직접 미분 수식을 써야하는 부담
-> 쓸일은 없으나 순서는 이해할 필요는 있음
데이터를 모델에 입력하는 방법
Dataset 클래스
데이터 입력 형태를 정의하는 클래스
데이터를 입력하는 방식의 표준화
Image, Text, Audio 등에 따른 다른 입력 정의
import torch
from torch.utils.data import Dataset
class CustomDataset(Dataset):
def __init__(self, text, labels):
self.labels = labels
self.data = text
def __len__(self):
return len(self.labels)
def __getitem__(self, idx):
label = self.labels[idx]
text = self.data[idx]
sample = {"Text" : text, "Class":label}
return sample
Data set 클래스 생성시 유의점
데이터 형태에 따라 각 함수를 다르게 정의함
모든 것을 데이터 생성 시점에 처리할 필요는 없음
: image의 Tensor 변화는 학습에 필요한 시점에 변환데이터 셋에 대한 표준화된 처리방법 제공 필요
-> 후속 연구자 또는 동료에게는 빛과 같은 존재최근에는 HuggingFace 등 표준화된 라이브러리 사용
DataLoader 클래스
Data의 Batch를 생성해주는 클래스
학습 직전(GPU feed전) 데이터의 변환을 책임
Tensor 로 변환 + Batch 처리가 메인 업무
병렬적인 데이터 전처리 코드의 고민 필요
text = ['Happy','Amazing','Sad','Unhappy','Glum']
labels = ['positive','positive','negative','negative','negative']
Mydattaset = CustomDataset(text,labels)
MyDataLoader = DataLoader(MyDataset, batch_size=2, shuffle=True)
next(iter(MyDataLoader))
# {'Text':['Glum','Sad'],'Class':['negative','negative']}
MydataLoader = DataLoader(Mydataset, batch_size=2, shuffle=True)
for dataset in MyDataLoader:
print(dataset)
# {'Text':['Glum','Unhappy'], 'Class':['negative','negative']}
# {'Text':['Sad','Amazing'], 'Class':['negative','positive']}
# {'Text':['happy'], 'Class':['positive']}
DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,
batch_sampler=None, num_workers=0, colaate_fn=None,
pin_memory=False, drop_last=False, timeout=0,
worker_init_fn = None, *, prefetch_factor=2,
persistent_workers = False)
Casestudy
데이터 다운로드부터 loader까지 직접 구현해보기
NotMNIST 데이터의 다운로드 자동화 도전