Skip to main content

RNN — 순환 신경망

순환 신경망(Recurrent Neural Network, RNN)은 **은닉 상태(Hidden State)**를 유지하며 시퀀스 데이터를 순차적으로 처리하는 아키텍처입니다.

핵심 아이디어

RNN은 이전 시점의 은닉 상태를 현재 시점의 입력과 함께 처리하여, 시퀀스의 맥락 정보를 누적합니다.

동작 방식

수학적 표현

ht=tanh(Whhht1+Wxhxt+bh)h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h) yt=Whyht+byy_t = W_{hy} h_t + b_y
  • hth_t: 시점 tt의 은닉 상태
  • xtx_t: 시점 tt의 입력
  • Whh,Wxh,WhyW_{hh}, W_{xh}, W_{hy}: 가중치 행렬 (모든 시점에서 공유)

구현

import torch
import torch.nn as nn

# PyTorch 내장 RNN
rnn = nn.RNN(
    input_size=10,    # 입력 차원
    hidden_size=20,   # 은닉 상태 차원
    num_layers=1,     # RNN 층 수
    batch_first=True, # (배치, 시퀀스, 특성) 형식
)

# 입력: (배치 크기, 시퀀스 길이, 입력 차원)
x = torch.randn(32, 15, 10)  # 32개 샘플, 15 시점, 10차원
output, h_n = rnn(x)

print(f"출력: {output.shape}")  # (32, 15, 20) — 모든 시점의 은닉 상태
print(f"최종 은닉 상태: {h_n.shape}")  # (1, 32, 20) — 마지막 시점

수동 구현으로 이해하기

class SimpleRNN(nn.Module):
    """RNN의 내부 동작을 보여주는 수동 구현"""
    def __init__(self, input_size, hidden_size):
        super().__init__()
        self.hidden_size = hidden_size
        self.W_xh = nn.Linear(input_size, hidden_size)
        self.W_hh = nn.Linear(hidden_size, hidden_size, bias=False)
        self.tanh = nn.Tanh()

    def forward(self, x):
        batch_size, seq_len, _ = x.shape
        h = torch.zeros(batch_size, self.hidden_size, device=x.device)
        outputs = []

        for t in range(seq_len):
            # h_t = tanh(W_xh * x_t + W_hh * h_{t-1})
            h = self.tanh(self.W_xh(x[:, t]) + self.W_hh(h))
            outputs.append(h.unsqueeze(1))

        return torch.cat(outputs, dim=1), h.unsqueeze(0)

시간 역전파 (BPTT)

RNN의 역전파는 시간을 거슬러 올라가며 수행됩니다. 이를 **시간 역전파(Backpropagation Through Time, BPTT)**라고 합니다. LWhh=t=1TLtWhh=t=1Tk=1tLthtj=k+1thjhj1hkWhh\frac{\partial L}{\partial W_{hh}} = \sum_{t=1}^{T} \frac{\partial L_t}{\partial W_{hh}} = \sum_{t=1}^{T} \sum_{k=1}^{t} \frac{\partial L_t}{\partial h_t} \prod_{j=k+1}^{t} \frac{\partial h_j}{\partial h_{j-1}} \frac{\partial h_k}{\partial W_{hh}}

기울기 소실 문제

j=k+1thjhj1\prod_{j=k+1}^{t} \frac{\partial h_j}{\partial h_{j-1}} 항에서 Tanh의 미분값(1\leq 1)이 반복 곱해지면 기울기가 지수적으로 감소합니다. 이로 인해 먼 과거의 정보를 학습하지 못하는 장기 의존성(Long-term Dependency) 문제가 발생합니다.
기본 RNN은 약 10~20 시점 이상의 장기 의존성을 학습하기 어렵습니다. “The cat, which sat on the mat, ___” 같은 문장에서 멀리 떨어진 주어를 기억해야 하는 경우 성능이 급격히 저하됩니다. 이 문제를 해결하기 위해 LSTM과 GRU가 제안되었습니다.

참고 논문

논문연도핵심 기여
Learning representations by back-propagating errors (Rumelhart et al.)1986역전파를 시퀀스 모델에 적용
On the difficulty of training RNNs (Pascanu et al.)2013기울기 소실/폭주 문제 분석