순환 신경망 · 시퀀스 모델

LSTM은 어떻게 기억하는가

순환 신경망이 긴 문맥을 잃어버리는 이유부터, 셀 상태와 세 개의 게이트가 그 문제를 어떻게 우회하는지까지. 게이트를 손으로 돌려 보고, 사람이 직접 가중치를 심은 LSTM이 괄호를 세는 과정을 한 글자씩 따라가며 확인합니다.

이 자료는 Christopher Olah의 Understanding LSTM Networks(2015)를 바탕으로 한 한국어 번역·보충 설명 자료입니다. 원문이 다루는 개념과 설명 순서를 그대로 따라가되, 본문·그림·데모를 한국어 학습용으로 새로 작성하고 직접 조작할 수 있는 인터랙티브 데모 9종을 더했습니다. 원문도 함께 읽어 보시길 권합니다.

LEVEL 1 · 입문
상태를 들고 다니는 신경망

보통의 신경망은 입력 하나를 받아 출력 하나를 내고 끝납니다. 방금 무엇을 봤는지는 남지 않습니다. 영화의 한 장면만 떼어 놓고 “지금 무슨 일이 벌어지는가”를 판정하려는 것과 같습니다. 앞 장면을 모르면 판단할 수 없는 질문이 세상에는 너무 많습니다.

순환 신경망(RNN)은 여기에 아주 작은 장치 하나를 더합니다. 계산 결과의 일부를 다음 입력과 함께 자기 자신에게 돌려주는 것입니다. 이 되먹임 값이 “지금까지 본 것의 요약”, 즉 은닉 상태 h입니다.

ht = tanh(Wh ht−1 + Wx xt + b)  ·   yt = Wy ht xt = t번째 입력 · ht = t번째까지의 요약 · 모든 스텝이 같은 W를 쓴다

루프가 달린 그림은 신비해 보이지만, 시간축으로 펼쳐 보면 정체가 드러납니다. 같은 셀을 복사해 옆으로 이어 붙인 사슬입니다. 파라미터를 공유하기 때문에 입력이 5개든 500개든 같은 셀 하나로 처리할 수 있고, 바로 이 점이 시퀀스 모델로서 RNN의 힘이었습니다.

데모 1 — 루프를 펼쳐 보기

왼쪽 루프 표기와 오른쪽 펼친 사슬은 완전히 같은 계산입니다. ▶ 재생을 누르면 상태 h가 왼쪽에서 오른쪽으로 전달되는 순서를 따라갑니다.

2014~2016년 무렵 RNN은 음성 인식, 언어 모델링, 기계 번역, 이미지 캡셔닝, 필기 인식에서 잇달아 성과를 냈습니다. 당시 이 흐름을 가장 널리 알린 글이 Andrej Karpathy의 The Unreasonable Effectiveness of Recurrent Neural Networks입니다. 그런데 그 성과들의 거의 전부는 순수한 RNN이 아니라 LSTM이라는 변형으로 이룬 것이었습니다. 왜 그랬는지가 이 글의 주제입니다.

먼 과거는 왜 잊히는가

다음 단어를 맞히는 문제를 생각해 봅시다.

가까운 문맥으로 충분한 경우
“구름은 하늘에 떠 있다.” — ‘하늘’을 맞히는 데 필요한 단서는 바로 앞 몇 단어입니다. 거리 1~3.

먼 문맥이 필요한 경우
“나는 프랑스에서 나고 자랐다. … (수십 단어 뒤) … 그래서 나는 프랑스어를 유창하게 한다.” — ‘어떤 언어인가’는 한참 앞 문장에만 있습니다. 거리 30, 50, 100.

가까운 경우는 RNN이 잘합니다. 문제는 두 번째입니다. 그리고 이건 표현력의 문제가 아닙니다. 이론적으로는 적절한 W만 주면 RNN도 100스텝 전 정보를 나를 수 있습니다. 문제는 그 W를 경사 하강법으로 찾아낼 수 없다는 데 있습니다.

이유는 역전파의 구조에 있습니다. ht가 ht−k에 대해 갖는 민감도는 중간 단계들의 야코비안을 k번 연달아 곱한 것입니다.

