PyTorch 기초 - Tensor와 Dataset, DataLoader

Jeonghwan Kim·2024년 7월 13일
0

PyTorch 기초

목록 보기
1/1

머신러닝 파이토치 다루기 기초 를 기반으로 정리한 내용입니다.

Tensor

  • Pytorch 에서 Tensor는 다차원 배열을 나타내는 자료형
  • Numpy의 ndarray와 유사하며, GPU를 이용한 연산을 지원함
    torch.tensor(data, dtype=None, device=None, requires_grad=False)
  • Tensor 생성 예제
import torch

# 1차원 텐서 생성
x = torch.tensor([1, 2, 3])
print(x)

# 2차원 텐서 생성
y = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(y)

# 모든 원소가 0인 3차원 텐서 생성
z = torch.zeros((2, 3, 4))
print(z)

# 모든 원소가 1인 4차원 텐서 생성
w = torch.ones((2, 2, 2, 2))
print(w)

# 랜덤한 값으로 채워진 3x3 텐서 생성
r = torch.rand((3, 3))
print(r)

tensor([1, 2, 3])
tensor([[1, 2, 3],
        [4, 5, 6]])
tensor([[[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]],

        [[0., 0., 0., 0.],
         [0., 0., 0., 0.],
         [0., 0., 0., 0.]]])
tensor([[[[1., 1.],
          [1., 1.]],

         [[1., 1.],
          [1., 1.]]],


        [[[1., 1.],
          [1., 1.]],

         [[1., 1.],
          [1., 1.]]]])
tensor([[0.8370, 0.4505, 0.1556],
        [0.0408, 0.3685, 0.3798],
        [0.4273, 0.0290, 0.2450]])
  • torch.from_numpy()와 torch.tensor()의 차이
    • torch.from_numpy()는 NumPy 배열을 PyTorch Tensor로 변환함, 기존 NumPy 배열과 데이터를 공유하며, 따라서 반환된 Tensor를 수정하면 NumPy 배열도 수정되고, NumPy 배열과 Tensor가 메모리 상에서 동일한 위치를 참조함 (데이터 크기가 크고 계산 비용이 많이 드는 경우에 Numpy 배열과 Tensor를 공유하여 메모리를 절약)
    • torch.tensor()의 경우 Tensor와 Numpy 배열은 데이터를 공유하지 않으며, Tensor를 수정하더라도 Numpy 배열은 변경되지 않음 (데이터를 공유하지 않고 복사해서 사용하는 경우에 사용)
  • torch.rand와 torch.randn의 차이
    • rand함수는 균등 분포(uniform distribution)에서 난수를 생성하여, 최솟값과 최댓값 사이의 값들이 동일한 확률로 선택되는 분포
    • randn함수는 정규 분포(normal distribution)에서 난수를 생성하여, 평균 0, 분산 1인 정규 분포에서 무작위 값을 생성함
  • tensor는 4가지 속성 dtype(데이터 타입), device(GPU 등), size(텐서 내 데이터 개수), shape(텐서의 차원)을 가짐
  • np.concatenate처럼 tensor도 torch.cat, torch.vstack, torch.hstack 등으로 병합할 수 있음
  • torch.softmax: 소프트맥스 함수는 입력값을 확률 형태로 반환해주는 함수로, 다중 클래스 분류 문제에서 예측된 점수를 확률로 변환하는 데 사용됨
    torch.softmax(input, dim=None, dtype=None)
    • input: 소프트맥스 함수를 적용하려는 입력 텐서
    • dim(optional): 소프트맥스를 계산할 차원 (Dimension)으로, 기본값 None일 경우 입력 텐서의 마지막 차원이 사용됨
    • dtype(optional): 출력 텐서의 데이터 타입으로, 기본값 None일 경우 동일한 데이터 타입으로 출력 텐서가 생성됨
    • torch.softmax 함수는 입력 텐서 input의 각 원소에 대해 소프트맥스를 계산하여 확률값으로 변환된 텐서를 반환함. 원본 텐서와 같은 shape을 가지며 원소의 합이 1인 확률 분포로 변환됨
  • 인플레이스 연산은 원본 텐서의 값을 변경하며, add_, sub_, mul_ 처럼 _가 연산자 뒤에 붙는 메소들르 사용하여 수행함
  • fill()과 full()은 텐서의 값을 채우는데 사용됨

