Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

파이토치 데이터 공정

import torch, torchvision

print('PyTorch', torch.__version__)
PyTorch 2.8.0+cu128

1Oxford IIIT Pets

1.1데이터

from pathlib import Path

data_dir = Path('data/oxford-iiit-pet')
assert data_dir.exists() and data_dir.is_dir(), f'{data_dir} 경로가 존재하지 않습니다.'
이미지파일 = list((data_dir / 'images').glob('*.jpg'))
이미지파일.sort()
print(f'파일 개수: {len(이미지파일)}')
print(f'첫 번째 파일: {이미지파일[0]}')
파일 개수: 7390
첫 번째 파일: data/oxford-iiit-pet/images/Abyssinian_1.jpg
from pathlib import Path
from PIL import Image

class OxfordIIITPetDataset:
    def __init__(self, 폴더, transform=None, return_image_id=False):
        dir_path = Path(폴더)
        assert dir_path.exists() and dir_path.is_dir(), f'{폴더} 경로가 존재하지 않습니다.'
        
        self.이미지파일 = list((dir_path / 'images').glob('*.jpg'))
        self.이미지파일.sort()
        self.transform = transform
        self.return_image_id = return_image_id

    def __len__(self):
        return len(self.이미지파일)
    
    def __getitem__(self, idx):
        이미지경로 = self.이미지파일[idx]
        sample = None
        with Image.open(이미지경로) as img:
            # 이미지 객체를 반환하려면 복사본을 만들어야 합니다.
            sample = img.copy()

        if self.transform:
            sample = self.transform(sample)

        if self.return_image_id:
            return {'img_id': 이미지경로.name, 'sample': sample}
        
        return sample
dataset = OxfordIIITPetDataset('data/oxford-iiit-pet', transform=None)
print(f'데이터셋 크기: {len(dataset)}')
sample = dataset[0]
print(type(sample), sample.size, sample.mode)

transform = torchvision.transforms.Compose([
    torchvision.transforms.Resize((200, 200)),
    torchvision.transforms.ToTensor()])

dataset = OxfordIIITPetDataset('data/oxford-iiit-pet', transform=transform)
sample = dataset[0]
print(type(sample), sample.shape, sample.dtype, sample.device)

dataset = OxfordIIITPetDataset('data/oxford-iiit-pet', transform=transform, return_image_id=True)
sample = dataset[0]
print(type(sample), sample['img_id'], type(sample['sample']))
데이터셋 크기: 7390
<class 'PIL.Image.Image'> (600, 400) RGB
<class 'torch.Tensor'> torch.Size([3, 200, 200]) torch.float32 cpu
<class 'dict'> Abyssinian_1.jpg <class 'torch.Tensor'>

2Data Loader

transform = torchvision.transforms.Compose([
    # 배치를 위해 3채널로 변환
    torchvision.transforms.Lambda(lambda img: img.convert('RGB')),
    torchvision.transforms.Resize((200, 200)),
    torchvision.transforms.ToTensor()])

dataset = OxfordIIITPetDataset('data/oxford-iiit-pet', transform=transform)
loader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)

batch = next(iter(loader))
print(type(batch), batch.shape, batch.dtype, batch.device)
<class 'torch.Tensor'> torch.Size([32, 3, 200, 200]) torch.float32 cpu

2.1멀티 프로세스 로딩

torch.utils.data

도커 컨테이너를 사용하는 경우, 공유 메모리 (shm; shared memory) 크기의 기본값(64MB)이 작아서 멀티 프로세스가 실패할 수 있습니다. (도커 컨테이너 자원 제한)

호스트 공유 메모리 사용 설정을 권장합니다. (도커 컨테이너 IPC 설정)

docker run --ipc=host $IMAGE_ID
# 배치 크기별 로드 속도 측정
import time
import pandas as pd

batch_sizes = [1, 8, 32, 64, 128, 256, 512, 1024]

results = {}
for num_workers in [0, 2, 4, 8]:
    print(f'멀티 프로세스 수: {num_workers}')
    for batch_size in batch_sizes:
        print(f'배치 크기: {batch_size}', end=' ')
        loader = torch.utils.data.DataLoader(
            dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers)
        
        start_time = time.time()
        for batch in loader:
            pass
        end_time = time.time()
        
        elapsed_time = end_time - start_time
        print(f'소요 시간 (초): {elapsed_time:.1f}')
        results[(batch_size, num_workers)] = elapsed_time
Output
멀티 프로세스 수: 0
배치 크기: 1 소요 시간 (초): 27.3
배치 크기: 8 소요 시간 (초): 27.2
배치 크기: 32 소요 시간 (초): 27.2
배치 크기: 64 소요 시간 (초): 27.5
배치 크기: 128 소요 시간 (초): 28.1
배치 크기: 256 소요 시간 (초): 28.6
배치 크기: 512 소요 시간 (초): 29.4
배치 크기: 1024 소요 시간 (초): 28.8
멀티 프로세스 수: 2
배치 크기: 1 소요 시간 (초): 15.8
배치 크기: 8 소요 시간 (초): 14.0
배치 크기: 32 소요 시간 (초): 13.8
배치 크기: 64 소요 시간 (초): 14.0
배치 크기: 128 소요 시간 (초): 14.2
배치 크기: 256 소요 시간 (초): 14.6
배치 크기: 512 소요 시간 (초): 14.7
배치 크기: 1024 소요 시간 (초): 16.4
멀티 프로세스 수: 4
배치 크기: 1 소요 시간 (초): 8.9
배치 크기: 8 소요 시간 (초): 7.8
배치 크기: 32 소요 시간 (초): 7.6
배치 크기: 64 소요 시간 (초): 7.6
배치 크기: 128 소요 시간 (초): 7.8
배치 크기: 256 소요 시간 (초): 8.4
배치 크기: 512 소요 시간 (초): 8.7
배치 크기: 1024 소요 시간 (초): 9.3
멀티 프로세스 수: 8
배치 크기: 1 소요 시간 (초): 6.6
배치 크기: 8 소요 시간 (초): 4.6
배치 크기: 32 소요 시간 (초): 4.3
배치 크기: 64 소요 시간 (초): 4.3
배치 크기: 128 소요 시간 (초): 4.7
배치 크기: 256 소요 시간 (초): 4.7
배치 크기: 512 소요 시간 (초): 5.2
배치 크기: 1024 소요 시간 (초): 5.9
frame = pd.Series(results).unstack(level=1)
frame.index.name = 'batch size'
frame.columns.name = 'num_workers'
frame.round(1)
Loading...