코딩 기록들

[Dataset 구현] 2. Dataloader 본문

이미지다루기및 데이터셋 구축

[Dataset 구현] 2. Dataloader

코딩펭귄 2023. 1. 5. 04:49

data -> 전처리 -> dataset() : 정의하는 과정 -> load 해와야됨

 

pytorch에서 배치학습에 요긴하게 사용되는 클래스 : dataloader

딥러닝학습시 데이터를 모델에 입력해 출력&목표값 비교하는 방식으로 순방향 전달(아래 사)이 일어난다.

모델에 데이터를 넣을때 작은 데이터셋이 아닌이상 학습할 데이터셋을 쪼개서, 미니배치 단위로 모델에 입력하게된다.

이 과정을 dataloader가 도와주는것.

 

노란색으로 표시한 부분이 이번 게시글의 과정!

 

dataloader 간단하게 사용하기

1. 사용할 모듈 불러오기 :  from torch.utils.data import Dataset, DataLoader

2. 한 dataloader 인스턴스 생성하기위해 생성자에 어떤 파라미터들이 필요한지 보기 

 :  DataLoader(dataset, batch_size=1, shuffle=False, ...)   # shuffle=False : 랜덤하게 섞어서 넣지 않겠다. 즉, 순차적으로!

    보통 학습시 : dataloader = DataLoader(dataset, batch_size=16, shuffle=True  <- 이렇게 생성, batch_size : 2의배수로!

3. dataloader 인스턴스를 만들었으면 미니배치단위로 데이터를 불러올 준비가 된것.

   모델 학습을 할때는 다음과같이 for문으로 바로 데이터를 불러온다 

    for index, (images, labels, path넣어도됨) in enumerate(dataloader): -> 여기서 index는 for문에서 얼만큼 데이터가              print(f"{index}/{len(dataloader)}", end=' ')                                                 불러와졌는지 확인하는 용도로 사용한다.

    print("x shape:", images.shape, end=' ')

    print("y shape:", labels.shape

   # 0/1563 x shape: torch.Size([16, 3, 256, 256]) y shape: torch.Size([16] 

   -> 16 : 배치사이즈 / 3 : 채널 / 256 256 : 이미지사이즈

 

 

num_workers 

- 서브 프로세스를 실행시켜 데이터를 불러오는데, 그때 실행시킬 서브프로세스의 개수를 의미한는 파라미터.

- 멀티프로세싱을 통해 저장된 데이터를 빠르게 가져오도록 하는것 :  (최근에는 대부분 8 사용)

- num_workers = GPU개수 * 4로 지정하면 좋다라는 말이 있긴 함.

 

 

pin_memory

1. 메모리구조

on-chihp 

- GPU 칩 안에있는 메모리 = 레지스터 메모리 / 로컬메모리 : 접근속도가 빠름, 비용의 이유로 메모리사이즈가 작다

 

off-chip

- 그래픽 카드에 장착한 DRAM으로,GPU 기본메모리는 FDDR5메모리 사용 : CUDA에서는 이를 글로벌메모리 / 디바이스메모리라고 한다

- 메모리 할당및 해제 방법 : GPU포인터 선언 -> cudaMalloc 명령으로 메모리 할당해주기 -> 메모리해제

- 속도가 느린대신 메모리사이즈가 크다

 

shared memory

- shared memory는 항상 __syncthreads()함수를 사용해야한다

 

Pinned memory & Pageable memory

 

Unified memory

- cpu 와 gpu가 동시에 같은메모리포인터를 사용할수있게한 CUDA 6.0의 새로운 기능

- cudaMallocManaged 함수를 사용해 쉽게 GPU병렬화 작업을 할수있다

 

 

DataLoader 잘 짜서 병목 극복하기 : GPU util 높이는법

문제상황 :  gpu utils이 왜 항상 20%정도만 나올까. oom이 뜨기 직전 상황에도 왜 util은 100%를 찍지 않는걸까.

원인 : 데이터를 load하는 과정과 feed하는 과정 사이에서 생기는 딜레이 때문. : 데이터 로더의 설계문제일것

데이터 로더 실험

- 이미지 불러올때 몇가지 trade-off와 싸워야 한다. : 공간복잡도와 시간복잡도의 싸움. 

- 실험의 설계 : 데이터의 위치만 가지고있고 실시간으로 필요한 양만큼만 불러오는 과정. :  torch 데이터 로더에서는 __init__()에 구현하느냐 __getitem__()에 구현하느냐의 차이!

 

방법1.

PIL : convert 하기 더편함(.convert RGB하면알아서바뀜)

cv2 : BGR 을 RGB로 바꿔주는 코드를 넣어야됨

 

 

 

 

 

 

 

 

방법2.

이미지가 있다고 가정했을떄, 1/4로 축소하고 크롭한뒤 불러오는 작업을 수행한다

0.5 = 50%의 확률로 되고 안되고를 의미

마지막줄 transforms.ToTensor() 해줘야 학습이 이루어질수있다

 

 

 

 

 batch_size : 가벼운 딥러닝일경우 이 값 높여도 상관없음(64, 32 등으로 넣고 돌려보기) - ex) 8G 메모리라면 최대 7.3-4 정도까지만 올려서 돌리기(값이 튈 수 있기 때문)

sampler : 디폴트 None 

num_workers : 체크하면서 조정하

 

 

 

학습 파이프라인

1. CPU : 데이터

- 디스크에서 데이터 읽기 / 전처리하기 / batch 만들기

2. GPU : 학습

- Forward / Loss / Back Propagation

 

 

모델이 학습되는 과정

한 Batch는 1,2,3 의 과정을 거쳐 학습하게된다.

1. Disk -> Memory로 데이터를 올리는 과정

2. CPU가 Memory에 올라간 데이터를 전처리+Batch 만드는과정

3. GPU 가 한 Batch를 학습하는  과정(Weight Update)

 

 

- GPU가 한 Batch학습 끝내고 다음 Batch 학습하기전까지 1+2 시간동안의 지연이 된다

- 따라서 : GPU util을 높이기위해선 : GPU에서 한 Batch 학습이 끝나기전에 다음 Batch 메모리에 준비!

 

 

 

 

데이터 파이프라인을 최적화하는 방법들

1. Multi Process Data Loading

- 단일 프로세스 1+2 시간지연을 없애자는 아이디어

- cpu0이 한 Batch 준비해 GPU올려 학습하는동안 다른 CPU1(프로세스)가 다음 Batch 준비하는것 : GPU의 시간지연이 없이 바로 다음 Batch 학습할수있기때문에 지연이 일어나지 않는다.

- 실제로는 다중의 프로세스들이 준비한 Batch를 공유하는 Queue에 넣고, 하나씩빼서 GPU에 올리는 방법(실제론 C, C++에서 구현함)

 

 

딥러닝 프레임워크 Pytorch 를 사용 :

torch.utils.data.dataloader 의 Dataloader객체 중.

num_workers라는 인자를 1보다 크게 설정하면

Multi Process Data Loading이 구현된다

 

 

문제 : 디스크 -> 메모리로 데이터 올리는게 너무 느림

         -> 해결방법 : 데이터의 일부를 메모리에 올려놓는것! : HDF5의 Chunk 사용!

Chunk Hit : HDF5이란 HDF 그룹에의해 관리되고있는 대용량 데이터 저장하기위한 파일형식 

- HDF5 : contigious layout, chunk layout이 있다

 

 

 

1. contigious layout : dataset을 일자로 편다 / 배열의 메모리에 저장되는 방식과 유사하다 / 한개의 통으로 디스크에 저장된다

2. chunk layout : Dataset을 여러개의 chunk(블록)으로 나누어서 저장한다 / 파일안에 한 블록이 무작위로 저장된다 / chunk별로 읽고쓸수있다 -> chunk에 있는 데이터하나를 참조하면 해당 chunk전체가 메모리에 올라가게 되는데, 이후 임의의 데이터를 참조했을대 해당데이터가 메모리에 올라가있으면 메모리에서 바로 참조한다!!

 

 

Batch Echoing

- GPU에 올라온 한 batch를 여러번 사용하는것

- 득 : 학습의 속도를 증가시킴 / 실 : Randomness(무작위성)가 감소

 

- 무작위성 : 어떠한 사건에 특정한 패턴이 없거나 실제로 예측이 불가능한경우

 

 

 

 

 

Reproducible pytorch를 위한 randomness 올바르게 제어하는 방법

1. pytorch randomness : pytoorch의 random seed를 고정할수있음

2. CuDNN : 딥러닝에 특화된 Cuda 라이브러리임. 환경설정시 CUDA와 CuDNN을 함께 설치하고, 딥러닝프레임워크에서 필수적으로 사용되는 라이브러리

 

 

 

 

 

3. Numpy

4. Random

 

 

 

'이미지다루기및 데이터셋 구축' 카테고리의 다른 글

[Dataset 구현] 1. customdataset  (1) 2023.01.05
CNN  (0) 2022.12.28
인공신경망  (0) 2022.12.23
04. Image augmentation  (0) 2022.12.16
이미지다루기_넘파이에 대하여  (0) 2022.12.06