Dataset과 DataLoader

  • PyTorch에서 제공하는 데이터 로딩 및 전처리 기능을 제공하며, 모델 학습에 필요한 데이터를 batch 단위로 처리할 수 있도록 도와줌

  • 1) Dataset

    • 사용자가 정의하는 데이터셋에 대한 인터페이스를 제공함
    • len(), getitem(idx) 메서드를 구현해야 함
      • len(): 데이터셋의 전체 샘플 개수를 반환하는 메서드로, 정수 값을 반환함
      • getitem(idx): 인덱스 idx에 해당하는 샘플을 가져오는 메서드로, 인덱스에 따라 샘플 데이터와 레이블(label) 등을 반환함
    import torch
    from torch.utils.data import Dataset
    
    class CustomImageDataset(Dataset):
        def __init__(self, file_paths, labels, transform=None):
            """
            커스텀 이미지 데이터셋 클래스의 생성자입니다.
    
            Args:
                file_paths (list): 이미지 파일 경로의 리스트
                labels (list): 이미지 레이블의 리스트
                transform (callable, optional): 이미지에 적용할 전처리 함수
            """
            self.file_paths = file_paths
            self.labels = labels
            self.transform = transform
    
        def __len__(self):
            """
            데이터셋의 전체 샘플 개수를 반환합니다.
            """
            return len(self.file_paths)
    
        def __getitem__(self, idx):
            """
            인덱스에 해당하는 샘플을 가져옵니다.
    
            Args:
                idx (int): 샘플의 인덱스
    
            Returns:
                image (torch.Tensor): 이미지 데이터의 텐서
                label (torch.Tensor): 이미지 레이블의 텐서
            """
            # 이미지 파일을 불러옴
            image = Image.open(self.file_paths[idx])
    
            # 이미지에 전처리 함수를 적용 (예: Resize, RandomCrop, ToTensor 등)
            if self.transform is not None:
                image = self.transform(image)
    
            # 이미지 레이블을 텐서로 변환
            label = torch.tensor(self.labels[idx])
    
            return image, label
    
  • torchvision.transforms를 사용하여 이미지 전처리 작업을 정의함

    import torchvision.transforms as T
    
    img_T = T.Compose([
        transforms.Resize((256, 256)),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.5,), (0.5,))
    ])
    • Custom Dataset 클래스의 __getitem__ 메서드에서 이미지 데이터에 transforms를 적용하게 됨, self.imge_T를 적용하고 텐서와 레이블을 반환하도록 정의함

      from torch.utils.data import Dataset
      from PIL import Image
      
      class CustomImageDataset(Dataset):
          def __init__(self, file_list, label_list, img_T=None):
              self.file_list = file_list
              self.label_list = label_list
              self.img_T = img_T
      
          def __getitem__(self, idx):
              image = Image.open(self.file_list[idx])
              label = self.label_list[idx]
      
              if self.img_T is not None:
                  image = self.img_T(image)
      
              return image, label
      
          def __len__(self):
              return len(self.file_list)
      
    • torchvision.transforms 함수의 기능 (Data Augmentation에 활용)

      • Resize: 이미지의 크기를 조절합니다.
      • RandomResizedCrop: 이미지를 무작위로 자르고 크기를 조절합니다.
      • RandomHorizontalFlip: 이미지를 무작위로 수평으로 뒤집습니다.
      • RandomVerticalFlip: 이미지를 무작위로 수직으로 뒤집습니다.
      • ToTensor: 이미지를 텐서로 변환합니다.
      • Normalize: 이미지를 정규화합니다.
      • ColorJitter: 이미지의 색상을 무작위로 조정합니다.
      • RandomRotation: 이미지를 무작위로 회전합니다.
      • RandomCrop: 이미지를 무작위로 자릅니다.
      • Grayscale: 이미지를 흑백으로 변환합니다.
      • RandomSizedCrop: 이미지를 무작위로 자르고 크기를 조절합니다.
      import torchvision.transforms as T
      
      # 이미지 전처리 작업을 정의
      preprocess = T.Compose([
          T.Resize((256, 256)),
          T.RandomHorizontalFlip(),
          T.ToTensor(),
          T.Normalize((0.5), (0.5))# T.Normalize([0.5],[0.5])
      ])
      
      # 이미지에 전처리 작업 적용
      image = Image.open('image.jpg')
      imge = preprocess(image)
      
  • torchvision.utils.save_image 함수는 이미지 텐서를 파일로 저장하며, 모델이 생성한 이미지를 저장할 때 활용함

    import torch
    import torchvision.utils as vutils
    
    # Create a tensor of shape (3, 64, 64) representing a single RGB image
    img = torch.randn(3, 64, 64)
    
    # Save the image to a file
    vutils.save_image(img, 'my_image.png')
  • 2) DataLoader

    • PyTorch에서 제공하는 데이터 로딩 유틸리티로, 모델 학습 시에 데이터를 batch 단위로 로드하여 효율적인 학습을 가능하게 해주는 클래스로, for 루프를 사용해 데이터를 배치 단위로 로드하고 모델에 전달해 학습함

      # CustomImageDataset 객체 생성
      dataset = CustomImageDataset(file_list, label_list, transform=transform)
      
      # DataLoader 생성
      dataloader = DataLoader(dataset, batch_size=32, shuffle=True, num_workers=4)
      
      # 데이터 로딩을 위한 반복문
      for images, labels in dataloader:
          # images와 labels를 이용하여 모델 학습 수행
          pass
      • dataset: 데이터를 로드할 데이터셋 객체를 지정합니다. 이는 torch.utils.data.Dataset 클래스를 상속받은 사용자 정의 데이터셋 클래스를 사용하거나, torchvision의 내장 데이터셋 클래스를 사용할 수 있습니다. (기본값: None)

      • batch_size: 한 번에 로드할 배치(batch)의 크기를 지정합니다. 작은 배치 크기는 더 많은 메모리를 사용하지만 더 자주 모델이 업데이트되고 더 높은 학습 속도를 제공합니다. (기본값: 1)

      • shuffle: 데이터를 섞을지 여부를 지정합니다. True로 설정할 경우, 데이터가 매 에폭(epoch)마다 섞여서 모델이 각 배치에서 다양한 데이터를 학습하도록 도와줍니다.(기본값: False)

      • num_workers: 데이터 로딩에 사용할 워커(worker)의 수를 지정합니다. 병렬 처리를 통해 데이터 로딩 속도를 향상시키는 데 사용됩니다.(기본값: 0)

      • pin_memory: GPU 메모리에 데이터를 고정할지 여부를 지정합니다. GPU를 사용하는 경우 True로 설정하면 데이터가 CPU와 GPU 간에 더 빠르게 복사되어 학습 속도를 향상시킬 수 있습니다. (기본값: False)

      • collate_fn: 배치를 생성하기 전에 데이터를 결합하는 함수를 지정합니다. 기본값은 None이며, 데이터셋이 출력하는 원시 데이터의 리스트를 배치로 결합합니다. 필요에 따라 사용자 정의 결합 함수를 지정하여 배치를 구성할 수 있습니다.(기본값: None)

      • drop_last: 마지막 배치의 크기가 batch_size보다 작을 경우, 해당 배치를 무시할지 여부를 지정합니다. True로 설정할 경우 마지막 배치를 무시합니다.(기본값: False)

0개의 댓글