∂ht / ∂ht−k = ∏j=1..k Wh⊤ · diag(tanh′)   ⟹   크기 ≈ λk λ는 반복해서 곱해지는 행렬의 실효 배율. tanh′ ≤ 1이라 λ < 1이 되기 쉽다.

이 진단은 Sepp Hochreiter의 1991년 학위논문에서 처음 정리되었고, Yoshua Bengio, Patrice Simard, Paolo Frasconi가 1994년 논문에서 “장기 의존성 학습이 왜 근본적으로 어려운가”를 규명했습니다. 기억이 사라지는 게 아니라 학습 신호가 도달하지 못한다는 점이 핵심입니다.

데모 2 — 신호는 몇 걸음이나 살아남는가

세로축은 로그 스케일입니다. 배율 λ를 1보다 조금만 낮춰도 파란 곡선(바닐라 RNN)은 순식간에 바닥으로 떨어집니다. 초록 곡선은 LSTM의 셀 상태 경로로, 망각 게이트 f가 그대로 배율이 됩니다. f를 1.00에 두면 곡선이 평평해집니다 — 100스텝을 가도 신호가 줄지 않는다는 뜻입니다.

바닐라 RNN — λk LSTM 셀 상태 — fk 실질적 소멸선 (10⁻³)
RNN 신호가 1/1000 되는 거리—
LSTM 신호가 1/1000 되는 거리—
거리 100에서의 신호비—
문제의 정확한 형태

RNN의 상태는 매 스텝 행렬 곱 + tanh 압축으로 완전히 새로 계산됩니다. 그래서 과거의 흔적이 남으려면 그 곱셈 사슬을 통과해야 하고, 사슬은 지수적으로 감쇠합니다. 해법은 “곱을 잘 조절하자”가 아니라 “곱셈 사슬을 통과하지 않는 길을 따로 내자”였습니다.

LEVEL 2 · 학부
LSTM의 핵심 — 더하기로만 갱신되는 기억

LSTM(Long Short-Term Memory)은 Sepp Hochreiter와 Jürgen Schmidhuber가 1997년에 제안했습니다. 처음부터 장기 의존성을 겨냥해 설계된 구조이며, 이후 Felix Gers, Fred Cummins, Santiago Fernández, Justin Bayer, Daan Wierstra, Julian Togelius, Faustino Gomez, Matteo Gagliolo, Alex Graves 등 여러 연구자의 개선이 쌓여 오늘날 우리가 쓰는 형태가 되었습니다.

발상의 전환은 한 문장으로 요약됩니다.

한 문장

상태를 매 스텝 새로 계산하지 말고, 그대로 흘려 보내면서 필요한 만큼만 지우고 필요한 만큼만 더하자.

이를 위해 LSTM은 은닉 상태 ht 외에 셀 상태 Ct라는 두 번째 상태를 둡니다. 셀 상태는 셀을 관통해 지나가는 별도의 기억 레일입니다. 이 레일 위에서 벌어지는 연산은 딱 두 가지뿐입니다.

행렬 곱도, tanh 압축도 없습니다. 그래서 남길 비율이 1에 가까우면 ∂Ct/∂Ct−1 ≈ 1이 되고, 역전파 신호가 감쇠 없이 수십·수백 스텝을 거슬러 올라갑니다. 몇 년 뒤 ResNet의 스킵 연결이 깊이 방향에서 똑같은 일을 하게 되는데(how-resnet-work), LSTM은 시간 방향에서 그 아이디어를 먼저 쓴 셈입니다.

게이트 — 데이터가 스스로 여닫는 밸브

“얼마나 지울지, 얼마나 쓸지”를 결정하는 장치가 게이트입니다. 구조는 놀랍도록 단순합니다. 시그모이드 층 하나 + 원소별 곱 하나.

g = σ(W[ht−1, xt] + b)  ∈ (0, 1)  ·   통과량 = g ⊙ 값 0이면 완전 차단, 1이면 완전 통과, 그 사이면 부분 통과. 성분마다 값이 다르므로 밸브 n개가 독립적으로 열리고 닫힌다.

