Data Loader(2)

pppanghyun·2022년 7월 12일
0

Pytorch 기본

목록 보기
4/21

커스텀 데이터 + 커스텀 전처리

텐서 생성 부분에서 이미지 전처리를 진행


import torch
import torchvision.transforms as tr # 이미지 전처리 기능
from torch.utils.data import DataLoader, Dataset # 데이터를 모델에 사용
import numpy as np

# 32x32 컬러 이미지와 라벨이 각각 100장이 있다고 가정
# glob -> PIL, openCV ..
train_images = np.random.randint(256,size=(100,32,32,3)) # (이미지 수)x(너비)x(높이)x(채널 수)
train_labels = np.random.randint(2,size=(100,1)) # 라벨 수

class MyDataset(Dataset):
    
    def __init__(self, x_data, y_data, transform=None):
        
        self.x_data = x_data # 넘파이 배열
        self.y_data = y_data # 넘파이 배열
        self.transform = transform
        self.len = len(y_data)
    
    def __getitem__(self, index):
        sample = self.x_data[index], self.y_data[index]
        
        if self.transform:
            sample = self.transform(sample) #self.transform이 None이 아니라면 전처리를 작업한다.
        
        return sample # tensor가 아닌 넘파이 배열로 출력
        
    def __len__(self):
        return self.len 

직접 전처리 만들기

위 기본 양식과 같이 사용하기 위해 call 함수를 사용
def __call__ 내의 원하는 전처리 작업을 프로그래밍 할 수 있음

# 1. 텐서 변환
class ToTensor:
    def __call__(self, sample):
        inputs, labels = sample
        inputs = torch.FloatTensor(inputs) # 텐서로 변환
        inputs = inputs.permute(2,0,1) # 크기 변환
        return inputs, torch.LongTensor(labels) # 텐서로 변환

# 2. 선형식    
class LinearTensor:
    
    def __init__(self, slope=1, bias=0):
        self.slope = slope
        self.bias = bias     
        
    def __call__(self, sample):
        inputs, labels = sample
        inputs = self.slope*inputs + self.bias # ax+b 계산하기
        return inputs, labels 
        
trans = tr.Compose([ToTensor(),LinearTensor(2,5)]) # 텐서 변환 후 선형식 2x+5 연산
dataset1 = MyDataset(train_images,train_labels, transform=trans)
train_loader1 = DataLoader(dataset1, batch_size=10, shuffle=True)

# ToTensor()와 tr.ToTensor()의 차이
# 앞서 사용한 tr.ToTensor()는 import torchvision.transforms as tr를 이용한 파이토치 메소드를 이용한 것
# ToTensor()는 위에서 정의 된 메소드를 사용한 것

dataiter1 = iter(train_loader1)
images1, labels1 = dataiter1.next()
print(images1.size()) # 배치 및 이미지 크기 확인

#result
torch.Size([10, 3, 32, 32])

커스텀 데이터 + torchvision.transforms 전처리

# torchvision.transforms은 제공하는 전처리 방법
# torchvision.transforms은 입력 이미지가 일반적으로 PILImage 타입이나 텐서일 경우에 동작
# 현재 데이터는 넘파이 배열. 따라서 텐서 변환 후 tr.ToPILImage()을 이용하여 PILImage 타입으로 만들어줘야함
# __call__을 이용한 기본 구조는 동일

class MyTransform:
    
    def __call__(self, sample):
        inputs, labels = sample
        inputs = torch.FloatTensor(inputs)
        inputs = inputs.permute(2,0,1)
        labels = torch.FloatTensor(labels)

        transf = tr.Compose([tr.ToPILImage(), tr.Resize(128),tr.ToTensor(),tr.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
        final_output = transf(inputs)      
        
        return final_output, labels 
        
dataset2 = MyDataset(train_images,train_labels, transform=MyTransform())
train_loader2 = DataLoader(dataset2, batch_size=15, shuffle=True)

dataiter2 = iter(train_loader2)
images2, labels2 = dataiter2.next()
print(images2.size()) # 배치 및 이미지 크기 확인

#result
torch.Size([15, 3, 128, 128])
profile
pppanghyun

0개의 댓글