# AI 이론/TensorFlow Function

TensorFlow batch,window 메서드

alz 2022. 5. 3. 19:02

시계열 데이터를 다룰때 사용하는 메서드입니다.

 

Batch 사용하기

range_ds = tf.data.Dataset.range(10000)

# Using Batch 
batches = range_ds.batch(10,drop_remainder=True)

for batch in  batches.take(5):
	print(batch.numpy())
    
# Outputs
[0 1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]
[40 41 42 43 44 45 46 47 48 49]

 

한 단계 앞선 데이터를 예측하기 위한 메서드 입니다

def dense_1_step(batch):
  # Shift features and labels one step relative to each other.
  return batch[:-1], batch[1:]

predict_dense_1_step = batches.map(dense_1_step)

for features, label in predict_dense_1_step.take(3):
  print(features.numpy(), " => ", label.numpy())
  
#outputs

[0 1 2 3 4 5 6 7 8]  =>  [1 2 3 4 5 6 7 8 9]
[10 11 12 13 14 15 16 17 18]  =>  [11 12 13 14 15 16 17 18 19]
[20 21 22 23 24 25 26 27 28]  =>  [21 22 23 24 25 26 27 28 29]
  • map 메서드를 통해 batches에 dense_1_step 메서드를 적용시킵니다

 

배치를 두 부분으로도 분할 할 수 있습니다.

batches = range_ds.batch(15, drop_remainder=True)

def label_next_5_steps(batch):
  return (batch[:-5],   # Inputs: All except the last 5 steps
          batch[-5:])   # Labels: The last 5 steps

predict_5_steps = batches.map(label_next_5_steps)

for features, label in predict_5_steps.take(3):
  print(features.numpy(), " => ", label.numpy())
 
 #outputs
[0 1 2 3 4 5 6 7 8 9]  =>  [10 11 12 13 14]
[15 16 17 18 19 20 21 22 23 24]  =>  [25 26 27 28 29]
[30 31 32 33 34 35 36 37 38 39]  =>  [40 41 42 43 44]

 

다음은 한 배치의 기능과 다른 배치의 레이블이 약간 겹치게 하는 방식인데 다음과 같습니다.

a = [0,1,2,3,4,5,6,7,8,9],[10,11,12,13,14,15,16,17,18,19] ... 일때 

label 값을 a의 다음배치 중 앞에서 3 개의 값으로 하고싶을때

ex)  a = [0,1,2,3,4,5,6,7,8,9] , label = [10,11,12]

feature_length = 10 
label_length = 3 

features = range_ds.batch(feature_length,drop_remainder=True)
labels = range_ds.batch(feature_length).skip(1).map(lambda labels : labels[:label_length]

predicted_step = tf.data.Dataset.zip((features,labels))

for features,label in predicted_steps.take(5):
	print(features.numpy(), "=>", label.numpy())
    
#outputs

[0 1 2 3 4 5 6 7 8 9]  =>  [10 11 12]
[10 11 12 13 14 15 16 17 18 19]  =>  [20 21 22]
[20 21 22 23 24 25 26 27 28 29]  =>  [30 31 32]
[30 31 32 33 34 35 36 37 38 39]  =>  [40 41 42]
[40 41 42 43 44 45 46 47 48 49]  =>  [50 51 52]

 

Window 사용하기

 

dataset = tf.data.Dataset.range(10)
dataset = dataset.window(5, shift=1)
for window_dataset in dataset:
  for val in window_dataset:
    print(val.numpy(), end=" ")
  print()

위의 코드를 실행하면 다음과 같은 결과를 얻게 됩니다.0 1 2 3 41 2 3 4 52 3 4 5 63 4 5 6 74 5 6 7 85 6 7 8 96 7 8 97 8 98 99

6번째 줄까지는 window_size =5 만큼의 데이터를 가져오지만 이후에 윈도우 사이즈보다 적은 데이터를 가져옵니다.

윈도우 사이즈가 데이터셋의 크기를 초과 했기 때문입니다.

이를 위해서 drop_remainder =True 로하면 이를 방지할 수 있습니다.

dataset = tf.data.Dataset.range(10)
dataset = dataset.window(5, shift=1, drop_remainder=True)
for window_dataset in dataset:
  for val in window_dataset:
    print(val.numpy(), end=" ")
  print()
  
 #outputs 
 0 1 2 3 4 
 1 2 3 4 5
 2 3 4 5 6
 3 4 5 6 7
 4 5 6 7 8
 5 6 7 8 9

for-loop를 2번 쓴이유는 ?

dataset.window는 Tensor가 아닌 Dataset을 반환하기 때문입니다.

즉 Datasets 안에있는 Dataset을 반환하는데, 이는 flat_map 메서드를 통해 window_dataset을 Flatten 해줄수 있습니다.

원래는 5->4->3...처럼 iter방식으로 받지만 flat_map을 사용하면[5,4,3,2,1]으로 바로 받을 수 있습니다.\

다음과 같이 작성할 수 있습니다

range_ds = tf.data.Dataset.range(10)
range_ds = range_ds.window(5,shift=1,drop_remainder=True)
range_ds = range_ds.flat_map(lambda window : window.batch(5))
for window in range_ds:
	print(window.numpy())

 

 

참고글

https://hwiyong.tistory.com/350

https://www.tensorflow.org/guide/data

 

tf.data: TensorFlow 입력 파이프라인 빌드  |  TensorFlow Core

5월 11~12일 Google I/O에서 TensorFlow에 참여하세요. 지금 등록하세요. tf.data: TensorFlow 입력 파이프라인 빌드 tf.data API를 사용하면 간단하고 재사용 가능한 조각으로 복잡한 입력 파이프라인을 빌드할

www.tensorflow.org

 

'# AI 이론 > TensorFlow Function' 카테고리의 다른 글

TensorFlow tf.lookup  (0) 2022.05.04
TensorFlow tf.strings  (0) 2022.05.04