중요한 것은 이 값이 고정된 상수가 아니라 매 스텝 입력에 따라 다시 계산된다는 점입니다. “지금 이 단어를 봤으니 3번 성분은 지우고 7번 성분은 유지한다” 같은 판단을 모델이 스스로 학습합니다.

데모 3 — 게이트는 밸브다

왼쪽은 시그모이드 곡선, 오른쪽은 8개 성분을 가진 벡터가 이 밸브를 통과한 결과입니다. 슬라이더는 게이트의 입력값(활성화 전)이며, 개별 성분 편차 슬라이더를 올리면 성분마다 밸브가 다르게 열리는 실제 상황이 됩니다.

LSTM 한 스텝에는 이런 층이 네 개 들어갑니다. 게이트 세 개(망각·입력·출력)와, 무엇을 쓸지 만드는 후보 생성기 하나(tanh)입니다. 바닐라 RNN이 tanh 층 하나로 끝나는 것과 비교하면 딱 그만큼이 차이의 전부입니다.

한 스텝을 네 단계로

표기를 정합니다. 각 층은 이전 은닉 상태와 현재 입력을 이어 붙인 [ht−1, xt]를 받고, 각자의 가중치 W와 편향 b를 갖습니다. ⊙는 원소별 곱입니다.

① 망각 게이트 — 무엇을 지울 것인가

ft = σ(Wf[ht−1, xt] + bf) 셀 상태의 각 성분을 얼마나 남길지. 0이면 그 기억을 버리고, 1이면 그대로 보존한다.

언어 모델이라면 이런 상황입니다. 셀 어딘가에 “현재 주어는 단수 남성”이라는 정보가 저장돼 있는데, 새 문장의 새 주어가 등장했습니다. 이제 옛 주어 정보는 방해만 되므로 해당 성분을 0으로 밀어 자리를 비웁니다.

② 입력 게이트와 후보 — 무엇을 새로 쓸 것인가

it = σ(Wi[ht−1, xt] + bi)  ·   C̃t = tanh(WC[ht−1, xt] + bC) 쓸지 말지는 i가, 쓸 내용은 C̃가 정한다. 후보가 tanh(−1~1)이므로 더할 수도 뺄 수도 있다.

두 역할을 굳이 나눈 이유가 있습니다. “쓸 만한 값”을 만드는 일과 “지금 그걸 쓸 때인가”를 판단하는 일은 서로 다른 문제이기 때문입니다. 새 주어의 성·수 정보를 만들어 두고(C̃), 방금 비운 자리에 그것을 밀어 넣습니다(i).

③ 셀 상태 갱신 — 지우기와 쓰기를 한 줄로

Ct = ft ⊙ Ct−1 + it ⊙ C̃t 앞 항이 “남기기”, 뒤 항이 “더하기”. 이 한 줄이 LSTM 전체에서 가장 중요한 식이다.

여기서 새 상태를 만드는 데 행렬 곱이 쓰이지 않았다는 점을 다시 확인해 두세요. 앞 절에서 본 소멸의 원인이 이 경로에는 없습니다.

④ 출력 게이트 — 무엇을 밖으로 내보낼 것인가

ot = σ(Wo[ht−1, xt] + bo)  ·   ht = ot ⊙ tanh(Ct) 셀에 담긴 내용을 tanh로 −1~1에 맞춘 뒤, 지금 필요한 부분만 골라 내보낸다.

셀에 있는 것을 전부 내보내지 않는다는 점이 포인트입니다. 주어가 단수인지 복수인지는 동사를 낼 차례에만 꺼내면 됩니다. 그때까지는 셀 안에 조용히 보관해 두었다가, 필요한 스텝에서 출력 게이트를 열어 꺼냅니다.

C와 h를 나눈 이유

C는 장부입니다 — 길게 보관하는 기억, 밖으로 직접 나가지 않음. h는 이번 스텝의 답변입니다 — 위층으로 올라가고, 다음 스텝의 게이트를 결정하는 입력이 됨. 하나의 상태로 이 두 역할을 겸하게 하면, 지금 출력하고 싶지 않은 정보까지 매번 드러나게 됩니다.

