AI/자연어처리(NLP)

[Stanford 강의] Lecture 5 : Recurrent Neural Networks

CSE 2025. 12. 9. 02:32

과적합과 정규화

이전에는 과적합이 좋지 않은 것으로 여겨졌지만, 현대의 거대 모델들은 훈련 데이터에 거의 완벽히 과적합 되도록 학습시킨다.

만약 정규화를 잘 수행했다면 모델은 훈련 데이터가 아닌 다른 데이터에도 잘 일반화되기 때문이다.

 

정규화는 여러가지 방법이 있지만 이 중 Dropout이라는 방식을 알아보자.

과제 2에서 이미 한번 나온 개념이지만, 다시 얘기하면 훈련 중에 중간 layer에서 몇몇 입력을 버리는 것이다.

이를 위해 0과 1로 이루어진 마스크 행렬을 요소별 곱셈을 하면 된다.

 

이렇게 하면 모델은 하나의 입력에 강하게 의존할 수 없다.

이 입력이 가끔 사라진 상태로 학습도 되기 때문이다.

 

테스트 시에는 모든 입력을 활성화 시킨다.

 

이게 좋은 이유에 대한 해석은 몇가지가 있는데,

1. Feature co-adaptation, 특징 간 공동 적응을 방지한다.

모델은 3번 6번 특징이 예측에 좋다고 학습하지 않고 이런 특징들이 언젠가 누락될 수도 있기 때문에 더 유연하게 학습을 해야한다.

2. 모델 앙상블, 서로 다른 모델을 합해 결과를 개선하는 효과와 같기 때문이다.

 

훈련을 시작할 때, 신경망 행렬의 초기화를 모두 0또는 다른 상수로 하면 대칭성이 생겨 학습의 방향을 찾기가 어려워진다.

따라서 무작위 숫자로 초기화가 필요하다.

조금 더 자세히 얘기하면, 행렬은 모든 원소에 같은 연산을 적용하는데 모든 원소의 값이 같다면 단순히 하나의 특징을 복사한 것밖에 되지 않기 때문이다.

 

또 과제2에 나왔던 내용 중 옵티마이저 라는 것도 있었다.

각 파라미터에 대한 과거의 기울기를 고려하는 것이다.

 


언어 모델(Language Models)

언어 모델의 아이디어는 다음에 어떤 단어가 올지 예측하는 것이다.

즉 다음에 올 단어의 확률 분포를 구하는 것이다.

식으로 쓰면 아래와 같다.

앞에 주어진 t개의 단어에 대해 $x^{(t+1)}$라는 단어가 나올 확률을 나타낸다.

아래 식은 t개의 단어로 이루어진 문장이 나올 확률을 나타낸다.

아무단어도 없을때 첫 단어가 나올 확률부터 마지막 단어까지의 확률을 곱해서 구할 수 있다.

n-gram 언어 모델

n은 숫자를 얘기한다.

아래 빈칸에 들어갈 단어를 찾는 방법은 여러가지가 있다.

한단어의 확률만 보면 unigram이고, 두쌍의 단어 확률을 보면 bigram,...이런 식으로 단어 수에 따라 여러 방법이 있다.

n-gram의 종류

 

Markov assumption

어떤 단어를 예측할 때 앞의 모든 문장을 사용하는 것이 아니라 바로 이전 n-1개의 단어만 사용해 예측하는 것이다.

만약 4-gram 언어 모델을 사용한다면 아래와 같다.

즉 훈련 데이터에서 각 조합의 수를 세서 비율을 따지는 것이다.

그러나 이 방법은 좀 성능이 좋지 않다.

훈련데이터(corpus)에 있지 않았던 조합은 count가 0이므로 확률도 0이 될 것이다.

 

가장 간단히 이를 해결하는 방법은 분자에 0.25같은 작은 수를 더해주는 것이다.

한번도 나오지 않아도 분자는 0이 되지 않고, 1번 나왔다면 1.25가 분자가 된다.

 

만약 분모의 조합도 한번도 나오지 않았다면 분모가 0이 되어버린다.

이 때는 opened their이 조합을 count를 해보고 이도 안되면 their의 한단어에 대해 카운트를 해본다.

 

