6117 단어
31 분
LSTM 이해하기 - RNN의 한계부터 Gate와 Cell State까지
2026-08-30
TIP

핵심 요약(TL;DR)

  • LSTM(Long Short-Term Memory)은 일반 RNN이 긴 시퀀스에서 과거 정보를 안정적으로 유지하기 어려운 문제를 완화하기 위해 만든 순환 신경망 구조입니다.
  • 핵심은 Cell State라는 장기 기억 경로와, 정보를 선택적으로 버리고·쓰기·내보내는 Gate입니다.
  • Forget Gate, Input Gate, Output Gate가 각각 이전 기억의 유지, 새 정보의 저장, 현재 출력의 노출을 조절합니다.
  • Cell State가 덧셈 중심으로 갱신되기 때문에 일반 RNN보다 장기 의존성(Long-term Dependency)을 학습하기 쉬워집니다.
  • 순서가 중요한 시계열·문장·이벤트 시퀀스 등에 사용할 수 있지만, 매우 긴 시퀀스나 대규모 병렬 처리가 중요한 문제에서는 Transformer가 더 적합할 수 있습니다.

왜 LSTM이 필요했을까?#

문장을 왼쪽에서 오른쪽으로 읽는 RNN을 생각해 봅시다. 현재 단어를 해석할 때 이전 단어의 정보가 필요하므로, RNN은 이전 시점의 Hidden State를 다음 시점으로 전달합니다.

문장이 길어질수록, RNN은 아주 앞부분의 정보를 마지막까지 얼마나 잘 기억할 수 있을까?

예를 들어 다음처럼 앞부분의 정보가 뒤에서 다시 필요할 수 있습니다.

“나는 프랑스에서 태어났고 여러 나라에서 오래 살았다. … 그래서 내가 처음 배운 언어는 프랑스어였다.”

마지막의 “프랑스어”를 예측하려면 꽤 앞에서 나온 “프랑스”라는 정보가 여전히 의미 있게 남아 있어야 합니다.


기존 방법: 일반 RNN은 어떻게 기억하는가?#

일반 RNN은 현재 입력 xtx_t와 이전 Hidden State ht1h_{t-1}를 이용해 새로운 Hidden State hth_t를 계산합니다.

ht=tanh(Wxxt+Whht1+b)h_t = \tanh(W_x x_t + W_h h_{t-1} + b)

이 방식의 장점은 분명합니다.

  • 입력의 순서를 반영할 수 있습니다.
  • 같은 파라미터를 모든 시점에 재사용하므로 길이가 다른 시퀀스도 처리할 수 있습니다.
  • 이전 상태가 다음 상태에 전달되므로 과거 문맥을 사용할 수 있습니다.

하지만 중요한 문제가 하나 있습니다. 과거의 정보가 매 시점마다 같은 변환을 반복해서 통과해야 한다는 점입니다.

긴 시퀀스에서 무엇이 문제일까?#

RNN을 학습할 때는 BPTT(Backpropagation Through Time)를 사용합니다. 마지막 시점의 Loss가 이전 시점들로 역전파되면서, 여러 Jacobian과 가중치가 반복해서 곱해집니다.

이때 곱해지는 값들의 크기가 계속 1보다 작으면 Gradient가 매우 작아지는 Vanishing Gradient가 발생할 수 있습니다. 반대로 반복 곱의 크기가 커지면 Exploding Gradient가 발생할 수 있습니다.

WARNING

중요한 포인트

Vanishing Gradient는 단순히 “RNN이 오래된 값을 저장할 공간이 부족하다”는 문제가 아닙니다. 학습 과정에서 아주 오래전 입력이 현재 Loss에 어떤 영향을 주었는지 알려 주는 Gradient가 약해지기 쉬운 것이 핵심입니다.

결과적으로 일반 RNN은 가까운 과거의 패턴은 잘 활용해도, 수십·수백 시점 떨어진 장기 의존성을 학습하기 어려울 수 있습니다.

그래서 필요한 것은 중요한 정보가 여러 시점을 지나도 비교적 안정적으로 흐를 수 있는 별도의 경로였습니다.


핵심 아이디어: 기억을 매번 새로 만들지 말고 관리하자#