데모 4 — 셀 한 스텝 따라가기

단계 버튼을 누르면 해당 계산에 참여하는 경로만 밝게 표시됩니다. 위쪽 굵은 가로선이 셀 상태 레일이고, 그 위에는 ⊗(지우기)와 ⊕(더하기)만 놓여 있다는 점을 확인해 보세요.

↔ 그림이 잘려 보이면 가로로 밀어서 볼 수 있습니다.

데모 5 — 게이트 조작기

성분 하나만 떼어 놓고 숫자로 확인합니다. 프리셋을 눌러 게이트 조합이 만드는 네 가지 기본 동작을 먼저 보고, 오른쪽 그래프에서 그 설정을 20스텝 반복했을 때 기억이 어떻게 변하는지 확인하세요.

Ct = f·Ct−1 + i·C̃—
ht = o·tanh(Ct)—
20스텝 뒤 C—

파라미터는 몇 개인가

층이 네 개이고 각 층은 [ht−1, xt](차원 n+m)를 받아 n차원을 내므로, 총 파라미터는 아래와 같습니다. 같은 은닉 크기라면 바닐라 RNN의 정확히 4배입니다.

4 · (n·m + n·n + n) m = 입력 차원, n = 은닉 차원. 게이트 3개 + 후보 1개 = 4

손으로 가중치를 심어 보기 — 괄호 세는 LSTM

“셀 상태가 기억을 나른다”는 말을 확인하는 가장 빠른 방법은, 학습을 시키는 대신 사람이 직접 게이트 값을 정해 보는 것입니다. 아래 규칙은 학습된 가중치가 아니라 우리가 손으로 심은 것이지만, 계산 자체는 앞 절의 네 식을 그대로 따릅니다.

입력 문자fiC̃결과
(11+1깊이 +1 — 자리를 유지한 채 더한다
)11−1깊이 −1 — 후보가 음수면 빼기가 된다
.000문장 끝 — 망각 게이트를 닫아 장부를 초기화
그 밖의 문자100아무 일도 하지 않음 — 기억은 그대로 통과

이 네 줄이면 끝입니다. 셀 상태 C는 정확히 “지금 열려 있는 괄호의 개수”가 되고, 문자가 100개든 1,000개든 값이 흐려지지 않습니다. 세는 데 필요했던 것은 정교한 곱셈이 아니라 지워지지 않는 덧셈 자리였습니다.

데모 6 — 한 글자씩 실행하기

문자열을 직접 고쳐 보세요. 위 그래프는 LSTM 셀 상태 C(괄호 깊이)이고, 아래는 매 스텝의 게이트 값입니다. 회색 점선은 같은 신호를 tanh로 압축하는 바닐라식 상태로, ±1에서 포화되어 깊이 2와 4를 구별하지 못합니다.

↔ 문자열이 길면 가로로 밀어서 볼 수 있습니다.

셀 상태 C (깊이) 망각 f 입력 i tanh 압축 상태
최종 깊이—
도달한 최대 깊이—
tanh 상태의 최대값—
실제로 학습된 LSTM에서도 이런 해석 가능한 성분이 관찰됩니다. Karpathy, Johnson, Fei-Fei(2015)는 문자 단위 LSTM에서 따옴표 안인지 밖인지를 추적하는 셀, 줄 길이를 세는 셀, 코드의 들여쓰기 깊이에 반응하는 셀을 찾아냈습니다. 우리가 손으로 심은 것과 같은 종류의 회로를 모델이 스스로 만들어 낸 것입니다.

LEVEL 3 · 심화
변형들

지금까지 본 것은 가장 표준적인 형태입니다. 실무와 논문에서 마주치게 될 주요 변형을 정리합니다.

① 핍홀 연결 (peephole)

Gers와 Schmidhuber가 2000년에 제안했습니다. 기본형에서 게이트는 ht−1와 xt만 보고 결정을 내리는데, 정작 자기가 조작하려는 대상인 셀 상태는 보지 못합니다. 핍홀은 게이트 입력에 셀 상태를 직접 끼워 넣어 이 “구멍”을 냅니다.