정확하려면 n-gram의 n값이 크면 좋을 것이다. 대신 그만큼 카운트 횟수는 줄어든다.

또 이 많은 조합들을 저장하는데 용량 문제도 생길 수 있다.

보통 실제로 사용된 최대 n-gram은 5-gram이었다.

 

이 방법은 신경망이 없다. 그냥 세기만 하면 된다.

학습 데이터 양이 많아지고 n의 값이 커질수록 좋아지지만 사람들은 다른 방법을 생각해냈다.


 fixed-window neural Language Model

신경망을 사용해 다음 단어를 예측하는 모델이다.

이전 글에서 봤던 방법과 거의 비슷하게, 단어 벡터들을 연결해 입력으로 사용한다.

최종 출력은 각 단어가 나올 확률 값이 된다.

fixed-window라는 것은 입력으로 들어가는 단어의 개수가 일정하다는 것을 의미한다.

얼핏 보면 n-gram과 비슷한 것 같지만, 이 방법은 희소성 문제 저장공간 문제를 해결할 수 있었다.

더 이상 모든 단어의 조합을 저장할 필요 없이 신경망의 파라미터만 저장하면 된다.

 

하지만 이 방법도 문제가 있다.

윈도우의 사이즈를 늘리면 연산이 많아진다는 단점이 있다.

 

두번째 단점으로 아래의 예시를 보자.

students slowly opened their, the students opend their 의 뒤에 모두 book이 올 만 하다.

이 예측에 가장 중요한 단어는 student라고 생각할 수 있는데 이 두 경우에서 student의 위치가 다르다.

이 모델에서는 이 두 student를 학습하는데 완전히 다른 파라미터가 사용될 것이다.

이는 비효율적이다.


Recurrent Neural Networks (RNN)

위의 단점들을 보완하기 위해 RNN이라는 신경망이 나오게 되었다.

지금까지는 word2vec, Feed Forward Network알아봤고, 이번 글에서 RNN를 알아보고, 그 이후 transformer를 알아볼 것이다.

 

기본적으로 단어 하나하나를 거치면서 은닉층에 가중치가 재귀적으로 곱해져 은닉층의 값이 바뀌는 것이다.

이 방식으로 은닉층은 이전 단어들을 정보를 모두 포함한다.

이 방식은 단어의 길이가 길어도 저장공간이 더 필요하지 않다.

단어가 늘어날 때마다 계산만 더 해주면 되지만, 이 부분이 시간의 측면에서 손해이다.

또 하나의 문제는 이전 단어에 대한 기억이 금방 희미해지는 것이다.

 


RNN 학습

다음에 올 단어의 확률 예측한 결과와 실제 단어의 차이를 손실 함수로 사용할 것이다.

전체 단어에 대해서는 아래처럼 평균을 내어 손실 함수를 설정한다.

아래 예시에 적용해보자.

첫 단어가 the일 확률을 대강 0.05라고 예상했다면 여기서 오는 손실함수 값이 있을 것이다.

the가 있는 상황에서 그 다음에 오는 단어를 students로 예측했을 확률도 있을 것이다. 여기서도 손실값이 발생한다.

이런 값들을 모두 더해 평균내면 그것이 전체의 손실 값이 된다.

 

실제로는 엄청나게 긴 데이터들이 훈련에 사용될텐데, 이 긴 데이터를 한번에 훈련하는 것은 어렵다.

그래서 segment라는 합리적인 길이로 잘라 학습시키는 것이다.

 

RNN에서의 역전파

아래처럼 구할 수 있다.

$$\frac{\partial J}{\partial W} = \frac{\partial}{\partial W} \left( \sum_{t=1}^{T} J^{(t)} \right) = \sum_{t=1}^{T} \frac{\partial J^{(t)}}{\partial W}$$

 

RNN이 글을 만드는 방법

위에서 얘기한 것과 같은 내용이다.

좀 더 디테일하게 알 것은 갑자기 문장의 첫 단어가 나오는 것이 아니고 <s>라는 심볼에서 첫 단어가 시작되고,</s>로 끝난다는 것이다.