본문 바로가기

딥러닝

순환 신경망(RNN) (1)

1. 피드포워드(feed forward) 신경망의 문제점

■ 지금까지 살펴본 신경망은 신경망의 기본적인 형태인 피드포워드 신경망이다.

- 피드포워드 신경망은 다충 퍼셉트론이라고도 불리며, 은닉칭이 하나 이상인 신경망을 말한다.

피드포워드 신경망은 흐름이 단방향인 신경망으로, 입력 신호가 출력까지 한 방향으로만 전달되는 구조를 가진다.

■ 피드포워드 신경망은 이러한 특징으로 인해 시계열 데이터 같은 연속적인 정보를 잘 다루지 못한다. 구체적으로 시계열 데이터의 성질(패턴)을 충분히 학습할 수 없다.

cf) 그래서 등장한 것이 순환 구조를 가지는 순환경 신경망(RNN)이다. 이 순환 구조를 이용해서 각 시점의 정보를 출력까지 전달한다.

■ 예를 들어 CBOW는 피드포워드 신경망으로 시점이 \( t = 1, 2, ... , T \)인 단어 \( w_1, w_2, ... , w_T \)에 대해서 \(w_t \)가 타깃이라면, 맥락인 \( w_{t-1} \), \( w_{t+1} \)만 고려해 \( w_t \)를 추축한다. (윈도우 크기가 1) 

■ 이를 확률에 대한 식으로 나타내면 \( P(w_t \mid w_{t-1}, w_{t+1}) \)인데, 이 식을 통해 알 수 있는 것은 CBOW 모델은 \( w_t \)를 추측할 때, \( w_1, w_2, w_3, ... \)같은 더 이전 시점의 정보를 고려하기 어렵다는 것이다.

- 윈도우를 늘려 더 이전 시점을 고려할 수 있지만, CBOW 모델은 입력층의 단어 벡터들이 더해져 은닉층으로 전달되기 때문에 맥락 안의 단어 순서가 무시된다는 한계점이 있다. 

- 예를 들어 CBOW 모델은 다음 그림처럼 단어 벡터들이 더해지기 때문에 (you, say)와 (say, you)라는 맥락이 똑같이 취급된다.

- 이 문제를 해결하기 위해 각 맥락 단어마다 고유한 은닉층과 연결하여 계산하는 방법이 있으나, 이 경우 각 맥락 단어마다 별도의 은닉층 벡터(뉴런)이 필요하므로 가중치 매개변수의 수가 크게 증가하게 된다.

 

2. 언어 모델(Language Model) 

■ 언어 모델은 어떤 문장에 \( 1, 2, 3, ... , m \)이라는 순서로 나열된 \( w_1, w_2, \cdots, w_m \) 단어 시퀀스에 확률을 부여해서 가장 자연스러운 단어 시퀀스를 찾아내는 모델이다. 

■ 단어 시퀀스에 확률을 할당하는 일반적인 방법은 이전 시점의 단어들이 주어졌을 때, 언어 모델이 다음 단어를 예측하도록 하는 방법이다.

- 특정 단어의 시퀀스에 대해 이 시퀀스가 발생할 가능성이 어느 정도인지, 즉 특정 단어가 순서에 맞춰 등장했을 때 얼마나 자연스러운 단어 순서인지를 확률로 평가한다.

- 예를 들어 언어 모델은 'You say goodbye and I say hello.'처럼 자연스러운 단어 시퀀스에는 높은 확률을, 'You goobye I'처럼 부자연스러운 단어 시퀀스에는 낮은 확률을 출력한다.

- 이처럼 언어 모델은 마치 문법(grammar)같이 단어 시퀀스가 얼마나 적절한지를 판별해주는 역할을 한다.

■ \( w_1, \cdots, w_m \)이라는 \( m \)개 단어로 만든 문장이 있을 때, 이 문장이 \( 1, \cdots, m \)이라는 올바른 시점에 맞춰 단어가 \( w_1, \cdots, w_m \) 순서로 등장할 확률은 \( w_1, \cdots, w_m \)이 동시에 발생할 확률인 \( P(w_1, \cdots , w_m) \)으로 나타낼 수 있다.

■ \( w_1, \cdots, w_m \)은 시퀀스 단어이므로, 예를 들어 \( w_m \)이 등장했을 때 \( w_m \)이 자연스러운 단어 순서인가에 대한 평가는 \( w_m \)의 이전 단어들 \( w_1, \cdots, w_{m-1} \)이 등장했다는 전제 하에 이뤄져야 한다.

■ 즉, \( w_m \)의 등장이 자연스러운 단어 순서인지는 확률 \( P(w_m \mid w_1, \cdots, w_{m-1}) \), \( w_{m-1} \)의 순서에 대한 평가는 \( P(w_{m-1} \mid w_1, \cdots, w_{m-2}) \), ... , \( w_3 \)은 \( P(w_3 \mid w_1, w_2) \), \( w_2 \)는 \( P(w_2 \mid w_1) \) \( w_1 \)은 \( P(w_1) \)이 된다.

