PyTorch 데이터 커스터마이징

IngCoding·2022년 6월 16일
1

머신러닝

목록 보기
12/34

1. 미니 배치와 배치 크기

  • 데이터가 너무 큰 경우 작은 단위(미니 배치)로 나누어 학습
  • 여러 미니배치를 학습해 전체 데이터 학습이 1회 끝나면 1에포크(Epoch)가 끝나게 됨
  • 전체 데이터에 경사하강법을 수행하면'배치 경사 하강법', 미니 배치 단위로 하면 '미니 배치 경사 하강법'이라고 부름
  • 이터레이션 : 전체 데이터가 2,000 일 때 배치크기를 200으로 한다면 이터레이션은 총 10개
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import TensorDataset # 텐서데이터셋
from torch.utils.data import DataLoader # 데이터로더 (미니배치, 셔플, 병렬처리 가능)
x_train  =  torch.FloatTensor([[73,  80,  75], 
                               [93,  88,  93], 
                               [89,  91,  90], 
                               [96,  98,  100],   
                               [73,  66,  70]])  
y_train  =  torch.FloatTensor([[152],  [185],  [180],  [196],  [142]])
dataset = TensorDataset(x_train, y_train)
# 데이터로더 사용 (보통 batch_size는 2의 배수로, shuffle은 ture 사용)
# shuffle은 문제 순서를 랜덤으로 해서 문제보단 순서에 익숙해지는 것을 방지
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
model = nn.Linear(3,1) # 모델
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5) # 옵티마이저
nb_epochs = 20 # 에폭을 늘리면 Cost가 더 작아질 수도 있음
for epoch in range(nb_epochs + 1):
    for batch_idx, samples in enumerate(dataloader):
    # print(batch_idx)
    # print(samples)
        x_train, y_train = samples
        # H(x) 계산
        prediction = model(x_train)

        # cost 계산
        cost = F.mse_loss(prediction, y_train)

        # cost로 H(x) 계산
        optimizer.zero_grad()
        cost.backward()
        optimizer.step()

        if epoch % 5 == 0: # 5번마다 로그 출력
               print('Epoch {:4d}/{} Batch {}/{} Cost: {:.6f}'.format(
        epoch, nb_epochs, batch_idx+1, len(dataloader),
        cost.item()
        ))
Epoch    0/20 Batch 1/3 Cost: 2.637822
Epoch    0/20 Batch 2/3 Cost: 2.769465
Epoch    0/20 Batch 3/3 Cost: 0.987163
Epoch    5/20 Batch 1/3 Cost: 2.294036
Epoch    5/20 Batch 2/3 Cost: 2.152998
Epoch    5/20 Batch 3/3 Cost: 5.632655
Epoch   10/20 Batch 1/3 Cost: 2.742777
Epoch   10/20 Batch 2/3 Cost: 2.669617
Epoch   10/20 Batch 3/3 Cost: 0.489590
Epoch   15/20 Batch 1/3 Cost: 0.765782
Epoch   15/20 Batch 2/3 Cost: 3.040927
Epoch   15/20 Batch 3/3 Cost: 4.324440
Epoch   20/20 Batch 1/3 Cost: 1.829746
Epoch   20/20 Batch 2/3 Cost: 4.514516
Epoch   20/20 Batch 3/3 Cost: 2.241494
# 임의의 입력 [73, 80, 75]를 선언
new_var =  torch.FloatTensor([[73, 80, 75]]) 
# 입력한 값 [73, 80, 75]에 대해서 예측값 y를 리턴받아서 pred_y에 저장
pred_y = model(new_var) 
print("훈련 후 입력이 73, 80, 75일 때의 예측값 :", pred_y) 
훈련 후 입력이 73, 80, 75일 때의 예측값 : tensor([[151.6705]], grad_fn=<AddmmBackward0>)

2. 커스텀 데이터셋

#### 커스텀 데이터셋 기본골격 
# torch.utils.data.Dataset 상속받은 뒤 커스터마이징
class CustomDataset(torch.utils.data.Dataset): 
    def __init__(self):
    데이터셋의 전처리를 해주는 부분

    def __len__(self):
    데이터셋의 길이., 총 샘플의 수를 적어주는 부분

    def __getitem__(self, idx): 
    데이터셋에서 특정 1개의 샘플을 가져오는 함수

커스텀 데이터셋(Custom Dataset)으로 선형 회귀 구현

import torch
import torch.nn.functional as F
from torch.utils.data import Dataset
from torch.utils.data import DataLoader
# Dataset 상속
class CustomDataset(Dataset): 
  def __init__(self):
    self.x_data = [[73, 80, 75],
                   [93, 88, 93],
                   [89, 91, 90],
                   [96, 98, 100],
                   [73, 66, 70]]
    self.y_data = [[152], [185], [180], [196], [142]]

  # 총 데이터의 개수를 리턴
  def __len__(self): 
    return len(self.x_data)

  # 인덱스를 입력받아 그에 맵핑되는 입출력 데이터를 파이토치의 Tensor 형태로 리턴
  def __getitem__(self, idx): 
    x = torch.FloatTensor(self.x_data[idx])
    y = torch.FloatTensor(self.y_data[idx])
    return x, y
dataset = CustomDataset()
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
model = torch.nn.Linear(3,1)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5) 
nb_epochs = 20
for epoch in range(nb_epochs + 1):
  for batch_idx, samples in enumerate(dataloader):
    # print(batch_idx)
    # print(samples)
    x_train, y_train = samples
    # H(x) 계산
    prediction = model(x_train)

    # cost 계산
    cost = F.mse_loss(prediction, y_train)

    # cost로 H(x) 계산
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()
    
    
    if epoch % 5 == 0: # 5번마다 로그 출력
        print('Epoch {:4d}/{} Batch {}/{} Cost: {:.6f}'.format(
            epoch, nb_epochs, batch_idx+1, len(dataloader),
            cost.item()
            ))
Epoch    0/20 Batch 1/3 Cost: 5813.212891
Epoch    0/20 Batch 2/3 Cost: 2100.857422
Epoch    0/20 Batch 3/3 Cost: 310.679901
Epoch    5/20 Batch 1/3 Cost: 3.192920
Epoch    5/20 Batch 2/3 Cost: 2.133197
Epoch    5/20 Batch 3/3 Cost: 3.113661
Epoch   10/20 Batch 1/3 Cost: 3.035672
Epoch   10/20 Batch 2/3 Cost: 2.492183
Epoch   10/20 Batch 3/3 Cost: 4.437047
Epoch   15/20 Batch 1/3 Cost: 3.557247
Epoch   15/20 Batch 2/3 Cost: 2.481020
Epoch   15/20 Batch 3/3 Cost: 2.758196
Epoch   20/20 Batch 1/3 Cost: 3.123384
Epoch   20/20 Batch 2/3 Cost: 3.331470
Epoch   20/20 Batch 3/3 Cost: 0.357248
profile
Data & PM

0개의 댓글