ft = σ(Wf[Ct−1, ht−1, xt] + bf) 망각·입력 게이트는 Ct−1을, 출력 게이트는 이미 갱신된 Ct를 본다. 세 게이트 전부가 아니라 일부에만 넣는 변종도 흔하다.

타이밍이 중요한 과제(정확한 간격을 세어야 하는 문제 등)에서 이득이 보고되었습니다.

② 망각·입력 게이트 결합

“무엇을 지울지”와 “무엇을 쓸지”를 따로 정하는 대신 한 번에 정합니다. 자리를 비울 때만 새것을 쓰고, 유지할 때는 새것을 쓰지 않는다는 규칙입니다.

Ct = ft ⊙ Ct−1 + (1 − ft) ⊙ C̃t 게이트 층이 하나 줄어 파라미터와 계산이 절약된다.

③ GRU (Gated Recurrent Unit)

Cho 등이 2014년에 제안한, 지금까지 나온 단순화 중 가장 널리 쓰이는 형태입니다. 두 가지를 과감하게 정리했습니다. 셀 상태와 은닉 상태를 하나로 합치고, 망각과 입력을 업데이트 게이트 하나로 묶었습니다. 여기에 “과거 상태를 얼마나 참고해 후보를 만들지” 정하는 리셋 게이트가 더해집니다.

zt = σ(Wz[ht−1, xt]) ·  rt = σ(Wr[ht−1, xt])
h̃t = tanh(W[rt ⊙ ht−1, xt]) ·  ht = (1−zt) ⊙ ht−1 + zt ⊙ h̃t z = 업데이트 게이트(망각+입력), r = 리셋 게이트. 게이트 2개, 상태 1개.

상태가 하나뿐이라 “장부와 답변의 분리”는 사라졌지만, 마지막 줄이 여전히 가중 평균 형태의 덧셈 갱신이라는 점은 같습니다. 소멸을 막는 핵심 성질은 그대로 유지한 셈입니다. 파라미터는 LSTM의 3/4입니다.

데모 7 — 구조와 파라미터 비교

같은 입력·은닉 차원에서 세 구조의 파라미터 수를 비교합니다. 은닉 차원을 키우면 n2 항이 지배하면서 셋의 비율이 4 : 3 : 1로 수렴합니다.

LSTM—
GRU—
바닐라 RNN—
GRU / LSTM—

④ 그 밖의 방향

그래서 무엇이 제일 좋은가

이 질문에는 두 편의 대규모 실험이 답을 냈습니다.

정리

변형은 많지만 “게이트로 조절되는 덧셈형 상태”라는 뼈대는 모두 같습니다. 실무에서는 LSTM과 GRU 중 아무거나 골라도 대개 무방하고, 파라미터·속도가 아쉬우면 GRU, 안전한 기본값이 필요하면 LSTM(망각 편향 1)이 무난합니다.

LEVEL 3 · 심화
실제 문장은 어디에 담기는가

데모 6의 게이트 값은 우리가 손으로 심은 것이었습니다. 그래서 셀 상태가 “괄호 깊이”라는 사실을 처음부터 알고 있었습니다. 그렇다면 아무것도 심어 주지 않고 영어 문장으로 학습시킨 LSTM은 무엇을 어디에 적어 둘까요? 이 절의 데모는 사전 학습된 가중치를 내려받지 않고, 짧은 영어 말뭉치로 12차원 LSTM을 이 브라우저에서 직접 학습시킨 뒤 그 내부를 열어 봅니다.

저장소는 두 군데로 나뉜다

“문장이 어떻게 보관되는가”가 헷갈리는 가장 큰 이유는, LSTM 안에 성격이 전혀 다른 저장소가 두 개 있기 때문입니다. 하나는 모든 문장이 함께 쓰는 붙박이이고, 하나는 지금 읽는 문장에만 딸린 메모장입니다.

붙박이 · 학습이 끝나면 고정

가중치 Wf Wi WC Wo

—
개의 실수 · 어떤 문장이 들어와도 변하지 않음
  • 게이트 3개 + 후보 1개—
  • 다음 문자 출력층—

