본문 바로가기

ML & AI

Stateful RNN의 input data 에 대한 이해

* 핸즈온 머신러닝(2판) 16장 내용 중 이해한 내용을 바탕으로 쓴 글임. 

* 개인 공부를 위해 이해한 바를 적은 글이기 때문에, 사실과 다른 내용이 있을 수 있습니다.

 

상태가 있는 RNN에 관하여, 책에서는 이렇게 설명하고 있다.

  1. 먼저 상태가 있는 RNN은 배치에 있는 각 입력 시퀀스가 이전 배치의 시퀀스가 끝난 지점에서 시작해야 합니다. 
  2. 따라서 상태가 있는 RNN을 만들기 위해 첫 번째로 할 일은 순차적이고 겹치지 않는 입력 시퀀스를 만드는 것임.

 

정확히 무슨 뜻인지를 파보자.

 

먼저 배치의 개념을 다시 생각해보자. 배치의 개념만 정확히 이해해도 위 내용을 이해하는 것은 쉽다.

 

  • 배치란, 신경망이 파라미터를 업데이트 하는 단위임. 즉, 배치 내의 모든 데이터가 한 번에 모델에 입력되고, 이를 바탕으로 신경망은 파라미터를 업데이트 한다.

이 부분에서 위의 1번이 헷갈렸던 것이다. 

첫 번째 배치가 윈도우 1부터 윈도우 32까지 포함하고, 두번째 배치는 윈도우 33부터 윈도우 64까지 포함한다고 하자.

이 배치 형태는 1번 조건을 만족하는가? 언뜻 보면 32 다음에 33으로 넘어가므로 1번이 만족한다고 볼 수 있겠지만, 이는 배치의 개념을 무시하고 생각한 것이다. 32와 33의 연속성은 신경망의 알 바가 아니다.

 

Stateful RNN에서 원하는 배치는 이런 것이다.

 

첫번째 배치 중 첫번째 원소가 윈도우 1이면, 다음 배치의 첫 원소가 윈도우 2.

첫 번째 배치 중 두번째 원소가 윈도우 10이면, 다음 배치의 첫 원소가 윈도우 11.

.

.

.

.

이 때 2번에서는 시퀀스 간에 겹치지 않을 것을 요구하는데, 만약 배치 간 시퀀스가 서로 겹치게 된다면,  이전 배치에 대한 상태가 흐르는 신경망이기에, 학습/일반화 효과가 떨어질 것이다.

 

 

 

이러한 방식을 코드로 구현하면 

batch_size = 32
encoded_parts = np.array_split(encoded[:train_size], batch_size)
datasets = []
for encoded_part in encoded_parts:
    dataset = tf.data.Dataset.from_tensor_slices(encoded_part)
    dataset = dataset.window(window_length, shift=n_steps, drop_remainder=True)
    dataset = dataset.flat_map(lambda window: window.batch(window_length))
    datasets.append(dataset)
dataset = tf.data.Dataset.zip(tuple(datasets)).map(lambda *windows: tf.stack(windows))
dataset = dataset.map(lambda windows: (windows[:, :-1], windows[:, 1:]))
dataset = dataset.map(
    lambda X_batch, Y_batch: (tf.one_hot(X_batch, depth=max_id), Y_batch))
dataset = dataset.prefetch(1)

출처 : https://github.com/rickiepark/handson-ml2/blob/master/16_nlp_with_rnns_and_attention.ipynb 

 

GitHub - rickiepark/handson-ml2: 핸즈온 머신러닝 2/E의 주피터 노트북

핸즈온 머신러닝 2/E의 주피터 노트북. Contribute to rickiepark/handson-ml2 development by creating an account on GitHub.

github.com