AI/Tensorflow

Tensorflow windowed dataset 활용법

Urong 2020. 12. 24. 18:08
728x90

tf.data.Dataset을 활용하여 다양한 Dataset 로더를 만들 수 있습니다. 그리고, 로더를 활용하여, shuffle, batch_size, window 데이터셋 생성등 다양한 종류를 데이터 셋을 상황에 맞게 생성하고 모델에 feed할 수 있도록 제공해 줍니다.

더 이상 numpy로 한땀 한땀 만들어 줄 필요없이, 간단한 옵션 몇 개면 데이터세트를 완성할 수 있습니다.

References: 텐서플로우 공식 도큐먼트

# 필요한 라이브러리 import 
import numpy as np import tensorflow as tf

1. dimension을 1만큼 늘려주기

1-1. tensorflow 의 expand_dim : 차원 늘리기

x = np.arange(20) tf.expand_dims(x, 1).shape

1-2. numpy의 expand_dims와 동일

np.expand_dims(x, 1).shape

1-3. from_tensor_slices: numpy array나 list를 tensor dataset으로 변환

from_tensor_slices는 list numpy array 모두 변환하도록 지원하고 있습니다.

ds = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5]) 
for d in ds: 
	print(d)
ds = tf.data.Dataset.from_tensor_slices(np.arange(10)) 
ds 
for d in ds: 
	print(d)

2. batch

batch는 model에 학습시킬 때 batch_size를 지정하여 size만큼 데이터를 읽어 들여 학습시킬 때 유용한 method입니다.

이미지와 같은 큰 사이즈는 memory에 한 번에 올라가지 못하기 때문에, 이렇게 batch를 나누어서 학습시키기도 하구요.

또한, model이 weight를 업데이트 할 때, 1개의 batch가 끝나고 난 후 업데이트를 하게 되는데, 업데이트 빈도를 조절하는 효과도 있습니다.

drop_remainder는 마지만 남은 데이터를 drop 할 것인지 여부

ds = tf.data.Dataset.range(8) 
ds = ds.batch(3, drop_remainder=True) 
list(ds.as_numpy_iterator())

원래는 6, 7 이 batch로 출력되어야 하지만 drop_remainder=True 옵션이 나머지를 버린다

ds = tf.data.Dataset.range(8) 
for d in ds.batch(3, drop_remainder=True): 
	print(d)

3. window: Time Series 데이터셋 생성에 유용

Time Series 데이터셋을 구성할 때 굉장히 유용하게 활용할 수 있습니다.

  • window: 그룹화 할 윈도우 크기(갯수)
  • drop_remainder: 남은 부분을 버릴지 살릴지 여부
  • shift는 1 iteration당 몇 개씩 이동할 것인지

drop_remainder=False 인 경우

ds = tf.data.Dataset.range(10) 
ds = ds.window(5, shift=1, drop_remainder=False) 
for d in ds: 
	print(list(d.as_numpy_iterator()))

drop_remainder=True 인 경우

ds = tf.data.Dataset.range(10) 
ds = ds.window(5, shift=1, drop_remainder=True) 
for d in ds: 
	print(list(d.as_numpy_iterator()))

shift=2로 설정: 2칸씩 이동

ds = tf.data.Dataset.range(10) 
ds = ds.window(5, shift=2, drop_remainder=True) 
for d in ds: 
	print(list(d.as_numpy_iterator()))

4. flat_map

flat_map은 dataset에 함수를 apply해주고, 결과를 flatten하게 펼쳐 줍니다.

아래는 lambda 함수를 통해 3개의 batch를 읽어들인 뒤 flatten된 리턴값을 받습니다.

ds = tf.data.Dataset.range(10) 
ds = ds.window(5, shift=1, drop_remainder=True) 
ds = ds.flat_map(lambda w: w.batch(3)) 
for d in ds: 
	print(d)
ds = tf.data.Dataset.range(10) 
ds = ds.window(5, shift=1, drop_remainder=True) 
ds = ds.flat_map(lambda w: w.batch(5)) 
for d in ds: 
	print(d)

5. shuffle

shuffle은 Dataset을 섞어주는 역할을 하며, 반드시 학습전에 shuffle을 통해 적절하게 Dataset을 섞어주어야 합니다.

# shuffle을 해주지 않은 경우 
ds = tf.data.Dataset.from_tensor_slices(np.arange(10))#.shuffle() 
for d in ds: 
	print(d)
# shuffle 설정 
ds = tf.data.Dataset.from_tensor_slices(np.arange(10)).shuffle(buffer_size=5) 
for d in ds: 
	print(d)

위의 shuffle함수에서 꼭 지정해주어야하는 인자는 buffer_size 입니다.

텐서플로우 공식 도큐먼트에 의하면,

  • 데이터세트는 buffer_size 요소로 버퍼를 채운 다음이 버퍼에서 요소를 무작위로 샘플링하여 선택한 요소를 새 요소로 바꿉니다.

  • 완벽한 셔플 링을 위해서는 데이터 세트의 전체 크기보다 크거나 같은 버퍼 크기가 필요합니다.

  • 예를 들어, 데이터 집합에 10,000 개의 요소가 있지만 buffer_size가 1,000으로 설정된 경우 셔플은 처음에 버퍼의 처음 1,000 개 요소 중 임의의 요소 만 선택합니다.

  • 요소가 선택되면 버퍼의 공간이 다음 요소 (즉, 1,001-st)로 대체되어 1,000 요소 버퍼를 유지합니다.

6. map

Dataset의 map함수는 pandas의 map과 유사합니다.

Dataset 전체에 함수를 맵핑합니다.

Time Series Dataset을 만드려는 경우, train/label 값을 분류하는 용도로 활용할 수 있습니다.

x[:-1], x[-1:] 의 의도는 각 row의 마지막 index 전까지는 train data로, 마지막 index는 label로 활용하겠다는 의도입니다.

window_size=5 
ds = tf.data.Dataset.range(10) 
ds = ds.window(window_size, shift=1, drop_remainder=True) 
ds = ds.flat_map(lambda w: w.batch(window_size)) 
ds = ds.shuffle(10) 

# 첫 4개와 마지막 1개를 분리 
ds = ds.map(lambda x: (x[:-1], x[-1:])) 
for x, y in ds: 
	print('train set: {}'.format(x)) 
    print('label set: {}'.format(y))

출처 - tensorflow 2.0 Dataset, batch, window, flat_map을 활용한 loader 만들기 (teddylee777.github.io)

 

tensorflow 2.0 Dataset, batch, window, flat_map을 활용한 loader 만들기

tensorflow 2.0 Dataset, batch, window, flat_map을 활용한 loader 만드는 방법에 대하여 알아보겠습니다.

teddylee777.github.io

 

728x90
반응형