여기 담긴 것은 문장이 아니라 문장을 읽는 법입니다. 영어의 철자 규칙, 단어가 공백으로 끝난다는 사실 같은 것.

메모장 · 글자마다 새로 쓰임

셀 상태 Ct + 은닉 상태 ht

—
개의 실수 · 지금까지 읽은 문장 전체가 여기 들어 있음
  • 셀 상태 C — 장부—
  • 은닉 상태 h — 답변—

문장이 20자든 2,000자든 이 크기는 그대로입니다. 늘어나지 않습니다. 순환 신경망의 힘이자 한계가 여기입니다.

문장을 넣으면 압축률이 여기에 표시됩니다.
“몇 글자까지 기억하나요?” — 순전파에는 상한이 없습니다. C와 h는 첫 글자부터 끊김 없이 이어지므로, 100번째 글자를 읽는 순간의 장부에는 앞선 99글자가 전부 접혀 들어가 있습니다. 진짜 한계는 “몇 글자”라는 창이 아니라 12개라는 용량과 점진적 감쇠이고, 그것을 재는 것이 데모 8의 마지막 그래프입니다. 다만 학습 쪽에는 상한이 하나 있습니다 — 이 데모는 절단 BPTT(25글자)로 학습하므로 기울기가 25글자까지만 거슬러 흐르고, 따라서 모델이 배울 수 있었던 의존 거리도 그 언저리입니다. 추론할 때 상태가 흐르는 거리와는 별개의 이야기입니다.

여기서 질문의 답이 나옵니다. 문장은 어디에도 글자 그대로 저장되지 않습니다. 글자는 어휘 크기만큼의 원-핫 벡터로 한 번 들어왔다가, 게이트를 통과하며 셀 상태의 12개 자리에 덧셈으로 누적되고 그대로 사라집니다. 남는 것은 “지금까지 읽은 것”을 12개 숫자로 요약한 장부 하나뿐입니다.

데모 8 — 영어 문장이 격자에 새겨지는 것을 보기

격자의 가로는 문장의 글자, 세로는 셀 상태의 12개 성분입니다. 칸 하나가 그 순간 그 자리에 적혀 있는 숫자 하나 — 문장 전체가 이 격자로 보관됩니다. 칸을 클릭하면 그 글자·그 성분의 계산을 아래에서 뜯어 봅니다.

격자에 표시할 값

↔ 문장이 길면 가로로 밀어서 볼 수 있습니다.

고른 칸 한 개에서 벌어지는 일

글자 — — 셀 성분 —

셀 상태 갱신 — 옛 장부를 f배로 남기고, 새 후보를 i배로 얹는다

—
옛 장부에서 온 몫 —— 이번 글자가 새로 쓴 몫

막대는 결과값에서 각자가 차지한 몫입니다 — 게이트 값 자체(f, i)와는 다른 수치입니다.

은닉 상태 — 장부에서 지금 꺼내 보일 부분만 o배로 내보낸다

—

한 글자는 얼마나 오래 남는가

같은 문장을 두 벌 흘려보냅니다. 두 문장은 딱 한 글자만 다릅니다 — 아래 그림의 A행과 B행이 그 두 문장이고, 빨간 띠가 다른 글자입니다. 그 뒤로 두 LSTM의 장부가 얼마나 벌어진 채로 남아 있는지를 재면, 그것이 곧 “바꾼 그 글자를 아직 기억하고 있는 정도”입니다. 세로축은 바뀐 직후를 100%로 둔 상대 크기입니다 — 두 곡선을 각자의 출발점 기준으로 재기 때문에, 값의 크기가 아니라 얼마나 오래 버티는지를 비교하게 됩니다. 곡선이 도중에 다시 솟는 것은 정상입니다. 같은 단어가 또 나오면 두 장부의 차이가 되살아나기도 합니다.

↔ 문장이 길면 가로로 밀어서 볼 수 있습니다.