TIP

LSTM의 핵심은 중요한 정보는 오래 유지하고, 필요 없는 정보는 선택적으로 버리는 것입니다.

일반 RNN의 Hidden State 하나에 모든 역할을 맡기지 않고, LSTM은 상태를 두 종류로 나눕니다.

  • Cell State ctc_t: 장기적으로 전달할 기억
  • Hidden State hth_t: 현재 시점에서 외부로 드러나는 상태이자 다음 계산에 사용하는 단기 표현

그리고 세 개의 Gate가 정보 흐름을 조절합니다.

  1. Forget Gate: 이전 Cell State에서 무엇을 유지할까?
  2. Input Gate: 새 정보 중 무엇을 Cell State에 기록할까?
  3. Output Gate: 현재 Cell State 중 무엇을 Hidden State로 보여 줄까?

Gate는 보통 Sigmoid를 사용해 각 원소에 대해 0~1 사이 값을 만듭니다. 0에 가까우면 거의 막고, 1에 가까우면 거의 통과시키는 연속적인 밸브처럼 생각할 수 있습니다.

전체 구조 먼저 보기#

┌──────────────────────────────────────────────┐
│ Cell State │
cₜ₋₁ ──────────┼── × Forget ────────┐ │
│ ├── + ───────────────→ cₜ│
│ Candidate ─ × Input │
└──────────────────────────────────────────────┘
tanh
xₜ ───────┐ × Output ─────────────→ hₜ
├──→ [Forget, Input, Candidate, Output Gates]
hₜ₋₁ ─────┘

한 시점 tt에서 LSTM이 받는 핵심 입력은 세 가지입니다.

  • 현재 입력 xtx_t
  • 이전 Hidden State ht1h_{t-1}
  • 이전 Cell State ct1c_{t-1}

그리고 다음 시점으로 hth_tctc_t를 전달합니다.

구성 요소역할직관
Cell State ctc_t장기 기억 전달시퀀스를 따라 흐르는 메모리 통로
Hidden State hth_t현재 시점의 표현지금 외부에 보여 줄 요약
Forget Gate ftf_t이전 기억 유지 비율 결정지울 것과 남길 것을 선택
Input Gate iti_t새 정보 저장 비율 결정새 메모리를 얼마나 쓸지 선택
Candidate gtg_t새로 기록할 후보 정보 생성메모장에 적을 내용의 초안
Output Gate oto_t현재 기억의 노출 비율 결정메모리 중 지금 보여 줄 부분을 선택

핵심 구성 요소와 수식#

1. Forget Gate — 이전 기억을 얼마나 유지할까?#

ft=σ(Wf[ht1,xt]+bf)f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)
  • xtx_t: 현재 입력
  • ht1h_{t-1}: 직전 시점의 Hidden State
  • [ht1,xt][h_{t-1}, x_t]: 두 벡터를 이어 붙인 값
  • Wf,bfW_f, b_f: 학습되는 파라미터
  • σ\sigma: 0~1 값을 만드는 Sigmoid

Forget Gate의 출력 ftf_t는 Cell State와 같은 차원의 벡터입니다.

  • 어떤 원소가 0에 가까우면 → 해당 기억을 거의 제거
  • 어떤 원소가 1에 가까우면 → 해당 기억을 거의 유지

즉, “이전 기억 전체를 버릴까?”를 하나의 스칼라로 정하는 것이 아니라 특징별로 유지 비율을 다르게 정합니다.

2. Input Gate — 새 정보를 얼마나 저장할까?#

먼저 새 정보를 얼마나 기록할지 결정합니다.

it=σ(Wi[ht1,xt]+bi)i_t = \sigma(W_i [h_{t-1}, x_t] + b_i)

그다음 실제로 기록할 후보 내용을 만듭니다.

gt=tanh(Wg[ht1,xt]+bg)g_t = \tanh(W_g [h_{t-1}, x_t] + b_g)

iti_t쓰기 강도, gtg_t쓸 내용에 가깝습니다.

Sigmoid를 사용하는 iti_t는 01 사이에서 저장량을 조절하고, Tanh를 사용하는 gtg_t는 -11 범위의 후보 표현을 만듭니다.

