반응형

Batching dataset elements

Simple batching

가장 간단한 배치의 형태는 데이터셋에서 n개의 요소를 하나의 요소로 쌓는 것이다. Dataset.batch() 변환은 정확하게 이를 수행한다. Dataset.batch() 변환은 tf.stack() 연산과 동일한 제약 - 즉, 각 컴포넌트 i에 대해 모든 요소는 정확하게 동일한 형태(shape)의 tensor를 가져야만 한다 - 으로 요소(elements)의 각 구성요소(component)에 적용된다.

 

inc_dataset = tf.data.Dataset.range(100)
dec_dataset = tf.data.Dataset.range(0, -100, -1)
dataset = tf.data.Dataset.zip((inc_dataset, dec_dataset))
batched_dataset = dataset.batch(4)

for batch in batched_dataset.take(4):
  print([arr.numpy() for arr in batch])

[array([0, 1, 2, 3]), array([ 0, -1, -2, -3])]
[array([4, 5, 6, 7]), array([-4, -5, -6, -7])]
[array([ 8,  9, 10, 11]), array([ -8,  -9, -10, -11])]
[array([12, 13, 14, 15]), array([-12, -13, -14, -15])]

tf.data가 형태 정보(shape information)을 전파(propagation)하려고 하지만, Dataset.batch의 기본 설정은 마지막 배치가 꽉 채워지지 않기 때문에 unknown batch size를 결과로 내 놓는다.

Shape중에 None을 주의하자.

batched_dataset
<BatchDataset shapes: ((None,), (None,)), types: (tf.int64, tf.int64)>

drop_reminder 인자를 사용하면 가장 마지막 배치를 무시하여 full shape propagation을 얻는다.

batched_dataset = dataset.batch(7, drop_remainder=True)
batched_dataset

<BatchDataset shapes: ((7,), (7,)), types: (tf.int64, tf.int64)>

 

Batching tensors with padding

위의 방법 Dataset.batch()는 모두 동일한 크기를 갖는 tensor에서 동작한다. 그러나 Sequence model 등 많은 모델이 다양한 크기 - 예를 들면, sequence of different length -의 입력 데이터를 갖는다. 이런 경우, Dataset.padded_batch 변환에서 padding되어야 하는 하나 이상의 차원을 명시하여 다른 모양의 텐서를 배치처리 할 수 있다.

 

dataset = tf.data.Dataset.range(100)
dataset = dataset.map(lambda x: tf.fill([tf.cast(x, tf.int32)], x))
dataset = dataset.padded_batch(4, padded_shapes=(None,))

for batch in dataset.take(2):
  print(batch.numpy())
  print()
 

[[0 0 0]
 [1 0 0]
 [2 2 0]
 [3 3 3]]

[[4 4 4 4 0 0 0]
 [5 5 5 5 5 0 0]
 [6 6 6 6 6 6 0]
 [7 7 7 7 7 7 7]]

Dataset.padded_batch 변환은 각 컴포넌트의 각 차원에 대해 다른 padding을 설정하는 것이 가능하고 이는 가변길이/고정길이 모두 가능하다. 또한 기본값이 0인 padding을 override 할 수 있다.

 

반응형

+ Recent posts