셀 상태 C가 벌어진 정도 은닉 h가 벌어진 정도 10% 선 — 이 아래면 거의 잊은 것
문장 끝에서 C에 남은 흔적—
문장 끝에서 h에 남은 흔적—
C가 10% 아래로 내려가기까지—
두 곡선을 비교해 보세요. 파란 선(C)이 보라 선(h)보다 오래 버팁니다. 셀 상태는 Ct = f ⊙ Ct−1 + i ⊙ C̃ — 원소별 곱 하나와 덧셈 하나만 거치므로 f가 1에 가까우면 흔적이 거의 손실 없이 다음 칸으로 넘어갑니다. 반면 h는 매 스텝 출력 게이트로 한 번 더 걸러지기 때문에, 장부에는 남아 있어도 밖으로는 안 보일 수 있습니다. §4에서 C와 h를 나눈 이유가 이 두 선의 간격입니다.

어느 자리가 무엇을 맡게 되었나

여기까지 보면 자연스럽게 다음 질문이 나옵니다. 그래서 12개 자리 각각은 무엇을 적고 있나? 확인하는 방법이 있습니다. 말뭉치 전체를 흘려보내면서 각 셀의 값을 기록하고, 그것을 사람이 이미 아는 사실—“지금 단어가 끝나 가는가”, “지금 따옴표 안인가”—과 나란히 놓고 얼마나 함께 움직이는지를 재면 됩니다.

데모 9 — 셀 해석기: 아무도 시키지 않은 역할 분담 찾기

데모 8에서 학습한 바로 그 모델입니다. 셀 12개 각각이 아래 고른 사실과 얼마나 함께 움직이는지를 말뭉치 전체(1,200여 글자)에서 피어슨 상관계수로 재 순위를 매깁니다. +1이면 그 사실이 참일 때 값이 크고, −1이면 반대로 움직이며, 0이면 무관합니다. 막대를 클릭하면 그 셀의 값을 아래 문장 위에 직접 칠해 보여줍니다.

무엇과 비교할까

셀 12개의 순위 — 절댓값이 큰 순. 클릭해서 고를 수 있습니다

고른 셀의 값을 문장 위에 칠하기

큰 음수 0 근처 큰 양수 색은 데모 8의 격자와 같은 규칙입니다

“다음 글자가 공백인가”를 골라 보면 한 자리가 눈에 띄게 앞섭니다. 그 셀을 칠해 보면 단어 안에서 값이 오르다가 공백에서 꺾이는 톱니가 그대로 보입니다. 어디에도 cat이라는 문자열은 저장되어 있지 않습니다. 매 글자마다 조금씩 더하다가 공백에서 망각 게이트가 닫히며 장부를 꺾는 계수기 하나가 만들어졌을 뿐이고, 우리가 “단어”라고 부르는 것이 거기에 대응합니다.

중요한 것은 아무도 그 자리에 역할을 지정하지 않았다는 점입니다. 모델의 유일한 임무는 다음 글자 맞히기였습니다. “지금 단어가 끝나 간다”를 적어 두면 그 예측이 쉬워지고, 그래서 손실이 줄고, 그래서 경사하강이 수천 번에 걸쳐 그 자리를 그렇게 쓰도록 밀었습니다. 의미는 설계된 것이 아니라 쓸모 있어서 생겨납니다. 데모 6에서 우리가 손으로 심었던 것과 같은 종류의 회로를, 모델이 스스로 만들어 낸 것입니다.

“지금 따옴표 안인가”를 골라 보면 성격이 다른 셀이 올라옵니다. 여는 따옴표는 수십 글자 전에 지나갔을 수 있습니다. 그 사실을 계속 붙들려면 그동안 망각 게이트를 계속 열어 두어야 합니다. 글자 수준이 아니라 문장 수준의 기억이고, 데모 8의 마지막 그래프에서 파란 선이 오래 버티던 이유가 바로 이것입니다.