3. Cell State Update — 기억을 실제로 갱신한다#

ct=ftct1+itgtc_t = f_t \odot c_{t-1} + i_t \odot g_t

여기서 \odot는 원소별 곱(element-wise multiplication)입니다.

이 식은 직관적으로 두 부분을 더합니다.

  1. ftct1f_t \odot c_{t-1}과거 기억 중 남길 부분
  2. itgti_t \odot g_t현재 새로 기록할 부분

일반 RNN과 비교했을 때 중요한 차이는 Cell State가 매번 완전히 새로운 비선형 변환으로 덮어쓰이지 않고, 이전 상태를 선택적으로 유지한 뒤 새 정보를 덧붙이는 방식으로 갱신된다는 점입니다.

TIP

이 덧셈 중심의 경로 덕분에 Gradient가 이전 시점으로 전달될 때 일반 RNN보다 안정적인 경로를 가질 수 있습니다. 다만 LSTM이 Vanishing Gradient를 수학적으로 완전히 제거하는 것은 아닙니다.

4. Output Gate — 현재 시점에서 무엇을 보여 줄까?#

ot=σ(Wo[ht1,xt]+bo)o_t = \sigma(W_o [h_{t-1}, x_t] + b_o)ht=ottanh(ct)h_t = o_t \odot \tanh(c_t)

Cell State에는 장기 기억이 들어 있지만, 그 내용을 모두 현재 출력으로 사용할 필요는 없습니다.

Output Gate는 현재 Cell State 중 지금 필요한 부분만 Hidden State로 노출합니다. 이렇게 만들어진 hth_t는 다음 시점의 Gate 계산에도 사용되고, 필요하면 분류기나 다음 레이어의 입력으로도 사용됩니다.

왜 Gate 계산에 $x_t$와 $h_{t-1}$를 함께 사용할까?

현재 입력만 보면 “지금 들어온 정보”는 알 수 있지만 문맥은 알기 어렵습니다. 반대로 이전 Hidden State만 보면 과거 문맥은 알 수 있지만 현재 새 입력을 반영할 수 없습니다.

두 값을 함께 사용하면 Gate가 현재 사건 + 지금까지의 문맥을 기준으로 기억을 유지하거나 수정할 수 있습니다.

역사적으로 모든 LSTM이 처음부터 Forget Gate를 가졌을까?

아닙니다. 1997년의 초기 LSTM과 오늘날 프레임워크에서 흔히 사용하는 표준 LSTM은 세부 구조가 동일하지 않습니다. Forget Gate는 이후 제안되어 현대적인 LSTM의 대표 구성 요소가 되었습니다. 이 글은 현재 일반적으로 사용되는 LSTM Cell을 기준으로 설명합니다.


데이터는 실제로 어떻게 흐를까?#

배치 크기 32, 입력 특징 수 16, Hidden Size 64인 LSTM 한 층을 생각해 봅시다.

현재 한 시점에서 텐서 크기는 다음과 같습니다.

  • xtx_t: [32, 16]
  • ht1h_{t-1}: [32, 64]
  • ct1c_{t-1}: [32, 64]
  • Gate 출력 ft,it,gt,otf_t, i_t, g_t, o_t: 각각 [32, 64]
  • 새 상태 ht,cth_t, c_t: 각각 [32, 64]
Step입력계산결과
1xt,`x_t`, h_{t-1}Forget Gate이전 기억의 유지 비율 ftf_t
2xt,`x_t`, h_{t-1}Input Gate + Candidate새로 저장할 양 iti_t와 내용 gtg_t
3ct1,c_{t-1}`, f_t, it,`i_t`, `g_t$Cell State Update새 장기 기억 ctc_t
4xt,x_t`, h_{t-1}, ct`c_tOutput Gate현재 Hidden State hth_t
5ht,h_t`, `c_t$다음 시점으로 전달t+1t+1의 이전 상태가 됨

작은 직관 예시#

