개요

지난 글에서 단어를 벡터로 바꾸는 데까지 왔다. 이제 단어 하나하나는 숫자 덩어리가 됐다.

그런데 문장은 단어의 모음이지, 단어가 아니다. 벡터를 그냥 한 줄로 늘어놓거나 평균을 내버리면 아주 곤란한 일이 생긴다.

순서가 중요하다

두 문장에 쓰인 단어는 완전히 똑같다. 바뀐 건 자리뿐인데 상황은 정반대다. 단어 벡터를 그냥 더하거나 평균 내면 두 문장이 같은 값이 되어버린다.

이번 글의 주제는 순서다. 왜 순서가 이렇게 결정적인지, 그리고 순서를 다루기 위해 등장한 RNN이 어떤 구조인지 정리한다.

교육 자료는 대외비라 슬라이드 이미지나 예제 데이터는 싣지 않는다. 개념 흐름만 내가 이해한 방식으로 재구성했고, 그림은 전부 생성하였다.


1. 순차적 데이터란

순차적 데이터(sequential data) = 들어오는 순서와 그 순서로 생기는 데이터끼리의 관계가 중요한 데이터

언어만 그런 게 아니다.

  • 음성 — 소리 조각의 순서가 바뀌면 다른 말이 된다
  • 영상 — 프레임 순서가 바뀌면 다른 장면이 된다
  • 주가·날씨 — 어제 값이 오늘 값에 영향을 준다

위 그림 아래쪽에 정리한 세 가지 특징이 핵심이다.

① 순서가 중요하다

앞에서 본 그대로다. 자리만 바꿔도 뜻이 뒤집힌다.

② 장기 의존성 — 멀리 있는 말이 영향을 준다

이게 언어를 어렵게 만드는 진짜 이유다. 예를 들어보자.

"어릴 때 할머니 댁 마당에서 키우던 강아지는 지금도 나를 보면 ___"

빈칸에 들어갈 말을 정하려면 맨 앞의 “강아지”를 기억하고 있어야 한다. 바로 앞 단어인 “보면”만 봐서는 아무것도 알 수 없다.

문장의 주어와 서술어가 아주 멀리 떨어질 수 있다. 이걸 장기 의존성(long-term dependency)이라고 한다.

③ 길이가 제각각이다

“응”도 문장이고, 30단어짜리 설명도 문장이다. 입력 길이가 고정되지 않는다.


2. 기존 신경망으로는 왜 안 되나

지금까지 배운 모델들(선형회귀, 일반적인 신경망)은 입력 크기가 고정이다. 입력이 3개면 3개짜리 함수를 만든 것이고, 4개가 들어오면 아예 계산이 안 된다.

문장은 길이가 매번 다르니 곧바로 문제가 된다. 억지로 맞추려면 이런 방법을 쓰게 된다.

  • 길이를 고정하고 자르기 → 긴 문장의 뒷부분이 통째로 버려진다
  • 빈칸으로 채워 늘리기 → 짧은 문장에 의미 없는 칸이 잔뜩 붙는다
  • 단어 벡터를 전부 평균 내기순서 정보가 완전히 사라진다

세 번째가 특히 뼈아프다. 평균을 내는 순간 앞에서 본 두 문장이 같은 값이 된다.

그래서 순차적 데이터를 위한 별도의 구조가 필요하다. 그게 RNN이다.


3. RNN — 메모를 이어 넘기는 구조

RNN(Recurrent Neural Network, 순환 신경망) = 단어를 하나씩 순서대로 처리하면서, 직전까지의 요약을 다음 단계로 넘겨주는 신경망

RNN 펼친 구조

그림을 보면 구조가 한눈에 들어온다. 각 단계에서 세 방향으로 정보가 오간다.

방향 무엇이 오가나
아래 → 위 이번 단어가 들어오고, 결과가 나간다
왼쪽 → 오른쪽 지금까지의 요약(메모)이 다음 단계로 넘어간다

메모를 정식 용어로 hidden state(은닉 상태)라고 부른다. RNN의 전부라고 해도 될 만큼 중요한 개념이다.

더 쉬운 비유로

친구가 긴 얘기를 들려주는 상황을 생각해보자. 우리는 들은 문장을 전부 통째로 외우지 않는다. 대신 머릿속에 “지금까지의 요약”을 하나 두고, 새 문장을 들을 때마다 그 요약을 조금씩 고친다.

“어제 친구랑 카페 갔는데” → 머릿속 요약: 어제, 친구, 카페 “거기서 우연히 중학교 동창을 만났어” → 요약 갱신: 어제 카페에서 동창 만남

RNN이 하는 일이 정확히 이거다. 새 입력 + 지금까지의 요약 → 새로운 요약.

계산 규칙

한 단계에서 벌어지는 일을 식으로 쓰면 이렇다.

새 요약 = 함수( 직전 요약 , 이번 단어 )

강의에서 쓴 표기로는 이렇게 된다.

기호 읽는 법
hₜ 에이치 티 지금 시점의 요약 (hidden state)
hₜ₋₁ 에이치 티 마이너스 원 직전 시점의 요약
xₜ 엑스 티 이번에 들어온 단어 벡터

hₜ = f(hₜ₋₁, xₜ) 는 말로 옮기면 “이번 요약은 직전 요약과 이번 단어를 섞어서 만든다”가 전부다.

가중치가 하나뿐이라는 점

그림에서 상자가 네 개 그려져 있지만, 서로 다른 상자가 아니다. 같은 상자를 네 번 돌린 것이다.

  • 상자 안의 값(가중치)이 모든 시점에서 똑같다
  • 그래서 문장이 4단어든 40단어든 모델 크기는 그대로

이게 RNN이 가변 길이를 다룰 수 있는 이유다. 길면 그냥 더 많이 돌리면 된다.

