데이터 과학

RNN 본문

인공지능/딥러닝 -파이썬 인공지능

RNN

티에스윤 2025. 10. 22. 16:11

RNN 개요

일반적인 신경망은 입력을 한 번에 받아 독립적으로 판단합니다. 하지만 문장, 음악, 센서 로그처럼 순서와 문맥이 중요한 데이터는, 앞에서 본 내용이 뒤의 해석에 계속 영향을 줘야 합니다.

예를 들어 “나는 어제 프랑스에 갔다. 그래서 오늘은 프랑스어를…”이라는 문장에서 **‘프랑스어’**라는 단어를 이해하려면 앞에서 언급된 **‘프랑스’**라는 정보가 머릿속에 남아 있어야 하죠. RNN(Recurrent Neural Network) 은 바로 이 문제를 풀기 위해 고안된 구조입니다. 핵심은 간단합니다. 지금 들어온 입력을 처리할 때, 바로 직전까지의 요약 정보(기억)를 함께 참고한다는 것입니다.

 

RNN의 기본 아이디어

RNN은 매 시점마다 두 가지를 받습니다. 현재 입력이전 시점까지의 요약(은닉 상태) 입니다. 모델은 이 둘을 조합하여 새로운 요약을 만들고, 그 요약을 다음 시점으로 넘깁니다. 이렇게 하면 시간이 흐르면서 요약 속에는 과거의 흔적이 차곡차곡 쌓입니다.

  • 이때의 요약은 단순한 복사가 아니라, 모델이 “앞으로 쓰일 법한 정보는 남기고, 필요 없다고 판단되는 내용은 희석”하는 방식의 동적 압축입니다.
  • 결과적으로 RNN은 “한 줄로 이어지는 작업 메모장”을 들고, 입력이 올 때마다 메모를 덧붙이거나 수정하면서 앞으로 나아가는 느낌입니다.

 

한 시퀀스를 처리하는 흐름(서사로 따라가기)

  1. 시작: 빈 메모장(초기 요약)으로 출발합니다.
  2. 첫 단어(또는 첫 시점)가 들어옴: 모델은 그 단어를 읽고, “앞으로 중요한 단서가 될지”를 감각적으로 평가합니다. 중요하다 싶으면 요약에 굵게 표시하듯 남겨두고, 덜 중요하면 가볍게 언급만 남깁니다.
  3. 다음 단어가 들어옴: 모델은 두 자료를 동시에 봅니다. 방금 들어온 단어, 그리고 지금까지의 요약. 둘을 비교해 의미가 이어질 때는 요약을 업데이트하고, 상반된 정보가 나오면 요약의 강조점을 바꾸기도 합니다.
  4. 끝까지 진행: 이 과정을 문장 끝, 시계열의 마지막 시점까지 반복합니다.
  5. 결정 내리기: 마지막에 남은 요약을 바탕으로 전체 감정 분류를 하거나(문장 전체의 감성), 매 시점마다 중간중간 결과를 내기도 합니다(다음 글자 예측, 시계열의 다음 값 예측 등).

 

RNN이 잘하는 일과 어려워하는 일

  • 강점: 순서가 있는 데이터를 자연스럽게 다룹니다. 문맥을 고려하기 때문에, 독립 입력으로는 놓치기 쉬운 패턴을 포착합니다.
  • 약점: 시간이 길어질수록 아주 옛날 정보는 점차 희미해집니다. RNN의 메모장은 무한히 늘어나지 않고, 요약이라는 형태로 압축되다 보니 매우 장기적인 의존성이 필요한 문제에서는 정보가 소실되거나 왜곡되기 쉽습니다. 또한, 한 시점씩 순차적으로 처리해야 해서 병렬화가 어렵고 학습 속도가 느린 편입니다.

 

RNN은 어떻게 학습하나

