1. Stacked RNN이란?
Stacked RNN은 기본 RNN의 단순한 구조로 복잡한 문제를 해결하지 못하는 점을 보완하기 위해 개발되었습니다. Stacked RNN은 여러 개의 RNN층을 쌓아 구성합니다. 그래서 복잡한 문제에서 RNN보다 더 높은 성능을 보일 수 있었습니다.
2. Stacked RNN의 구조
Stacked RNN은 여러 개의 RNN 층이 쌓여 있는 구조입니다. 각 층의 출력은 다음 층의 입력으로 사용되며, 마지막 층의 출력이 최종 결과로 사용됩니다. 이렇게 층을 쌓음으로써 모델의 표현력을 높일 수 있습니다.
Stacked RNN의 계산을 수식으로 표현하면 다음과 같습니다.
첫 번째 층
$$h_t^1 = f(W^1 * x_t + U^1 * h_{t-1}^1 + b^1)$$
여기서 \(x_t\)는 time step t에서의 입력 벡터입니다. \(h_{t-1}^1\)는 이전 time step t-1에서 첫 번째 RNN 층의 은닉 상태를 나타냅니다. \(W^1, U^1, b^1\)는 첫 번째 RNN 층의 가중치 행렬과 편향 벡터입니다. f는 활성화 함수로, 보통 tanh나 ReLU와 같은 비선형 함수를 사용합니다.
두 번째 층 부터 마지막 층
$$h_t^l = f(W^l * h_t^{l-1} + U^l * h_{t-1}^l + b^l) (l = 2, 3, ..., L)$$
여기서 \(h_t^{l-1}\)는 time step t에서 l-1번째 RNN 층의 은닉 상태를 나타냅니다. \(h_{t-1}^l\)는 이전 time step t-1에서 l번째 RNN 층의 은닉 상태를 나타냅니다. \(W^l, U^l, b^l\)는 l번째 RNN 층의 가중치 행렬과 편향 벡터입니다. f는 활성화 함수로, 첫 번째 층과 동일한 비선형 함수를 사용합니다.
출력 값
$$y = softmax(V * h_T^L + c)$$
여기서 \(h_T^L\)은 최종 time step T에서의 마지막 RNN 층 L의 은닉 상태를 나타냅니다. \(V\)는 출력 가중치 행렬이고, \(c\)는 출력 편향 벡터입니다. softmax 함수는 입력 벡터를 확률 분포로 변환하는데 사용됩니다.
3. 텐서플로우 코드
코드는 간단한 Stacked RNN 모델을 구성하고, 임의의 입력 데이터를 사용하여 훈련하는 텐서플로우 코드입니다. 각각의 RNN층에서 return_sequences를 True로 설정하였는데 이는 모든 time step에서의 은닉 상태를 출력하겠다는 말입니다. 반대로 False라면 마지막 time step에서만 은닉 상태를 출력하겠다는 말이 됩니다. 마지막 레이어의 RNN에서 return_sequences를 설정하는 것은 문제의 특성과 사용자의 요구에 따라 달라질 수 있습니다.
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, Dense
# 하이퍼파라미터 설정
input_shape = (None, 10)
num_layers = 3
num_units = 50
num_classes = 4
# Stacked RNN 모델 구성
model = Sequential()
# 첫 번째 RNN 층 추가
model.add(SimpleRNN(num_units, return_sequences=True, input_shape=input_shape))
# 두 번째 층부터 마지막 RNN 층까지 추가
for _ in range(num_layers - 2):
model.add(SimpleRNN(num_units, return_sequences=True))
# 마지막 RNN 층 추가
model.add(SimpleRNN(num_units))
# 출력 층 추가
model.add(Dense(num_classes, activation='softmax'))
# 모델 컴파일
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# 모델 요약 출력
model.summary()