■ \( P(w_1, \cdots, w_m) \)은 단어 \( w_1 \)부터 \( w_m \) 순서로 출현할 확률이기 때문에 \( P(w_1, \cdots, w_m) \)을 \( P(w_m \mid w_1, \cdots, w_{m-1}) \)부터 \( P(w_1) \)의 곱으로 표현할 수 있다.

- 동시 확률은 조건부 확률을 곱하는 방식으로 나타낼 수 있다.

- 조건부 확률의 정의 \( P(w_2 \mid w_1) = \dfrac{P(w_1, w_2)}{P(w_1)} \)를 \( P(w_1, w_2) = P(w_1) \cdot P(w_2 \mid w_1) \)으로 나타낼 수 있다.
- 이를 반복적으로 적용하면 \( P(w_1, w_2, w_3) = P(w_1) \cdot P(w_2 \mid w_1) \cdot P(w_3 \mid w_1, w_2) \)

■ 만약, 타깃 단어가 \( w_t \)라면 \( w_t \)의 위치는 \( w_1, w_2, \cdots, w_{t-1}, w_t, w_{t+1}, \cdots, w_m \), \( w_{t-1} \)의 다음 위치이기 때문에 \( P(w_t \mid w_1, \cdots, w_{t-1}) \)을 계산하면 된다. 

■ 동시 확률 \( P(w_1, \cdots, w_m) \)의 수식은 다음과 같이 사후 확률의 총 곱으로 나타낼 수 있다. \[ P(w_1, \cdots, w_m) = P(w_m \mid w_1, \cdots, w_{m-1}) P(w_{m-1} \mid w_1, \cdots, w_{m-2}) \cdots P(w_3 \mid w_1, w_2) P(w_2 \mid w_1) P(w_1) = \prod_{t=1}^m P(w_t \mid w_1, \cdots, w_{t-1}) \]cf) \( P(w_t \mid w_1, \cdots, w_{t-1}) \)을 나타내는 모델을 조건부 언어 모델(Conditional Language Model)이라고도 한다. 

 

3. 순환 신경망(Recurrent Neural Network, RNN)

RNN은 피드포워드 신경망과 달리 다음 그림처럼 순환 경로(닫힌 경로)가 존재한다. 입력 데이터는 이 경로를 이용해 끊임없이 갱신된다.

RNN 계층 순환 구조

- \( t \)는 시점, \( x_0, x_1, \cdots, x_t, \cdots \)는 시계열 데이터, \( h_0, h_1, \cdots, h_t, \cdots \)는 입력 \( x_0, x_1, \cdots, x_t, \cdots \)에 대한 출력

■ 이 순환 경로로 시계열 데이터가 순환될 때, 과거의 정보를 기억하는 동시에 최신 데이터로 갱신하기 때문에 긴 시계열 데이터가 들어와도 대응할 수 있다.

- 이처럼 RNN 계층은 일종의 메모리(기억력) 역할을 수행하여 이를 메모리 셀 또는 RNN 셀이라고도 표현한다.

■ 입력 \( x_t \)를 벡터라고 할 때, 단어 순서를 다루는 경우 각 단어의 분산 표현은 \( x_ t \)이며, 분산 표현 \( x_t \)가 순서대로 하나씩 RNN 계층에 입력된다.

■ 이 순환 구조를 시점 기준으로 펼치면 다음과 같이 한 방향으로 연산이 수행되는 피드포워드 신경망으로 볼 수 있다.

■ 위의 구조와 같이 각 시점의 RNN 계층은 그 계층에서의 데이터 1개와 직전 계층의 출력 결과를 받아 현재 시점의 출력을 계산한다. 이때 수행되는 계산의 수식은 다음과 같다. \[ h_t = \text{tanh}(h_{t-1} W_h + x_t W_x + b) \] - RNN 계층에는 입력 \( x \)를 출력 \( h \)로 변환하기 위한 가중치 \( W_x \)와 직전 (RNN) 계층의 출력을 다음 시각의 출력으로 변환하기 위한 가중치 \( W_h \)가 있다.

- \( h_{t-1} \)과 \( x_t \)는 행 벡터, \( b \)는 편향

- \( h_{t-1} W_h + x_t W_x + b \)의 결과에 tanh 함수를 적용시켜 시점 \( t \)의 출력 \( h_t \)로 변환한다.

현재 시점 \( t \)의 출력 \( h_t \)를 은닉 상태(hidden state), 은닉 상태 벡터라고 부른다.

