데이터셋을 얻고 사용하다보면 자주 메모리에 담을 수 없는 큰 규모의 데이터셋을 마주하게 될 것이다. 이러한 데이터를 다루는 방법을 알아보자.

데이터 API

전체적인 데이터 API의 중심에는 데이터셋의 개념이 있다. 데이터셋을 tf.data.Dataset.from_tensor_slices()를 사용하여 만들어 보자.

import tensorflow as tf

X = tf.range(10)
dataset = tf.data.Dataset.from_tensor_slices(X)

for data in dataset:
  print(data)

>> tf.Tensor(0, shape=(), dtype=int32)
>> tf.Tensor(1, shape=(), dtype=int32)
>> tf.Tensor(2, shape=(), dtype=int32)
>> tf.Tensor(3, shape=(), dtype=int32)
>> tf.Tensor(4, shape=(), dtype=int32)
>> tf.Tensor(5, shape=(), dtype=int32)
>> tf.Tensor(6, shape=(), dtype=int32)
>> tf.Tensor(7, shape=(), dtype=int32)
>> tf.Tensor(8, shape=(), dtype=int32)
>> tf.Tensor(9, shape=(), dtype=int32)

이와 같이 데이터를 하나 하나씩 가지고 올 수 있다.

연쇄 변환

데이터셋을 여러 메서드를 호출하여 변환을 수행할 수 있다. 코드를 통해 살펴보자.

dataset = dataset.repeat(3).batch(7)

for data in dataset:
  print(data)

>> tf.Tensor([0 1 2 3 4 5 6], shape=(7,), dtype=int32)
>> tf.Tensor([7 8 9 0 1 2 3], shape=(7,), dtype=int32)
>> tf.Tensor([4 5 6 7 8 9 0], shape=(7,), dtype=int32)
>> tf.Tensor([1 2 3 4 5 6 7], shape=(7,), dtype=int32)
>> tf.Tensor([8 9], shape=(2,), dtype=int32)

이와 같이 batch와 epoch에 따라 데이터셋을 불러올 수 있다.

위 코드에서 repeat은 데이터셋의 아이템을 반복하여 뽑는다는 것이고 batch는 한 번에 몇 가지를 뽑는가를 결정하는 메서드이다. 마지막에 2개가 출력되는 것과 같이 끝의 예외를 제외하고 싶다면, drop_remainder=True로 인자를 추가하면 된다.

데이터셋 셔플링

경사 하강법은 훈련 데이터의 샘플이 독집적이고 동일한 분포를 가질 때에 가장 좋은 성능을 낸다. 이를 수행하는 가장 간단한 방법은 shuffle메서드를 사용하는 것이다. 코드를 통해 살펴보자.

dataset = tf.data.Dataset.range(10).repeat(3)
dataset = dataset.shuffle(buffer_size=5, seed=42).batch(7)

for data in dataset:
  print(data)

>> tf.Tensor([0 2 3 6 7 9 4], shape=(7,), dtype=int64)
>> tf.Tensor([5 0 1 1 8 6 5], shape=(7,), dtype=int64)
>> tf.Tensor([4 8 7 1 2 3 0], shape=(7,), dtype=int64)
>> tf.Tensor([5 4 2 7 8 9 9], shape=(7,), dtype=int64)
>> tf.Tensor([3 6], shape=(2,), dtype=int64)

<aside> 💡 이전의 sklearn에서 train_test_split함수도 일반적으로 shuffle=True가 들어가 있기에 shuffle이 진행된다.

</aside>

데이터 전처리

데이터 전처리란 데이터를 그 말대로 사용하기 전에 처리를 해준다는 것이다. 이는 에로 평균을 빼고 표준편차로 나누어 주는 정규화, 이미지 처리 등이 존재한다.

프리패치

Dataset 코드의 마지막에 prefetch(n)를 사용한다면 데이터셋은 항상 한 배치가 미리 준비되도록 준비한다. 이전의 img2txt 코드에도 존재하니 확인해보자.

입력 특성 전처리