파이토치 데이터 공정
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 sampledataset = 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멀티 프로세스 로딩¶
도커 컨테이너를 사용하는 경우, 공유 메모리 (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_timeOutput
멀티 프로세스 수: 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...