은닉 상태 \( h_t \)는 \( t = 1\)부터 \( t = t-1 \) 시점까지의 (정확히는 \( t = 1\)부터 \( t = t-1 \) 시점까지의 은닉 상태) 정보를 계승한 것으로 볼 수 있다.

- 이러한 특징 때문에 RNN 계층이 메모리(기억력) 역할을 수행한다고 말할 수 있는 것이다. 

■ 순환 구조이므로 \( h_t \)는 다음 계층으로 전달되는 동시에 자기 자신의 RNN 계층으로도 전달된다.

■ 계산된 \( h_t \)는 다음 계층으로 전달된다. 이 계층을 출력층 \( y_t \)라고 하자. 그러면 \( y_t = f(W_y h_t + b) \)로 계산될 것이다.

- \( W_y \)는 \( h_t \)에서 \( y_t \)로 향할때 곱해지는 가중치

- \( f \)는 비선형 활성화 함수

■ RNN의 은닉층 연산 \( h_t = \text{tanh}(h_{t-1} W_h + x_t W_x + b) \)을 벡터와 행렬 연산으로 나타낼 수 있다.

- 입력 \( x_t \)를 단어 벡터라고 했을 때, 이 단어 벡터의 차원을 \( d \)라고 하자.

- 그리고 은닉 상태의 크기를 \( D_h \)라고 한다면, 

- \( x_t \)를 열벡터로 간주했을 때 \( x_t \)의 크기는 \( d \times 1 \), 은닉 상태인 \( h_t \)와 \( h_{t-1} \)의 크기는 \( D_h \times 1 \)

- 이를 통해 \( W_h \)의 크기는 \( D_h \times D_h \), \( W_x \)의 크기는 \( D_h \times d \), 편향의 크기는 \( D_h \times 1 \)임을 유추할 수 있다.

 

4. BPTT(Backpropagation Through Time)

■ 위의 그림처럼 RNN 계층은 순환 구조를 시간축으로 펼치면 일반적인 신경망의 구조(피드포워드 신경망 구조)이기 때문에 다음과 같은 순서로 학습(순전파 & 역전파)을 진행할 수 있다.

■ 이때의 오차역전파는 단순 신경망을 학습시키기 위해 사용했던 오차역전파와는 다르게 '시간 방향으로 펼친 신경망'을 학습시키기 위한 오차역전파이다. 이 알고리즘을 BPTT라고 한다.

■ 단, BPTT를 이용해 RNN을 학습할 때 큰 시계열 데이터(시간 크기가 큰 데이터)를 사용하면, 시간(\(t = 1, 2, ... \)) 크기에 비례해 메모리 사용량이 증가한다는 문제와 시간 크기가 클수록(길이가 긴 시계열 데이터) 역전파 시, 기울기가 불안정해지는 문제가 있다.

 

5. Truncated BPTT

■ BPTT의 문제(큰 시계열 데이터 학습 시의 문제)를 해결하고자 사용하는 기법이 Truncated BPTT이다. 

Truncated BPTT의 아이디어는 큰 시계열 데이터를 사용할 때, 신경망 연결을 적당한 지점에서 잘라내고, 잘라낸 작은 신경망 블록들로 학습을 수행하는 것이다.

단, 신경망의 연결을 끊는 순간은 역전파 과정에서만이다. 즉, 순전파 연결은 그대로 유지하면서 진행하고 역전파 과정에서만 역전파 연결을 적당한 지점에서 잘라내어, 잘라낸 작은 신경망들로 학습을 수행한다.

■ 예를 들어 시간 크기가 1,000인(\( t = 1, 2, ... , 1000) \)) 시계열 데이터가 있을 때, RNN 계층을 펼치면 가로 방향으로 1,000개가 연결된 신경망 구조가 된다.

■ 이 상태에서 BPTT를 사용하면 계산량, 메모리 사용량 문제와 기울기 소실 문제가 발생할 수 있다. 이러한 이유로 다음과 같이 Truncated BPTT를 사용하는 것이다.

- 이 예에서는 RNN 계층을 10개씩 잘라내 역전파 과정에서만 RNN 계층을 10개 단위로 학습을 수행한다. 여기서 이 10개 단위를 하나의 '블록'이라 하며, 각 블록은 다른 블록과 독립적으로 오차역전파를 진행한다.

■ 위의 그림과 같이 Truncated BPTT 기법으로 RNN을 학습시키는 방법은 다음과 같다.

- 가장 먼저 할 일은 입력 데이터를 넣는 것이다. 이때 하나의 블록에는 RNN 계층이 10개로 구성되어 있고, 전체 구조가 블록 단위로 나뉘어져 있으므로

- 먼저, 첫 번째 블록 입력 데이터 \( (x_0, x_1, \cdots, x_9) \)를 RNN 계층에 넣어야 한다.

- 이때의 순전파, 역전파 과정은 다음과 같다.

 

