인공지능/파이토치

파이토치 무작정 시작하기 3 - 데이터 불러오기

해피밀세트 2020. 7. 14. 23:18
반응형

 

 

 

 

 

 

 

https://www.youtube.com/watch?v=8PnxJ3s3Cwo

 

# 라이브러리 불러오기
# torchvision.transforms : 데이터를 불러오면서 바로 전처리를 할 수 있게 해준다.
# DataLoader : 배치사이즈 형태로 만들어서 실제로 학습할때 이용할 수 있는 형태로 만든다.
# Dataset : 튜닝할때 사용

 

import torch

import torchvision

import torchvision.transforms as tr

from torch.utils.data import DataLoader, Dataset

import numpy as np

 

 

1. 파이토치 제공 데이터 사용

 

# 데이터 전처리
# tr.Compose()안의 순서대로 전처리 작업 수행
# 인풋데이터 8*8로 사이즈 조정 ->
텐서 데이터로 변환

transf = tr.Compose([tr.Resize(8),tr.ToTensor()])

 

# 파이토치에서 제공하는 데이터 불러오기
# root  : 데이터 경로 설정
# train : train 데이터셋으로 사용할것인지
# download : 데이터 다운로드
# transform :
데이터 전처리 작업내용 불러오기

trainset = torchvision.datasets.CIFAR10(root='C:/pypy', train=True, download=True, transform=transf)

testset = torchvision.datasets.CIFAR10(root='C:/pypy', train=False, download=True, transform=transf)

# train 데이터셋의 사이즈 확인
# 채널 3 , 이미지 8*8 사이즈

 

trainset[0][0].size()

# 배치 형태로 변환
# batch_size : 배치 크기 설정
# num_workers : 데이터를 불러올때 subprocess를 몇개 사용할 것인지 (에러가 나면 0으로 설정)

 

trainloader = DataLoader(trainset, batch_size=50, shuffle=True, num_workers=2)

testloader = DataLoader(testset, batch_size=50, shuffle=True, num_workers=2)

 

# 데이터 길이 학인
# 50000개의 CIFAR 데이터를 배치사이즈 50으로 나눴기 때문에 배치가 1000개라는 뜻

 

len(trainloader)

# trainloader안의 실제값 확인
# 데이터를 하나씩 불러온다.
# torch.Size([배치사이즈, 채널수, 이미지 너비, 이미지 높이
])

dataiter = iter(trainloader)

images, labels = dataiter.next()

images.size()

 

 

 

2. 같은 클래스 별 폴더 이미지 데이터 이용

 

# 이미지가 클래스별로 폴더에 분류되었을 경우
# ImageFolder 를 사용하면 class안에 있는 이미지들을 알아서 찾아주고, 각각의 폴더로 레이블링을 자동으로 해줌

 

transf = tr.Compose([tr.Resize(16), tr.ToTensor()])

trainset = torchvision.datasets.ImageFolder(root="C:/class", transform=transf)

trainloader = DataLoader(trainset, batch_size=1, shuffle=False, num_workers=2)

print(len(trainloader))

# train 데이터셋의 사이즈 확인

trainset[0][0].size()

 

 

 

3. 개인 데이터 사용 (2 types)

 

# import preprocession

 

train_images = np.random.randint(256, size=(20,32,32,3))

train_labels = np.random.randint(2, size=(20,1))

print(train_images.shape, train_labels.shape)

# Dataset을 상속받을 클래스 만들기 (TensorData)

 

class TensorData(Dataset):

    def __init__(self, x_data, y_data):

        self.x_data = torch.FloatTensor(x_data)

        # 들어온 데이터의 형식 바꾸기

        self.x_data = self.x_data.permute(0,3,1,2) # 이미지 개수, 채널 수, 이미지 너비, 높이

        self.y_data = torch.LongTensor(y_data)

        self.len = self.y_data.shape[0]

   

    # x,y를 튜플형태로 바깥으로 내보내기

    def __getitem__(self, index):

        return self.x_data[index], self.y_data[index]

   

    def __len__(self):

        return self.len

 
# 인스터스 생성

train_data = TensorData(train_images, train_labels)
train_loader = DataLoader(train_data, batch_size=10, shuffle=True)
 
# 데이터 사이즈 확인

train_data[0][0].size()

# train_loader안의 실제값 확인

 

dataiter = iter(train_loader)

images, labels = dataiter.next()

images.size()

torchvision.datasets.ImageFolder를 쓰지 않는 이유

  • 폴더 정리를 못하는 경우 때문에
  • 1) 다른 작업과 공용으로 사용
  • 2) 폴더가 아닌 SQL 같은 곳에서 넘어오는 경우

 

 

 

4. 파이토치로 무조건 전처리하기 (고급) 

아래 양식 기억하자!!

from torch.utils.data import Dataset

 

class MyDataset(Dataset):

 

    def __init__(self):

 

    def __getitem__(self, index):

 

    def __len__(self):

# 개인 데이터에 transform 까지 사용

 

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.trasform(sample)

 

        return sample   # 넘파이로 출력됨

   

    def __len__(self):

        return self.len

 

 

class ToTensor:

    def __call__(self, sample):

        inputs, labels = sample

        inputs = torch.FloatTensor(inputs)

        inputs = inputs.permute(2,0,1)

        return inputs, torch.LongTensor(labels)

   

# 들어온 데이터를 연산

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

        return inputs, labels

 

# 인스턴스 생성 및 데이터 처리

 

trans = tr.Compose([ToTensor(),LinearTensor(2,5)])

ds1 = MyDataset(train_images, train_labels, transform=trans)

train_loader1 = DataLoader(ds1, batch_size=10, shuffle=True)

 

# 데이터 확인

 

first_data = ds1[0]

features, labels = first_data

print(type(features), type(labels))

 

 

반응형