어떤 차원의 Cell State가 “현재 문장의 주제가 금융인가?” 같은 정보를 표현한다고 가정해 봅시다.

  • 이전까지 금융 관련 문맥이 강했다면 ct1c_{t-1}의 해당 성분이 큰 값을 가질 수 있습니다.
  • 현재 입력이 문맥과 무관한 수식어라면 Forget Gate가 1에 가까운 값을 내어 기존 정보를 유지할 수 있습니다.
  • 새로운 주제가 등장하면 Input Gate가 열리고 Candidate의 새 정보를 Cell State에 반영할 수 있습니다.
  • 현재 출력에 그 정보가 필요하지 않으면 Output Gate는 닫혀 있을 수 있습니다.

즉, 기억하고 있는 것과 지금 출력하는 것은 다를 수 있습니다. 이것이 Cell State와 Hidden State를 구분해서 봐야 하는 이유입니다.


전체 Forward 과정을 다시 연결하기#

  1. 현재 입력 xtx_t와 이전 Hidden State ht1h_{t-1}를 본다.
  2. Forget Gate로 이전 Cell State에서 유지할 정보를 정한다.
  3. Input Gate로 새 후보 정보 중 저장할 부분을 정한다.
  4. 두 정보를 합쳐 새로운 Cell State ctc_t를 만든다.
  5. Output Gate로 Cell State 중 현재 노출할 부분을 정한다.
  6. 새로운 Hidden State hth_t를 만든다.
  7. hth_tctc_t를 다음 시점으로 넘긴다.
for each timestep t:
decide what to keep from previous memory
decide what new information to write
update the cell state
decide what part of the cell state to expose
pass hidden state and cell state to the next timestep

PyTorch로 내부 계산 직접 구현하기#

LSTM의 원리를 이해하려면 nn.LSTM을 바로 쓰기 전에 Gate 계산을 직접 구현해 보는 것이 좋습니다.

import torch
import torch.nn as nn
class MyLSTMCell(nn.Module):
def __init__(self, input_size: int, hidden_size: int):
super().__init__()
self.hidden_size = hidden_size
# [x_t, h_{t-1}]를 한 번에 받아
# input, forget, candidate, output 네 벡터를 동시에 계산한다.
self.linear = nn.Linear(
input_size + hidden_size,
4 * hidden_size,
)
def forward(self, x_t, state):
h_prev, c_prev = state
combined = torch.cat([x_t, h_prev], dim=-1)
gates = self.linear(combined)
i_raw, f_raw, g_raw, o_raw = gates.chunk(4, dim=-1)
i_t = torch.sigmoid(i_raw) # input gate
f_t = torch.sigmoid(f_raw) # forget gate
g_t = torch.tanh(g_raw) # candidate
o_t = torch.sigmoid(o_raw) # output gate
c_t = f_t * c_prev + i_t * g_t
h_t = o_t * torch.tanh(c_t)
return h_t, c_t

핵심은 linear의 출력 차원을 4 * hidden_size로 만들고, 한 번의 선형 변환 결과를 네 Gate로 나누는 부분입니다. 수식에서는 Gate별로 Wi,Wf,Wg,WoW_i, W_f, W_g, W_o를 따로 썼지만, 구현에서는 효율을 위해 하나의 큰 행렬 연산으로 합치는 경우가 많습니다.

시퀀스 전체를 직접 순회하기#

batch_size = 32
seq_len = 20
input_size = 16
hidden_size = 64
x = torch.randn(batch_size, seq_len, input_size)
cell = MyLSTMCell(input_size, hidden_size)
h_t = torch.zeros(batch_size, hidden_size)
c_t = torch.zeros(batch_size, hidden_size)
outputs = []
for t in range(seq_len):
x_t = x[:, t, :]
h_t, c_t = cell(x_t, (h_t, c_t))
outputs.append(h_t)
outputs = torch.stack(outputs, dim=1)
print(outputs.shape) # [32, 20, 64]

이 코드에서 중요한 것은 Python for문 자체가 아니라 시점 tt의 상태가 t+1t+1 계산에 필요하다는 의존성입니다. LSTM이 본질적으로 순차 계산을 요구하는 이유입니다.

실무에서는 nn.LSTM 사용하기#