- 중요한 것은 전파 흐름이 역전파에서만 끊긴다는 것이고, 

- 이 예에서의 역전파 과정은 두 번째 블록에서의 기울기가 끊겼기 때문에, 첫 번째 블록 내에서만 오차역전파가 진행된다.

- 두 번째 블록도 마찬가지이다. 두 번째 블록 입력 데이터 \( (x_{10}, x_{11}, \cdots, x_{19}) \)를 넣고, 동일한 방식으로 순전파를 수행한 다음, 오차역전파를 수행한다.

- 마찬가지로 세 번째 블록에서의 기울기가 끊겼기 때문에, 두 번째 블록 내에서만 오차역전파가 진행된다.

- 이때, 첫 번째 블록의 순전파에서는 첫 번째 블록의 순전파 결과인 \( h_9 \)가 연결되고, 두 번째 블록의 순전파에서는 두 번째 블록의 순전파 결과인 \( h_{19} \)가 연결된 것을 볼 수 있다. 이를 '은닉 상태(h)'를 계승했다.'고 하며

RNN 학습은 이런 식으로

- (1) 각 블록의 '입력 데이터를 순서대로 넣고',

- (2) 이전 블록의 은닉 상태를 계승해서 '순전파의 흐름만 마지막 블록까지 계속 연결하고',

- (3) '오차 역전파는 각 블록 내에서 독립적으로 수행'한다.

5.1 Truncated BPTT의 미니배치 학습

■ 위의 예시는 미니배치 수가 1일 때의 과정이다. 

Truncated BPTT 기법은 입력 데이터를 '순서대로'넣어야 한다.

- 위의 예시에서는 길이가 1,000인 시계열 데이터를 10개 단위로 잘랐기 때문에 총 100묶음으로, 첫 번째 블록에 들어가는 입력 데이터는 \( (x_0, x_1, \cdots, x_9) \), 두 번째 블록에 들어가는 입력 데이터는 \( (x_{10}, x_{11}, \cdots, x_{19}) \)이다.

- 만약 미니배치의 수가 2라면, \( x_0 \)부터 \( x_{499} \)까지 50 묶음, \( x_{500} \)부터 \( x_{999} \)까지 50묶음이 된다.

- 이때, 첫 번째 블록에서 첫 번째 미니배치 때는 데이터 \( (x_0, x_1, \cdots, x_9) \)가 들어가고, 두 번째 미니배치 때는 \( x_{500}, x_{501}, \cdots, x_{509} \)가 들어가도록 위치를 500만큼 옮겨주면 된다.

- 그러면 두 번째 블록에서는 첫 번째 미니배치 때는 \( (x_{10}, x_{11}, \cdots, x_{19}) \), 두 번째 미니배치 때는 \( x_{510}, x_{511}, \cdots, x_{519} \)가 들어간다. 이렇게 시작 위치를 옮겨서 순서대로 데이터를 넣으면 된다.

[출처] https://velog.io/@a01152a/%EC%88%9C%ED%99%98-%EC%8B%A0%EA%B2%BD%EB%A7%9D-RNN-1

■ 미니배치를 구성해 학습을 수행한다면, 이렇게 시작 위치를 옮겨서 데이터를 순서대로 입력하면 된다. 만약, 끝에 도달했다면 다시 처음부터 입력하면 된다.

■ 참고로 \( (x_0, x_1, \cdots, x_9) \)나 \( (x_{500}, x_{501}, \cdots, x_{509}) \)같은 입력 데이터에는 시간 정보가 있으므로 각 데이터의 원소들을 \( (x_9, x_0, \cdots, x_1) \), \( (x_{506}, x_{503}, \cdots, x_{509}) \)처럼 셔플을 적용할 수는 없다.

■ 단, 미니배치에 있는 입력 데이터 \( (x_0, x_1, \cdots, x_9) \)와 \( (x_{500}, x_{501}, \cdots, x_{509}) \)는 독립이다. \( h_9 \)를 계산할 때 데이터 \( (x_0, x_1, \cdots, x_9) \)만 사용하고 \( h_509 \)를 계산할 때는 \( (x_{500}, x_{501}, \cdots, x_{509}) \)만 사용하기 때문이다.

그러므로 미니배치에 들어 있는 입력 데이터의 순서는 셔플해서 사용해도 무방하다.

 

6. RNN 구현

https://hyeon-jae.tistory.com/142

'딥러닝' 카테고리의 다른 글

게이트(gate)가 추가된 RNN - LSTM, GRU  (0) 2025.01.06
순환 신경망(RNN) (2)  (0) 2025.01.06
합성곱 신경망(CNN) (2)  (0) 2024.12.06
word2vec 속도 개선 (1)  (0) 2024.11.27
단어의 의미를 파악하는 방법 (4)  (0) 2024.11.22