반죽을 미는 밀대 하나로 반죽 전체를 미는 것과 같다. 반죽이 길어졌다고 밀대를 새로 사지 않는다. 여러 번 왕복하면 된다.


4. 입력과 출력 개수를 자유롭게

RNN의 또 다른 강점은 입력과 출력의 개수를 다르게 짤 수 있다는 것이다.

RNN 입출력 유형

형태 하는 일
여러 개 → 하나 문장 전체를 읽고 판정 하나 리뷰 감정 분류
하나 → 여러 개 입력 하나로 문장 생성 사진 설명 만들기
여러 개 → 여러 개 문장을 받아 문장을 생성 기계 번역

기존 신경망은 입력 하나 → 출력 하나밖에 못 했다. 이미지 한 장을 넣어 분류 하나를 뽑는 식이다. RNN은 여기서 자유로워졌고, 번역이나 요약처럼 길이가 안 맞는 작업을 처음으로 다룰 수 있게 됐다.


5. 그런데 오래 기억하지 못한다

여기까지만 보면 완벽해 보인다. 그런데 RNN에는 결정적인 한계가 있다.

RNN은 멀리 있는 단어를 잘 기억하지 못한다.

앞에서 짚은 장기 의존성을 못 잡는다는 뜻이다. 문제를 해결하려고 만든 구조가 정작 그 문제에서 무너진다.

왜 그럴까 — 기울기 소실

원인은 학습 방식에 있다. 지난 시리즈에서 신경망은 역전파로 배운다고 정리했다. 손실에서 출발해 거꾸로 돌아오며 “누구 책임인지”를 계산하는 절차였다.

RNN에서 이 “거꾸로 돌아오기”는 시간을 거슬러 올라가는 것이 된다. 마지막 단어에서 첫 단어까지 되짚어 가야 한다.

그리고 연쇄법칙에서 봤듯, 거슬러 갈 때마다 변화율을 곱해 나간다. 여기서 사고가 난다.

기울기 소실

한 시점 거슬러 갈 때마다 신호가 0.5배씩 줄어든다고 해보자.

거슬러 간 시점 남은 신호 상황
2시점 전 0.25배 아직 쓸 만하다
8시점 전 0.004배 거의 0
20시점 전 0.000001배 완전히 사라짐

앞쪽 단어에 도달할 때쯤이면 신호가 남아 있지 않다. 신호가 0에 가까우면 그 단어와 관련된 값은 거의 갱신되지 않는다. 배울 기회 자체가 사라지는 것이다.

이걸 기울기 소실(vanishing gradient) 문제라고 한다.

더 쉬운 비유로

교실 맨 뒷줄에서 앞줄로 귓속말을 전달한다고 하자. 한 사람 건너갈 때마다 말이 조금씩 뭉개진다. 두세 명까지는 그럭저럭 전해지는데, 스무 명을 거치면 아무 말도 남지 않는다.

문제는 이게 “틀리게 전달된다”가 아니라 “아무것도 전달되지 않는다”는 것이다. 앞줄 사람은 자기가 뭘 잘못했는지 들을 방법이 없으니 고칠 수가 없다.

그래서 실제로 이런 일이 벌어진다.

  • 최근 몇 단어에 대해서는 잘 배운다 (단기 의존성)
  • 멀리 있는 단어와의 관계는 거의 못 배운다 (장기 의존성)

문장이 길어질수록 앞부분을 잊어버리니, 긴 문장 번역이나 긴 글 요약에서 성능이 급격히 떨어진다.

참고로 반대 방향의 사고도 있다. 곱해지는 값이 1보다 크면 거꾸로 값이 폭발해서 학습이 터진다. 소실보다는 다루기 쉬운 편이라 보통은 소실 쪽이 더 큰 골칫거리로 다뤄진다.


6. 정리하면 — RNN이 남긴 숙제

RNN은 순차 데이터를 다루는 문을 열었다. 가변 길이를 받고, 순서를 반영하고, 입출력 개수를 자유롭게 짤 수 있게 됐다.

하지만 정작 가장 중요한 장기 의존성은 해결하지 못했다. 구조상 정보를 한 줄로만 흘려보내기 때문에, 멀어질수록 신호가 희미해지는 걸 피할 수 없다.

그래서 다음 질문이 자연스럽게 나온다.

“메모를 흘려보내되, 중요한 건 오래 남기고 필요 없는 건 지울 수는 없을까?”

이 질문에 답한 구조가 LSTM이다.


정리

  • 순차적 데이터 = 순서와 그 관계가 중요한 데이터. 언어·음성·영상·시계열
  • 세 가지 특징 — 순서 중요 / 장기 의존성 / 가변 길이
  • 기존 신경망은 입력 길이가 고정이라 문장을 다루기 어렵다. 평균을 내면 순서가 사라진다
  • RNN = 단어를 하나씩 처리하며 메모(hidden state)를 다음 단계로 넘기는 구조
  • 상자는 여러 개처럼 보여도 하나를 반복해 쓰는 것 — 그래서 길이에 상관없다
  • 입력·출력 개수를 다르게 짤 수 있어 번역·요약 같은 작업이 가능해졌다
  • 한계 — 기울기 소실로 멀리 있는 단어를 학습하지 못한다. 최근 몇 단어만 기억한다

다음 글에서

다음 글에서는 LSTM을 다룬다. RNN의 메모 전달 방식을 어떻게 뜯어고쳐서 오래 기억하게 만들었는지, 게이트 세 개의 역할을 하나씩 정리한다.

한줄 평

  • 여기까지는 단순한 흐름대로 쉽게 이해하기 편했다..! 임베딩에도 역사가 있었구나.. 라는 느낌이였지만