import torch
import torch.nn as nn
batch_size = 32
seq_len = 20
input_size = 16
hidden_size = 64
num_layers = 2
x = torch.randn(batch_size, seq_len, input_size)
lstm = nn.LSTM(
input_size=input_size,
hidden_size=hidden_size,
num_layers=num_layers,
batch_first=True,
)
output, (h_n, c_n) = lstm(x)
print(output.shape) # [32, 20, 64]
print(h_n.shape) # [2, 32, 64]
print(c_n.shape) # [2, 32, 64]
  • output: 마지막 레이어의 모든 시점 Hidden State
  • h_n: 각 레이어의 마지막 Hidden State
  • c_n: 각 레이어의 마지막 Cell State
WARNING

batch_first=True는 입력과 output[batch, sequence, feature] 형태로 바꾸지만, h_nc_n의 차원 순서는 [layers × directions, batch, hidden] 형태를 유지합니다.


학습할 때는 무엇이 업데이트될까?#

LSTM에서 직접 학습되는 것은 Gate의 결과값 자체가 아니라 Gate를 계산하는 가중치와 Bias입니다.

예를 들어 다음 파라미터들이 Gradient Descent로 업데이트됩니다.

  • Forget Gate의 Wf,bfW_f, b_f
  • Input Gate의 Wi,biW_i, b_i
  • Candidate의 Wg,bgW_g, b_g
  • Output Gate의 Wo,boW_o, b_o

학습 흐름은 일반적인 신경망과 같습니다.

  1. 시퀀스를 Forward 한다.
  2. 모델 출력으로 Loss를 계산한다.
  3. BPTT를 통해 여러 시점으로 Gradient를 전달한다.
  4. Optimizer가 LSTM 파라미터를 업데이트한다.