학습의 목표는 간단합니다. “이전까지의 요약을 어떻게 유지하거나 바꿔야, 미래의 판단이 더 정확해질까?”를 스스로 찾아내는 것입니다.

  • 모델은 매 시점의 판단 오류(예측과 정답의 차이)를 보고, “어떤 순간에 어떤 정보를 너무 지웠는지, 반대로 필요 없는 정보를 너무 강조했는지”를 거꾸로 추적합니다.
  • 이 과정을 통해, 무엇을 오래 기억하고 무엇을 빨리 잊을지에 관한 내부 규칙이 조금씩 조정됩니다.
  • 직감적으로 말하면, 여러 번의 시행착오 끝에 모델은 “이런 패턴이 나오면 앞으로 이런 일이 자주 이어졌지” 같은 경험칙을 요약 갱신 방식에 자연스럽게 녹여 넣습니다.

 

RNN을 쓰는 전형적인 방식들

  • many-to-one: 문장 전체를 읽고 마지막에 하나의 결론을 내리는 경우(감성 분석, 리뷰 긍/부정).
  • many-to-many(동일 길이): 각 시점마다 출력이 필요한 경우(품사 태깅, 프레임 단위 라벨링).
  • many-to-many(다른 길이): 입력과 출력의 길이가 다를 수 있는 경우(기계 번역). 이때는 인코더–디코더 구조로 RNN을 두 개 이어서 쓰곤 했습니다(Transformer 이전 전형).

 

RNN이 실전에서 보이는 행동 양식

  • 초반 정보의 영향력 조절: 초반에 강한 단서(예: “하지만”, “결론적으로”)가 나오면, RNN은 요약의 관점을 확 바꾸기도 합니다.
  • 반복과 리듬 감지: 주기적 신호(센서 진동, 계절성 매출)에서 RNN은 “리듬”을 요약 속에 간단한 패턴으로 새겨 넣어 다음을 예측하려 합니다.
  • 두서없는 잡음 처리: 중요하지 않은 순간이 길게 이어지면, 요약은 비교적 안정적으로 유지됩니다. 그러다 의미 있는 변곡점이 나오면 그때 요약이 크게 갱신됩니다.

 

왜 LSTM/GRU가 등장했나

RNN의 요약은 한 덩어리 메모장이라, 장기 기억을 다루는 데 한계가 있었습니다. 그래서 LSTM/GRU는 “메모장의 일부는 쉽게 지우지 못하게 하고, 일부는 빠르게 덧쓰기 좋게” 만드는 게이트(문지기) 를 도입했습니다. 이 문지기들은 “이건 꼭 들고 가, 이건 내려놓자” 같은 결정을 더 명시적으로 해 장기 의존성을 개선합니다. 즉, RNN의 기본 철학은 유지하되 기억 관리의 기술을 고도화한 셈입니다.

 

 

RNN을 잘 쓰기 위한 실무적 조언

  • 문제 길이를 보라: 문맥 길이가 짧거나 중간 정도면 RNN/GRU도 충분히 통합니다. 아주 길다면 LSTM, 더 나아가 Transformer를 고려하세요.
  • 전처리의 중요성: 텍스트는 토큰화·패딩, 시계열은 정규화·윈도우링이 성능을 크게 좌우합니다.
  • 학습 안정화: 기울기 폭발을 막기 위해 기울기 클리핑, 과적합을 막기 위해 드롭아웃조기 종료 같은 기본기를 챙기면 효과가 큽니다.
  • 평가 방법: 단순 정확도만 보지 말고, 시퀀스 위치별 오류나 예측 지연 여부 등 시간 축의 품질을 함께 봐야 합니다.

 

RNN에서 LSTM으로의 진화 

RNN은 처음 등장했을 때, “기계에게 기억을 주자”는 발상으로 인공지능 역사에 큰 전환점을 만들었습니다.
하지만 그 기억은 너무 짧고 쉽게 흐려졌습니다.
RNN은 새로운 입력이 들어올 때마다 과거의 흔적을 덮어쓰며 나아갔기 때문에, 멀리 있는 원인과 결과를 연결하지 못했습니다.
예를 들어 한 문장의 첫 단어가 마지막 의미를 결정짓는 언어 구조에서는 RNN의 한계가 분명했습니다.

