Doby's Lab

tf.data.Dataset & tf.data.Dataset의 유용한 Methods 본문

Code about AI/tensorflow

tf.data.Dataset & tf.data.Dataset의 유용한 Methods

도비(Doby) 2023. 8. 17. 07:13

✅ Intro

tensorflow를 활용할 때, 이전에는 ImageDataGenerator를 통해 이미지 분류 프로젝트를 진행했던 경험이 있습니다.

이번엔 다른 Task를 다루어서 데이터셋은 당연히 Numpy type을 통해 학습시키지 않을까 했지만, tensorflow에서 제공하는 tf.data.Dataset 클래스가 보편적으로 많이 사용되는 것을 보고, 유용하겠다라고 판단했기 때문에 포스팅을 작성하게 되었습니다.


 

✅ tf.data.Dataset

tf.data.Dataset은 TensorFlow에서 데이터를 효율적으로 처리하고, 입력 파이프라인을 구성하기 위해 도입된 개념입니다.

메모리와 병렬처리같은 다양한 장점들이 많았지만, 데이터 입력 파이프라인 구성을 위해 사용할 수 있다는 점이 직관적으로 '유용하겠다'라고 생각할 수 있는 장점이었습니다.

 

입력 파이프라인 구성을 위해 유용하게 쓸 수 있는 메서드를 5가지 정도 정리할 수 있었습니다.


📄 batch()

인자를 통해 BATCH_SIZE를 넘겨서 데이터셋을 Batch로 분할하는 메서드

# .batch()에 대한 예시

temp = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

temp_batch_size = 2

batched_temp_dataset = temp.batch(temp_batch_size)

for batch in batched_temp_dataset:
    print(batch.numpy())
OUTPUT
[1 2]
[3 4]
[5 6]
[7 8]
[ 9 10]

📄 repeat()

  • 데이터셋을 반복하는 역할을 함
  • 반복적으로 데이터셋을 사용하면 학습 과정에서 더 많은 에포크를 돌 수 있음
    • 즉, 2번을 설정했다면, 하나의 에포크에서 2번의 에포크 효과를 낼 수 있음
  • 인자를 지정하지 않으면 무한정 반복함
# .repeat()에 대한 예시

temp = tf.data.Dataset.range(5)

repeated_temp = temp.repeat(2)

for item in repeated_temp:
    print(item.numpy())
OUTPUT
0
1
2
3
4
0
1
2
3
4

📄 cache()

  • 데이터셋의 원소를 메모리나 디스크에 캐싱하여 데이터 로딩 속도를 향상하는 역할을 함.
  • 캐싱을 한 번하여 메모리나 디스크에 저장해두면, 이후에 동일한 데이터를 다시 사용할 때, 데이터를 다시 로딩하지 않고, 캐시된 값을 활용하는 방식
    1. 데이터 로딩 속도 향상
    2. 데이터 전처리 효율성
      • 전처리 과정이 복잡한 경우, 데이터를 캐싱하여 전처리한 결과를 재사용하면 계산 비용을 줄일 수 있음
    3.  반복 학습에서의 성능 향상
      • 모델이 여러 번의 에포크를 돌 때 데이터를 매번 로딩하는 것보다 캐싱된 데이터를 활용하여 학습 속도를 높일 수 있음 
  • 왜 모든 데이터가 그럼 캐싱을 안 하는가?
    • 모든 데이터를 캐싱하면 메모리 또는 디스크 공간을 과도하게 사용하게 되어 성능 저하나 시스템 리소스 부족 문제를 유발하기 때문
    • 캐싱할 때 고려할 점
      1. 데이터셋 크기
      2. 데이터 엑세스 빈도
      3. 전처리 비용
      4. 하드웨어 재한
      5. 학습 또는 추론 패턴
# .cache()에 대한 예시

temp = tf.data.Dataset.range(10)

cached_temp = temp.cache()

for item in cached_temp:
    print(item.numpy())
OUTPUT
0
1
2
3
4
5
6
7
8
9

📄 shuffle()

  • 데이터의 순서를 무작위로 섞어서 훈련의 다양성을 높임
  • 모델이 특정 순서에 의존하지 않게 함으로써 일반화 능력을 향상함
  • buffer_size
    • 버퍼 사이즈만큼 앞에서 데이터를 담아 섞는다.
    • 즉, 랜덤 하게 할 거면, 버퍼 사이즈를 데이터셋의 사이즈보다 크거나 같게 해야 한다.
    • 근데, tensorflow 2.7.0에서는 buffer_size가 데이터의 크기로 변환돼버리는 거 같다는 의견이 있다. (아래 예시도 그 의견에 똑같은 현상이 나옴) https://sunlab0623.tistory.com/472
# .shuffle()에 대한 예시

temp = tf.data.Dataset.range(10)

shuffled_temp = temp.shuffle(buffer_size=5)

for item in shuffled_temp:
    print(item.numpy())
OUTPUT
1
0
4
3
5
8
6
7
9
2

📄 take()

일부 원소만 추출하는 메서드, 앞에서부터 순차적으로 가져옴

# .take()에 대한 예시

temp = tf.data.Dataset.range(10)

subset_temp = temp.take(5)

for item in subset_temp:
    print(item.numpy())
OUTPUT
0
1
2
3
4
728x90