model = nn.LSTM(
input_size=16,
hidden_size=64,
batch_first=True,
)
head = nn.Linear(64, 3)
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(
list(model.parameters()) + list(head.parameters()),
lr=1e-3,
)
x = torch.randn(32, 20, 16)
y = torch.randint(0, 3, (32,))
output, _ = model(x)
last_hidden = output[:, -1, :]
logits = head(last_hidden)
loss = criterion(logits, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()

학습과 추론에서 LSTM Cell의 기본 Forward 계산 자체는 같습니다. 다만 학습에서는 Gradient를 저장하고 역전파하며, 추론에서는 보통 Gradient 계산을 끕니다.


계산 특성#

LSTM은 일반 RNN보다 장기 의존성을 다루기 쉬워졌지만 계산 비용은 더 큽니다. 한 시점마다 여러 Gate를 계산해야 하기 때문입니다.

특히 중요한 특성은 시간축 병렬화가 어렵다는 점입니다.

hth_tctc_t를 계산해야 ht+1h_{t+1}ct+1c_{t+1}를 계산할 수 있으므로, 한 시퀀스 내부의 시점들을 완전히 독립적으로 계산할 수 없습니다.

이 특성은 긴 시퀀스를 대규모로 처리할 때 Transformer 계열과 비교되는 대표적인 한계입니다.

장점과 한계#

구분내용
장점일반 RNN보다 장기 의존성을 학습하기 쉽다.
장점Cell State와 Gate를 통해 기억의 유지·수정·노출을 세밀하게 조절한다.
장점길이가 가변적인 시퀀스를 자연스럽게 처리할 수 있다.
한계일반 RNN보다 파라미터와 계산량이 많다.
한계시간축 순차 의존성 때문에 긴 시퀀스의 병렬화가 어렵다.
한계매우 긴 거리의 의존성을 항상 안정적으로 해결하는 것은 아니다.
WARNING

자주 오해하는 부분

  • Cell State와 Hidden State는 같은 값이 아닙니다.
  • Forget Gate는 정보를 완전히 삭제하는 스위치가 아니라, 보통 0~1의 연속값으로 기억의 통과량을 조절합니다.
  • LSTM이 Vanishing Gradient를 완전히 없애는 것은 아닙니다. 일반 RNN보다 장기 정보가 흐르기 좋은 경로를 제공하는 것입니다.
  • Hidden State의 마지막 값 하나가 항상 시퀀스 전체를 완벽히 요약한다고 볼 수는 없습니다.

실무에서 체크할 조건#

Padding이 있는 가변 길이 배치#

문장마다 길이가 다르면 짧은 문장 뒤에 Padding을 붙이는 경우가 많습니다. 그대로 마지막 시점을 사용하면 실제 마지막 토큰이 아니라 Padding 위치의 Hidden State를 사용할 수 있습니다.

PyTorch에서는 pack_padded_sequencepad_packed_sequence를 사용하면 Padding 구간을 불필요하게 순회하는 계산을 줄일 수 있습니다.

초기 Hidden/Cell State는 어떻게 정할까?

가장 흔한 기본값은 0으로 초기화하는 것입니다. 다만 연속된 긴 스트림을 여러 Chunk로 나누어 처리할 때는 이전 Chunk의 상태를 다음 Chunk에 넘길 수도 있습니다.

학습 그래프를 무한히 연결하지 않으려면 상황에 따라 상태를 detach()해야 합니다.

Bidirectional LSTM은 무엇이 다른가?

일반 LSTM은 과거 → 미래 방향으로만 상태를 전달합니다. Bidirectional LSTM은 정방향과 역방향 LSTM을 함께 사용해 각 위치가 양쪽 문맥을 이용할 수 있게 합니다.

다만 미래 입력을 볼 수 없는 실시간 예측 문제에서는 역방향 정보가 사용 불가능할 수 있습니다.

언제 LSTM을 사용하면 좋은가?#

순서가 중요하고, 현재 예측에 이전 정보가 영향을 주는 시퀀스 데이터에 잘 맞습니다.

  • 중간 규모 시계열 데이터 → 과거 관측의 흐름이 현재 값에 영향을 주는 경우
  • 텍스트 분류 → 단어 순서와 문맥을 순차적으로 읽어야 하는 경우
  • 이벤트 로그 / 사용자 행동 시퀀스 → 이전 행동의 순서가 이후 행동 예측에 중요한 경우
  • 스트리밍 입력 → 입력이 시간 순서대로 하나씩 도착하며 상태를 계속 이어갈 수 있는 경우

특히 Transformer의 큰 병렬 처리 장점이 꼭 필요하지 않거나, 데이터·모델 규모가 비교적 작고 순환 상태라는 inductive bias가 유용한 상황에서는 여전히 실용적인 선택이 될 수 있습니다.

언제 다른 모델을 고려할까?#

상황추천이유 / 대안
짧고 단순한 순차 패턴✅ LSTM구조가 충분히 강력하면서 구현이 간단하다.
파라미터 수를 줄이고 싶음⚠️ GRU 고려Gate 구조가 더 단순하고 성능이 비슷한 경우가 많다.
매우 긴 문맥 + 대규모 병렬 학습❌ 우선순위 낮음Transformer 계열이 시간축 병렬화와 장거리 참조에 유리할 수 있다.
순서보다 지역 패턴이 핵심인 신호⚠️ CNN 고려고정된 지역 패턴을 효율적으로 추출하는 데 유리할 수 있다.
미래 정보 사용이 금지된 실시간 예측✅ 단방향 LSTMBidirectional 구조는 미래 시점을 보기 때문에 주의해야 한다.

RNN, LSTM, GRU, Transformer 비교#

방법핵심 아이디어강점한계적합한 상황
Vanilla RNNHidden State 하나를 반복 전달구조가 가장 단순장기 의존성 학습이 어려움짧고 단순한 시퀀스
LSTMCell State + 여러 Gate장기 기억 관리가 쉬움계산량과 파라미터가 증가중장기 시퀀스 패턴
GRUGate 구조를 단순화LSTM보다 가벼운 편문제에 따라 LSTM과 우열이 달라짐효율과 순환 모델이 모두 필요한 경우
TransformerAttention으로 위치 간 직접 참조병렬화와 장거리 관계 모델링에 강함Attention 비용과 메모리 사용이 커질 수 있음대규모 NLP, 긴 문맥, 병렬 학습

어떻게 발전했는가?#

Vanilla RNN
│ 장기 의존성 / Gradient 문제
LSTM
│ Gate 구조를 더 단순하게
GRU
│ 멀리 떨어진 위치를 직접 참조하고 싶음
Attention
│ 순환 계산 자체를 제거하고 병렬화
Transformer

이 흐름을 단순히 “새 모델이 이전 모델보다 항상 좋다”라고 이해하면 안 됩니다. 각 구조는 계산 자원, 데이터 크기, 입력 길이, 지연 시간, 온라인 처리 여부 등에 따라 다른 Trade-off를 가집니다.

실제 활용#

LSTM은 다음과 같은 시퀀스 문제에서 오랫동안 널리 사용되어 왔고, 현재도 데이터 규모나 시스템 제약에 따라 유효한 선택입니다.

  • 시계열 예측: 센서, 수요, 트래픽처럼 과거 흐름이 미래 값에 영향을 주는 데이터
  • 텍스트 처리: 문장 분류, sequence labeling 등 순서 기반 표현이 필요한 문제
  • 음성·신호 처리: 시간 순서가 중요한 연속 신호
  • 이상 탐지: 정상 시퀀스의 동역학을 학습해 비정상 패턴을 찾는 문제
  • 행동 예측: 클릭, 구매, 이벤트 로그처럼 이전 행동이 다음 행동과 관련된 경우

실제 시스템에서는 LSTM 하나만 사용하는 것이 아니라 Embedding, CNN, Attention, MLP, CRF 등 다른 모듈과 조합하는 경우도 많습니다.


이해도 확인#

  1. 일반 RNN보다 LSTM의 Cell State가 장기 정보를 전달하기 쉬운 이유는 무엇일까요?
  2. Forget Gate가 항상 0 또는 1만 출력한다면 어떤 문제가 생길까요?
  3. Cell State와 Hidden State를 별도로 유지하면 어떤 장점이 있을까요?
  4. LSTM이 Transformer보다 시간축 병렬화가 어려운 이유는 무엇일까요?
  5. 가변 길이 문장을 Padding해서 학습할 때 마지막 Hidden State를 그대로 사용하는 것이 위험할 수 있는 이유는 무엇일까요?
힌트 1. Cell State 갱신식에서 "덮어쓰기"보다 "유지 + 추가"가 어떻게 나타나는지 보세요. 2. Gate를 연속적인 밸브로 생각해 보세요. 3. "오래 기억할 정보"와 "지금 출력할 정보"가 항상 같은지 생각해 보세요. 4. $t+1$ 계산 전에 필요한 값이 무엇인지 확인하세요. 5. 배치의 마지막 인덱스가 각 샘플의 실제 마지막 토큰인지 확인하세요.

핵심 정리#

TIP
  • LSTM은 일반 RNN의 장기 의존성 학습 문제를 완화하기 위해 등장했습니다.
  • 핵심은 Cell State라는 장기 기억 경로와 정보 흐름을 조절하는 Forget/Input/Output Gate입니다.
  • Cell State는 ct=ftct1+itgtc_t = f_t \odot c_{t-1} + i_t \odot g_t처럼 이전 기억을 선택적으로 유지하고 새 정보를 더하는 방식으로 갱신됩니다.
  • 일반 RNN보다 긴 문맥을 다루기 쉽지만, 순차 계산 때문에 긴 시퀀스의 병렬화가 어렵고 계산량이 더 큽니다.
  • 문제 규모와 시스템 요구에 따라 GRU, Attention, Transformer 같은 대안과 비교해서 선택해야 합니다.

다음에 공부하면 좋은 것#

  1. GRU → LSTM의 Gate 구조를 더 단순하게 만든 순환 모델입니다. LSTM의 각 Gate가 정말 모두 필요한지 생각해 보기 좋습니다.
  2. Bidirectional RNN/LSTM → 한 방향 상태 전달의 한계를 보완해 양쪽 문맥을 사용하는 방법입니다.
  3. Attention Mechanism → 모든 정보를 하나의 순환 상태에 압축하지 않고, 필요한 시점의 표현을 직접 참조하는 아이디어입니다.
  4. Transformer → Attention을 중심으로 순환 구조를 제거해 시퀀스 내부 병렬화를 가능하게 만든 구조입니다.

참고 자료#

LSTM 이해하기 - RNN의 한계부터 Gate와 Cell State까지
https://fuwari.vercel.app/posts/lstm-rnn-gates-cell-state/
저자
Argon
게시일
2026-08-30
라이선스
CC BY-NC-SA 4.0