1. 개요
순환 신경망(Recurrent Neural Network, RNN)은 인공신경망의 한 종류로, 유닛 간의 연결이 순환적 구조를 이루는 것이 특징이다. 이러한 내부의 순환성을 통해 시계열 데이터(Time Series Data)나 자연어와 같이 순서(Sequence)가 있는 데이터, 즉 순차 데이터(Sequential Data)를 처리하는 데 강점을 보인다. 입력과 출력의 길이를 가변적으로 다룰 수 있어 음성 인식, 기계 번역, 텍스트 생성 등 다양한 분야에서 활용되어 왔다.기존의 다층 퍼셉트론(MLP)이나 합성곱 신경망(CNN)과 같은 피드포워드 신경망(Feedforward Neural Network)은 입력 데이터가 네트워크를 한 방향으로만 통과하며, 각 입력 샘플이 독립적으로 처리된다고 가정한다. 하지만 순차 데이터에서는 이전 시점(time step)의 정보가 현재 시점의 처리에 영향을 미치는 경우가 많다. RNN은 이러한 시간적 종속성(Temporal Dependency)을 모델링하기 위해 설계되었으며 이전 시점의 정보를 기억해 현재 시점의 계산에 활용한다.
2. 원리
2.1. 기본 구조
가장 기본적인 형태의 RNN(종종 Vanilla RNN이라고도 불림)은 각 시점 [math(t)]에서 입력 벡터 [math(x_t)]와 이전 시점의 은닉 상태(Hidden State) 벡터 [math(h_{t-1})]을 받아 현재 시점의 은닉 상태 [math(h_t)]를 계산한다. 이 [math(h_t)]는 다음 시점으로 전달되는 동시에, 현재 시점의 출력 [math(y_t)]를 계산하는 데 사용될 수 있다.은닉 상태 업데이트
[math(h_t = f(W_{hh}h_{t-1} + W_{xh}x_t + b_h))]
출력 계산
[math(y_t = g(W_{hy}h_t + b_y))]
여기서 각 기호는 다음을 의미한다.
- [math(x_t)]: 시점 [math(t)]에서의 입력 벡터
- [math(h_{t-1})]: 이전 시점 [math(t-1)]에서의 은닉 상태 벡터
- [math(h_t)]: 현재 시점 [math(t)]에서의 은닉 상태 벡터 (RNN의 '기억' 역할을 수행)
- [math(y_t)]: 현재 시점 [math(t)]에서의 출력 벡터 (필요에 따라 생략될 수도 있음)
- [math(W_{xh})]: 입력 [math(x_t)]에서 은닉 상태 [math(h_t)]로의 가중치 행렬
- [math(W_{hh})]: 이전 은닉 상태 [math(h_{t-1})]에서 현재 은닉 상태 [math(h_t)]로의 가중치 행렬 (순환 가중치)
- [math(W_{hy})]: 은닉 상태 [math(h_t)]에서 출력 [math(y_t)]로의 가중치 행렬
- [math(b_h)]: 은닉 상태 계산을 위한 편향(bias) 벡터
- [math(b_y)]: 출력 계산을 위한 편향 벡터
- [math(f)]: 은닉 상태를 위한 활성화 함수(Activation Function). 주로 하이퍼볼릭 탄젠트나 ReLU가 사용된다.
- [math(g)]: 출력을 위한 활성화 함수. 문제의 종류에 따라 소프트맥스 함수 (분류), 시그모이드 함수 (이진 분류), 또는 항등 함수 (회귀) 등이 사용된다.
핵심은 현재의 은닉 상태 [math(h_t)]가 이전 은닉 상태 [math(h_{t-1})]에 의존한다는 점이다. 이 연결 고리를 통해 정보가 시간의 흐름에 따라 네트워크 내부에 지속적으로 흐르게 된다. 모든 시점에서 동일한 가중치 행렬([math(W_{xh})], [math(W_{hh})], [math(W_{hy})])과 편향([math(b_h)], [math(b_y)])을 공유한다는 것도 중요한 특징인데, 이는 모델이 학습해야 할 파라미터 수를 크게 줄여주고, 가변 길이 시퀀스에 대한 일반화 능력을 높여준다.
2.2. 학습
RNN의 순환적인 구조는 학습 시 역전파 알고리즘을 적용하기 어렵게 만든다. 이를 해결하기 위해 RNN을 시간 축으로 길게 펼쳐서(Unfold) 마치 깊은 피드포워드 신경망처럼 다루는 방법(Unfolding in Time)을 사용한다. 예를 들어, 시퀀스 길이가 [math(T)]라면, RNN은 [math(T)]개의 층(Layer)을 가진 네트워크로 펼쳐지며, 각 층은 특정 시점 [math(t)] ([math(1 \le t \le T)])의 계산을 담당한다. 펼쳐진 네트워크의 각 층은 동일한 가중치를 공유한다.이 펼쳐진 네트워크에 대해 표준적인 역전파 알고리즘을 적용하는 것을 시간을 통한 역전파(Backpropagation Through Time, BPTT)라고 한다. BPTT는 시퀀스의 마지막 시점부터 시작하여 오차(Error)를 계산하고, 이를 시간의 역방향으로 전파시키면서 각 시점의 가중치에 대한 그래디언트(Gradient)를 계산한다.
3. 종류
3.1. 홉필드 네트워크(Hopfield Network)
1982년 존 홉필드(John Hopfield)가 제안한 순환 신경망 모델로, RNN의 전신, 최초의 RNN으로 언급되기도 하나 뜯어보면 RNN과는 목적과 동작 방식이 상당히 다르다.[1] 홉필드 네트워크는 시계열 데이터를 순차적으로 처리해 다음 출력을 예측하는 일반적인 RNN(엘만, 조던, LSTM, GRU 등)과는 달리 정적인 패턴을 저장하고 복원하는 동적 시스템(dynamical system) 성격이 강하 학습 방식 또한 역전파 기반이 아니다.주된 목적은 연상 메모리(associative memory) 또는 콘텐츠 주소 지정 가능 메모리(content-addressable memory) 기능을 구현하는 것으로 RNN하면 흔히 생각하는 시퀀스 처리보다는 패턴 복원 및 저장에 특화되어 있다.
이런 차이점에도 불구하고 홉필드 네트워크는 뉴런 간의 순환적 연결을 가지고 있기도 하고 역사적으로도 이른 시기에 고안되었기 때문에 넓은 의미에서는 RNN에 포함되기도 한다.
3.2. 조던 네트워크(Jordan Network)
1986년 마이클 조던(Michael I. Jordan)이 제안한 단순 순환 신경망 구조.[2] 후술할 엘만 네트워크와 매우 유사하지만 피드백 정보의 출처가 다르다.- 구조 및 특징
현재 타임스텝([math(t)])의 은닉층([math(h_t)]) 계산 시, 현재 입력([math(x_t)])과 함께 이 컨텍스트 유닛 값([math(y_{t-1})])이 사용된다. 수식으로 표현하면 다음과 같다.[3]
- 은닉 상태: [math(h_t = \sigma_h(W_{xh} x_t + W_{yh} y_{t-1} + b_h))]
- 출력: [math(y_t = \sigma_y(W_{hy} h_t + b_y))]
3.3. 엘만 네트워크(Elman Network)
1990년 제프리 엘만(Jeffrey L. Elman)이 제안한 단순 순환 신경망(Simple Recurrent Network, SRN) 구조.[4] RNN의 가장 기본적인 형태로, 시간적 동적 특성을 학습하기 위해 설계되었다.앞서 제안된 조던 네트워크는 외부로 표출된 '결과'인 출력을 피드백하는 반면, 엘만 네트워크는 내부적인 '기억'에 해당하는 은닉 상태를 피드백한다. 일반적으로는 은닉 상태가 출력 상태보다 더 많은 내부 문맥 정보를 담고 있다고 생각되기 때문에 복잡한 시퀀스 학습에는 조던 네트워크는 거의 활용되지 않고 엘만 네트워크나 엘만 네트워크의 발전형(LSTM, GRU 등)이 더 널리 사용된다.
엘만 네트워크는 과거의 정보를 현재 상태 계산에 반영함으로써 시퀀스 데이터 내의 시간적 의존성을 학습할 수 있는 기본적인 메커니즘을 제공했다는 의의가 있다. 이런 의의에도 불구하고 엘만 네트워크는 기울기 소실과 폭주(vanishing/exploding gradient) 문제에 취약해 장기 의존성(long-term dependency)을 학습하는 데는 한계가 있었다. 이는 이후 LSTM, GRU 등의 모델이 등장하는 계기가 되었다.
3.4. 양방향 RNN(Bidirectional RNN, BRNN)
기본적인 RNN은 과거의 정보만 사용하여 현재를 예측한다. 하지만 자연어 처리와 같은 많은 문제에서는 미래의 문맥 또한 현재 단어를 이해하는 데 중요하다. 예를 들어, "나는 오늘 사과를 먹었다"와 "나는 그의 잘못에 대해 사과했다"에서 '사과'의 의미는 뒤따라오는 단어들에 의해 결정된다.양방향 RNN은 이러한 요구를 충족시키기 위해 고안되었다. BRNN은 동일한 입력 시퀀스를 두 개의 독립적인 RNN(주로 LSTM이나 GRU 사용)으로 처리한다. 하나는 정방향(Forward)으로 시퀀스를 처음부터 끝까지 읽고, 다른 하나는 역방향(Backward)으로 시퀀스를 끝에서 처음으로 읽는다. 각 시점 [math(t)]에서의 최종 출력(또는 은닉 상태)은 정방향 RNN의 은닉 상태 [math(\overrightarrow{h_t})]와 역방향 RNN의 은닉 상태 [math(\overleftarrow{h_t})]를 결합(예: 연결, 덧셈, 평균 등)하여 생성된다.
[math(h_t = [\overrightarrow{h_t}; \overleftarrow{h_t}])] (연결의 경우)
이를 통해 각 시점에서 과거와 미래의 정보를 모두 활용할 수 있게 되어, 문맥 이해 능력이 향상된다. 주로 개체명 인식(NER), 품사 태깅(POS tagging) 등 시퀀스 레이블링(Sequence Labeling) 문제에 효과적이다. 단점은 전체 시퀀스를 모두 입력받아야 각 시점의 완전한 은닉 상태를 계산할 수 있으므로, 실시간 처리에는 제약이 있을 수 있다.
3.5. 장단기 기억신경망(Long Short-Term Memory, LSTM)
기본 RNN의 가장 큰 문제점 중 하나는 기울기 소실/폭주 문제(Vanishing/Exploding Gradient Problem)이다. 시퀀스 길이가 길어질 경우, BPTT 과정에서 그래디언트가 반복적으로 곱해지면서 너무 작아지거나(소실) 너무 커져서(폭주) 학습이 제대로 이루어지지 않는 현상이다. 특히 기울기 소실 문제는 RNN이 장기 의존성(Long-term Dependency), 즉 시퀀스 초반의 정보가 후반까지 영향을 미치는 관계를 학습하기 어렵게 만든다.LSTM은 이러한 문제를 해결하기 위해 제안된 구조이다. LSTM은 기본 RNN의 은닉 상태 [math(h_t)] 외에 셀 상태 [math(c_t)](Cell State)라는 별도의 정보 흐름 경로를 도입한다. 셀 상태는 정보가 큰 변화 없이 장기간 보존될 수 있는 '컨베이어 벨트' 역할을 한다. 정보가 셀 상태를 통과하고, 추가되고, 제거되는 과정은 게이트(Gate)라는 메커니즘에 의해 정교하게 제어된다. LSTM의 주요 게이트는 다음과 같다.
- 망각 게이트(Forget Gate, [math(f_t)]): 이전 셀 상태 [math(c_{t-1})]에서 어떤 정보를 버릴지 결정한다.
- 입력 게이트(Input Gate, [math(i_t)]): 어떤 새로운 정보를 셀 상태에 저장할지 결정한다. 이는 다시 두 부분으로 나뉜다.
- 어떤 값을 업데이트할지 결정하는 시그모이드 층 ([math(i_t)])
[math(i_t = \sigma(W_i[h_{t-1}, x_t] + b_i))] - 셀 상태에 추가될 후보 값 벡터([math(\tilde{c}_t)])를 생성하는 tanh 층
[math(\tilde{c}_t = \tanh(W_c[h_{t-1}, x_t] + b_c))] - 셀 상태 업데이트: 이전 셀 상태 [math(c_{t-1})]에서 망각 게이트의 결과([math(f_t))]만큼 정보를 버리고, 입력 게이트의 결과 [math(i_t)]와 후보 값 [math(\tilde{c}_t)]의 곱만큼 새로운 정보를 추가한다.
- 출력 게이트(Output Gate, [math(o_t)]): 업데이트된 셀 상태 [math(c_t)]를 바탕으로 어떤 정보를 은닉 상태 [math(h_t)](이자 출력 [math(y_t)] 계산의 기반)로 내보낼지 결정한다.
[math(f_t = \sigma(W_f[h_{t-1}, x_t] + b_f))]
[math(c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t)]
[math(o_t = \sigma(W_o[h_{t-1}, x_t] + b_o))]
[math(h_t = o_t \odot \tanh(c_t))]
여기서 [math(\sigma)]는 시그모이드 함수, [math(\tanh)]는 하이퍼볼릭 탄젠트 함수, [math(\odot)]는 원소별 곱셈(Element-wise multiplication), [math([h_{t-1}, x_t])]는 두 벡터의 연결(Concatenation)을 의미한다. 게이트들은 시그모이드 함수를 통해 0과 1 사이의 값을 출력하여 정보의 흐름을 조절한다. 이러한 구조 덕분에 LSTM은 기울기 소실 문제에 훨씬 강하며 장기 의존성을 효과적으로 학습할 수 있다.
3.6. GRU(Gated Recurrent Unit)
GRU는 LSTM의 복잡성을 줄이면서 비슷한 성능을 내기 위해 제안된 구조이다. LSTM과 달리 별도의 셀 상태 [math(c_t)]를 사용하지 않고 은닉 상태 [math(h_t)]만으로 정보를 전달한다. 또한, 게이트의 수도 LSTM의 3개(망각, 입력, 출력 게이트) [5]에서 2개로 줄였다.- 리셋 게이트(Reset Gate, [math(r_t)]): 이전 은닉 상태 [math(h_{t-1})]의 정보를 얼마나 '잊을지' 결정한다.
- 업데이트 게이트(Update Gate, [math(z_t)]): 이전 은닉 상태 [math(h_{t-1})]의 정보를 얼마나 유지하고, 새로운 후보 은닉 상태의 정보를 얼마나 반영할지 결정한다. LSTM의 망각 게이트와 입력 게이트의 역할을 동시에 수행한다고 볼 수 있다.
- 후보 은닉 상태([math(\tilde{h}_t)]): 리셋 게이트의 영향을 받아 계산된 새로운 정보이다.
- 은닉 상태 업데이트: 업데이트 게이트 [math(z_t)]를 사용하여 이전 상태 [math(h_{t-1})]와 후보 상태 [math(\tilde{h}_t)]를 조합한다.
[math(r_t = \sigma(W_r[h_{t-1}, x_t] + b_r))]
[math(z_t = \sigma(W_z[h_{t-1}, x_t] + b_z))]
[math(\tilde{h}_t = \tanh(W_h[r_t \odot h_{t-1}, x_t] + b_h))]
[math(h_t = (1 - z_t) \odot h_{t-1} + z_t \odot \tilde{h}_t)]
GRU는 LSTM보다 파라미터 수가 적어 계산 효율성이 높고, 데이터가 적은 경우 과적합(Overfitting) 위험이 낮을 수 있다. 대부분 LSTM과 유사한 성능을 보여주지만 실제로 적용해보면 문제나 데이터셋에 따라 어느 쪽이 더 우수한지는 달라진다.
3.7. Sequence-to-Sequence 모델(Seq2Seq)
일리야 수츠케버(Ilya Sutskever)et al.의 Sequence to Sequence Learning with Neural Networks(2014)에서 처음 그 개념이 제안되었다.RNN(주로 LSTM이나 GRU)을 기반으로 하는 Seq2Seq 모델은 입력 시퀀스와 출력 시퀀스의 길이가 다를 수 있는 문제를 다루기 위해 설계되었다. 대표적인 예가 기계 번역(영어 문장 입력 -> 프랑스어 문장 출력)이다. Seq2Seq 모델은 크게 인코더(Encoder)와 디코더(Decoder)라는 두 개의 RNN으로 구성된다.
1. 인코더: 입력 시퀀스(예: 원본 언어 문장)를 읽어들여 전체 내용을 압축한 문맥 벡터(Context Vector) 또는 사고 벡터(Thought Vector)를 생성한다. 이 벡터는 보통 인코더 RNN의 마지막 은닉 상태이다.
2. 디코더: 인코더가 생성한 문맥 벡터를 초기 은닉 상태로 받아, 출력 시퀀스(예: 번역된 문장)를 한 단계씩 생성한다. 각 시점에서 디코더는 이전에 생성된 출력과 현재의 은닉 상태를 바탕으로 다음 출력을 예측하고, 이 정보를 다음 시점의 은닉 상태 계산에 사용한다.
Seq2Seq 모델은 기계 번역뿐만 아니라 챗봇, 텍스트 요약, 이미지 캡셔닝(Image Captioning) 등 다양한 생성 문제에 성공적으로 적용되었다. 이후 어텐션 메커니즘의 도입으로 성능이 크게 향상되었는데, 이 때 어텐션 메커니즘이 적용된 RNN based Seq2Seq model에서 RNN을 생략하고 어텐션 메커니즘만 남기자는 생각이 트랜스포머 모델의 출발점이 되었다.
4. 장점
- 순차 데이터 처리 능력: 시간적 순서와 의존성을 가진 데이터를 자연스럽게 모델링할 수 있다.
- 가변 길이 시퀀스 처리: 입력 및 출력의 길이에 제약이 비교적 자유롭다. (이론적으로는 가능하나, 실제로는 장기 의존성 문제 등으로 한계가 있음)
- 파라미터 공유: 모든 시점에서 동일한 가중치를 사용하므로, 모델의 파라미터 수가 시퀀스 길이에 비례하여 증가하지 않아 효율적이다.
5. 단점 및 한계
- 기울기 소실/폭주: 기본 RNN은 긴 시퀀스 학습 시 그래디언트가 불안정해지는 문제가 심각하다. LSTM과 GRU가 이를 완화했지만 완전히 해결된 것은 아니다. 특히 매우 긴 장기 의존성 학습에는 여전히 어려움이 있다.
- 순차적 계산의 비효율성: 각 시점의 계산이 이전 시점의 계산 결과(은닉 상태)에 의존하기 때문에, 전체 시퀀스에 대한 계산을 병렬화하기 어렵다. 이는 특히 긴 시퀀스 처리 시 학습 및 추론 속도를 저하시키는 요인이 된다. CNN이나 트랜스포머는 RNN에 비해 병렬 처리에 더 유리하다.
- 장기 의존성 문제: LSTM, GRU가 개선했지만, 여전히 수백, 수천 스텝 떨어진 정보 간의 의존성을 완벽하게 포착하는 데는 한계가 있었다. 어텐션 메커니즘이 이 장기 의존성 문제를 해결하는 데 도움을 주었지만 오히려 어텐션 메커니즘 자체가 너무 강력했던 바람에 RNN 컴포넌트는 제거하고 어텐션 레이어를 남긴 트랜스포머 알고리즘의 탄생으로 이어졌다. 이는 이후 상당 수의 적용 분야에서 트랜스포머에 의해 RNN이 대체되어 버리는 결과를 낳는다.
6. 활용 분야
RNN과 그 변형들은 다양한 분야에서 중요한 역할을 해왔다.- 자연어 처리(NLP)
- 기계 번역 (Seq2Seq 모델)
- 언어 모델링
- 텍스트 생성 (소설, 코드 등)
- 감성 분석
- 개체명 인식 (NER)
- 질의응답 시스템 (챗봇)
- 음성 인식
- 음향 신호의 텍스트 변환
- 시계열 예측
- 주가 예측
- 날씨 예측
- 산업 설비 이상 감지
- 컴퓨터 비전
- 비디오 분석 (프레임 간의 시간적 관계 분석)
- 이미지 캡셔닝
- 필기체 인식
트랜스포머 모델의 등장 이후 일부 NLP 분야에서는 RNN의 사용 빈도가 줄어들었지만, 특정 응용 분야나 경량 모델이 필요한 환경에서는 여전히 유용하게 사용되고 있다. 또한, RNN 구조 자체가 순차적 데이터 처리의 근본적인 아이디어를 제공했다는 점에서 중요한 의미를 갖는다.
7. 관련 문서
[1] Hopfield, J. J. (1982). Neural networks and physical systems with emergent collective computational abilities. Proceedings of the National Academy of Sciences, 79(8), 2554–2558.[2] Jordan, M. I. (1986). Serial order: A parallel distributed processing approach. Institute for Cognitive Science Report 8604, University of California, San Diego.[3] [math(\sigma)]는 활성화 함수를 뜻한다[4] Elman, J. L. (1990). Finding Structure in Time. Cognitive Science, 14(2), 179–211.[5] 실제로는 내부적으로 4개의 연산이다.