주의해서 읽을 것. 한 셀이 한 개념을 깔끔하게 맡는 일은 오히려 드뭅니다. 위 순위를 보면 같은 셀이 “공백”과 “단어 길이”와 “마침표”에 동시에 걸리고, 2·3등 셀도 상당한 값을 갖습니다. 대부분의 정보는 12개 자리에 뒤섞여 흩어져 있습니다(분산 표현). 상관계수가 0.7 언저리에서 그치는 것도 이 때문이며, 은닉 12차원에 말뭉치 1,200자짜리 장난감 모델이라는 점도 큽니다. Karpathy, Johnson, Fei-Fei(2015)가 훨씬 큰 문자 단위 LSTM에서 찾아낸 따옴표 셀은 거의 이진 스위치처럼 딱 떨어집니다 — 원리는 같고 선명도만 다릅니다.
그래서 “문장을 저장한다”가 아닙니다. 실수 24개에 문장을 글자 그대로 담을 수는 없습니다. 담기는 것은 다음 글자를 맞히는 데 필요한 사실 수십 개뿐이고 나머지는 버려집니다. 모델 안에 “단어”라는 것은 없습니다. 12차원 공간의 한 점이 있고, cat을 다 읽은 뒤의 점과 dog을 다 읽은 뒤의 점이 비슷한 영역에 놓일 뿐입니다 — 둘 다 “다음은 공백”을 잘 예측하게 해 주기 때문입니다. 우리가 단어라고 부르는 것은 그 영역입니다. 그리고 이 공간이 고정 크기이기 때문에 문장이 길어지면 오래된 사실부터 밀려납니다. 다음 절에서 볼 어텐션은 바로 이 압축을 포기하는 데서 출발합니다.

그 뒤에 무슨 일이 있었나

LSTM은 “상태 하나를 잘 유지하는 법”에 대한 답이었습니다. 다음 큰 걸음은 질문 자체를 바꿉니다. 왜 모든 것을 상태 하나에 욱여넣어야 하는가?

어텐션(attention)의 발상이 그것입니다. 매 스텝 하나의 요약 벡터에 의존하는 대신, 지금까지의 모든 정보에 접근해 그때그때 필요한 곳을 골라 보게 합니다. Xu 등(2015)의 이미지 캡셔닝은 이를 눈으로 보여 준 초기 사례입니다. 모델이 단어 하나를 생성할 때마다 이미지의 어느 부분을 보고 있는지가 그대로 드러납니다.

같은 시기의 다른 갈래들도 있었습니다.

그리고 2017년, Transformer는 순환 자체를 걷어내고 어텐션만 남겼습니다(how-attention-works). 그렇다면 LSTM을 지금 배울 이유가 있을까요? 있습니다. 게이트로 조절되는 덧셈형 상태라는 아이디어는 사라지지 않고 계속 재등장합니다. ResNet의 스킵 연결, Highway Network, GLU 계열의 게이팅, 그리고 최근 상태공간 모델(Mamba 등)의 선택적 상태 갱신까지 — 모두 같은 뿌리에서 나온 장치들입니다.

핵심 정리

  1. RNN은 상태 h를 다음 스텝으로 넘겨 문맥을 유지한다. 펼치면 파라미터를 공유하는 사슬이다.
  2. 장기 의존성이 어려운 이유는 표현력이 아니라 최적화다. 같은 야코비안이 k번 곱해져 신호가 λk로 사라진다.
  3. 셀 상태 C는 원소별 곱과 덧셈만 거치는 별도의 기억 레일이다. 그래서 ∂Ct/∂Ct−1 = f가 되고, f≈1이면 신호가 감쇠하지 않는다.
  4. 게이트는 시그모이드 + 원소별 곱. 매 스텝 입력에 따라 다시 계산되는 데이터 의존적 밸브다.
  5. 네 단계: 망각 f → 입력 i·후보 C̃ → 갱신 Ct = f⊙Ct−1+i⊙C̃ → 출력 ht = o⊙tanh(Ct).
  6. C와 h의 분리 — C는 보관용 장부, h는 이번 스텝의 답변이자 다음 게이트의 입력.
  7. 변형(핍홀·결합 게이트·GRU)은 성능이 대체로 비등하다. 망각 게이트와 출력 활성화는 빼면 안 되는 필수 부품이고, 망각 편향은 1 근처로 초기화한다.
  8. 다음 걸음은 어텐션 — 상태 하나를 잘 지키는 대신, 필요한 정보를 그때그때 골라 본다.

이해도 확인