이때 등장한 LSTM은 마치 인간의 장기기억(long-term memory)단기기억(short-term memory) 을 모방한 형태였습니다.
LSTM은 “모든 것을 다 기억하려고 하지 말고, 중요한 것만 남겨라”라는 새로운 철학을 적용했습니다.
망각 게이트가 불필요한 정보는 지우고, 입력 게이트가 새로운 경험을 받아들이며, 셀 상태는 시간의 강을 따라 흘러가며 기억을 전달했습니다.
이러한 구조는 RNN의 단점을 극복했고, 긴 문장 번역, 감정 분석, 음성 인식 등 복잡하고 길이가 긴 데이터 문제에 놀라운 성능을 보였습니다.

결국 LSTM의 등장은 단순한 기술 개선이 아니라, ‘기계가 기억을 다루는 방식’ 자체의 진화였습니다.
RNN이 기억의 시작이었다면, LSTM은 “기억을 관리할 수 있는 지능”으로 나아가는 결정적 계단이었습니다.

 

 

 

 

import math, torch, torch.nn as nn
from torch.utils.data import Dataset, DataLoader

# 1) 데이터: sin 파형에서 윈도우를 잘라 다음값 예측
class SineDataset(Dataset):
    def __init__(self, seq_len=50, n_samples=3000):
        self.X, self.y = [], []
        for i in range(n_samples):
            start = torch.rand(1).item() * 2*math.pi
            xs = torch.linspace(start, start + (seq_len)*0.1, steps=seq_len+1)
            series = torch.sin(xs)
            self.X.append(series[:-1].unsqueeze(-1))   # (seq_len, 1)
            self.y.append(series[-1])                  # scalar
        self.X = torch.stack(self.X)                   # (N, seq_len, 1)
        self.y = torch.stack(self.y)                   # (N,)

    def __len__(self): return len(self.X)
    def __getitem__(self, idx): return self.X[idx], self.y[idx]

train_ds = SineDataset(seq_len=50, n_samples=2500)
valid_ds = SineDataset(seq_len=50, n_samples=500)
train_dl = DataLoader(train_ds, batch_size=64, shuffle=True)
valid_dl = DataLoader(valid_ds, batch_size=128, shuffle=False)

# 2) 모델: 단층 RNN + 선형
class RNNReg(nn.Module):
    def __init__(self, input_size=1, hidden_size=64, num_layers=1):
        super().__init__()
        self.rnn = nn.RNN(input_size, hidden_size, num_layers, batch_first=True, nonlinearity='tanh')
        self.fc  = nn.Linear(hidden_size, 1)

    def forward(self, x):
        # x: (B, T, 1)
        out, h_last = self.rnn(x)      # out: (B, T, H)
        h_T = out[:, -1, :]            # (B, H) 마지막 시점
        y  = self.fc(h_T).squeeze(-1)  # (B,)
        return y

device = "cuda" if torch.cuda.is_available() else "cpu"
model = RNNReg().to(device)
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.MSELoss()

def eval_mse(dloader):
    model.eval()
    total, n = 0.0, 0
    with torch.no_grad():
        for X, y in dloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            total += loss_fn(pred, y).item() * X.size(0)
            n += X.size(0)
    return total / n

for epoch in range(30):
    model.train()
    for X, y in train_dl:
        X, y = X.to(device), y.to(device)
        pred = model(X)
        loss = loss_fn(pred, y)
        opt.zero_grad()
        loss.backward()
        opt.step()
    if (epoch+1) % 5 == 0:
        print(f"Epoch {epoch+1}: train_mse={eval_mse(train_dl):.4f}, valid_mse={eval_mse(valid_dl):.4f}")

 

 

https://tsyoon.tistory.com/181

 

RNN(순환 신경망), LSTM 그리고 cs231n

컨볼루션 뉴럴네트워크 이후에 많이 듣는 이론이 RNN입니다. 이미지 프로세싱에서는 CNN을 이용하는데 RNN은 텍스트 관련 처리 기술에 대한 내용입니다. 이에 대한 내용을 Understanding LSTM Networks 논

tsyoon.tistory.com