본문 바로가기

교육/CS224N winter 2021

Lec5) Language Models and RNNs

 

이전 강의: https://enjoythehobby.tistory.com/entry/Lec-4-Dependency-Parsing

 

Lec 4) Dependency Parsing

이전 강의: https://enjoythehobby.tistory.com/entry/Lec3-Backprop-and-Neural-Networks Lec3) Backprop and Neural Networks 이전 강의: https://enjoythehobby.tistory.com/entry/Lec-2-Neural-Classifiers Le..

enjoythehobby.tistory.com

지난 강의에 이어

Neural dependency parsing 에서 행동 결정

문제점

  1. sparse vectors (one-hot encoding)
  2. 없는 features 가 존재 (incomplete)
    : 모든 경우의 수를 고려하다보니 예를 들어 어떤 단어는 동사 앞에 나오지 않는 경우 해당 feature는 존재하지 않음
  3. 많은 계산량 (95%의 시간이 feature computation에 소요, 신경망으로 개선의 여지가 있다.

Indicator features의 많은 연산량을 dense vectors 로 변환하여 신경망을 통해 학습하는 방식으로 접근해 볼 수 있다.

Indicator features을 ~1000의 dense vector로 변환

 

A neural dependency parser [Chen and Manning 2014]

신경망을 도입함으로써 MaltParser → Chen and Mannig 2014로 성능과 속도가 향상됐다.

MST와 Turbo Parser는 graph 기반으로 신경망 이전까지 높은 정확도로 대세였으나 속도가 느리다는 단점이 존재했다.

각 Parser를 이용한 Stanford dependencies에 대한 영어 parsing 결과 (Unlabeled attachment score (UAS) = head, Labeled attachment score (LAS) = head and label)

어떻게 성능과 속도를 전부 향상시킬 수 있었을까?

 

○ 첫번째: Distributed Representations

  • word embedding과 같은 방식을 통한 각 단어의 d-차원의 dense 벡터로 표현 (유사한 단어는 인접한 벡터로 표현)
  • 품사(part-of-speech tags, POS)dependency labels도 d-차원의 벡터로 표현
    : 비록 적은 수의 집합이지만 벡터로 표현하면 유사한 품사는 인접하게 된다. 예를들어 복수 명사(plural noun, NNS)와 단수 명사(singular noun, NN)는 가까지 존재할 것이다.

현재 상태에 해당하는 단어, POS, dependencies를 토큰화한 후 벡터로 표현한 뒤 concatenation한다

 

○ 두번째: 딥러닝 분류기는 비선형

고전적인 ML 분류기들(Naive Bayes, SVMs, logistic regression 그리고 softmax 포함)은 선형 decision boundaries를 제공하기에 그렇게 강력한 분류기는 아니다. 그 중 softmax 분류기 수식은 아래와 같으며, $W\in\mathbb{R}^{ C \times d}$의 가중치 행렬을 손실함수를 최소화하는 방향으로 학습한다.

$$P(y|x)=\frac{exp(W_{y}\cdot x)}{\sum_{c=1}^{C}exp(W_{c}\cdot x)}, y\in C, x\in \mathbb{R^{d}}$$

(좌) 고전적인 ML 분류기를 이용한 경우, 빨간 영역으로 분류된 곳에 초록색 값을 가지는 데이터가 보인다. (우) 신경망 위에 softmax 분류기를 쌓은 경우 복잡한 데이터도 잘 분류하는 것이 확인된다.

신경망의 경우 비선형 활성화 함수가 포함되어있기 때문에 신경망 위에 분류기를 올려서 사용하면 훨씬 복잡한 분류도 해낼 수 있다. 간단하게 신경망 분류 모델의 구조를 보면 아래와 같다. 여기서 ReLU(Retified Linear Unit)이 비선형 활성화함수이다.

신경망 분류 모델의 구조, 실제로는 입력층 전에 dense 벡터로 변화해주는 lookup층이 존재한다.

이 원리를 neural dependency parser에 적용하면 아래와 같은 아키텍처를 보인다.

neural dependency parser 아키텍처, 각 상태에서 dependency parsing을 위한 최적 행동을 정해준다.

 

위 두 가지 방식을 이용하여 Chen and Manning(2014)은 성능과 속도면에서 성공적인 neural dependency parser였다. 

 

○ Transition-based neural dependency parsing 의 발전

이후 다음과 같은 형태로 Transition-based neural dependency parser는 발전되었다.

  • 크고 깊은 신경망
  • Beam search
  • Global, conditional random field(CRF) 스타일의 추론 

2014년 이후 발전된 dependency parser

○ Graph-based dependency parser

각 단어의 모든 가능한 head의 확률을 계산하는 방식으로 단순하게 두단어의 관계 뿐만 아니라 모든 단어 간의 관계를 알 수 있다.

big의 head로 cat이 가장 높은 점수를 보이고 있다.

○ A Neural graph-based dependency parser

Graph-based dependency parser에 신경망을 도입함으로써 2017년 더 좋은 성능의 모델을 얻을 수 있었다. 그러나 $n$길이의 문장은 $n^{2}$개의 dependencies를 가질 수 있기 때문에 단순한 neural transition-based parsers보다 훨씬 느리다.

Dozat and Manning 2017; Dozat, Qi, and Manning 2017의 Neural graph-based dependency parser


추가적인 신경망 내용

○ 정규화(Regularization)

신경망은 수많은 매개변수($\theta$)를 가지고있기 때문에 정규화가 필요하다. 예를들어 L2 정규화

$$J(\theta))=\frac{1}{N}\sum_{i=1}^{N}-log(\frac{e^{f_{yi}}}{\sum_{c=1}^{C}e^{f_{c}}}) + \textcolor{blue}{\lambda\sum_{k}\theta^{2}_{k}}$$

모델을 학습할 때 매개변수가 정말로 유용한 경우에만 매개변수를 0이 아닌값으로 만들려고 하는데, 정규화 항을 추가하면 매개변수가 큰 도움이 되지 않는 범위에서는 0이 아닌 값으로 함으로써 불이익을 받게 된다. 그러나 매개변수가 도움이 되는 범위에서는 가능성을 추정하는 데 도움이 되기 때문에 0이 아닌 것도 괜찮다.

과적합 예시, 많은 학습을 통해 학습데이터를 예측을 잘한다고 해서 다른 데이터에 대해서도 예측을 잘하게 되는 것은 아니다.

이러한 정규화는 문제가 되어왔던 과적합(Overfitting)을 방지하기 위해서 사용된다. 과적합이란 학습데이터를 지나치게 학습하여 세부적인 특징까지 학습해 버린 결과, 다른 데이터셋의 경우에는 오히려 예측 정확도가 떨어지게 되는 것을 의미한다. 따라서 고전적인 관점에서 일반적인 특징만 학습하는 것이 중요하다.

그러나 요즘엔 거대한 모델을 사용하는데 반해 데이터가 적기 때문에 과적합을 신경쓰지 않는 대신 단순히 모델을 잘 일반화 시키기위해 사용된다

그래서 얼마만큼 정규화를 시킬지가 중요한데 이 것을 $\lambda$를 통해 조절하며 값이 클수록 더 많이 정규화 한다.

 

○ 드롭아웃(Dropout, Srivastava, Hinton, Krizhevsky, Sutskever, & Salakhutdinov 2012/JMLR 2014)

 Preventing Feature Co-adaptation = 좋은 정규화 방법!

여기서 Co-adaptation이란 뉴런들 간 상호의존적이게 되는 것으로 서로 같은 특징에 대해 학습하기 때문에 중복적인 역할을 하게된다. 이를 막기 위해서 드롭아웃(Dropout)을 사용한다.

  • 학습시: 평가할 때 일부 뉴런에 대한 입력값을 0으로 한다(비활성화)
  • 테스트시: 모든 모델 가중치를 이용하여 평가한다.

이는 앙상블(ensemble)과 같은 model bagging으로 생각할 수 있으며, 최근 가장 강력한 정규화 방법 중 하나다.

직관적으로 생각해 봤을 때, 적게 사용되는 특징이 더 많이 정규화 된다. 

○ 비선형 함수

신경망을 여러층을 쌓아서 효과를 보기 위해서는 비선형 함수가 필요하다. 가장 8,90년대에 사용된 대표적인 비선형 함수는 로지스틱(logistic) 혹은 시그모이드(sigmoid)함수이다. 그러나 0~1사이의 출력을 내기 때문에 항상 모든 것을 양의 영역으로 보내버리는 문제가 있다. 이를 해결하기 위해 tanh함수가 등장하였으며 이는 로지스틱함수를 단순히 재조정($tanh(z) = 2logistic(2z)-1$)한 값이다. 이후에 더욱 단순하게 비선형함수를 설계해보자는 아이디어에서 hard tanh함수가 등장한다. 일정 범위 밖에서는 증감이 없기 때문에 이상해보이나 굉장히 성공적인 결과를 보여주었고 이를 개량하여 가장 성공적이고 일반적으로 널리 사용되는 ReLU(rectified linear unit)이 등장한다.

로지스틱과 tanh는 여전히 확률을 구하는데 많이 사용되나 대부분 딥러닝에 일반적으로는 굉장히 빠르게 학습이 가능하기 때문에 ReLU를 사용한다. 이후에는 Leaky ReLu, Parametric ReLU, Swish 등의 ReLU의 개선된 비선형 함수들이 등장하였다. 

대표적인 비선형 함수들

○ 매개변수 초기화(Parameter Initialization)

대부분의 경우 무조건 너무 크지도 작지도 않은 작은 임의의 값으로 시작하여야한다. 행렬을 0으로 시작하면 모든 것이 대칭이 되기 때문에 딥러닝을 사용하는 의미가 없어집니다. 따라서 가중치의 경우 $Uniform(-r, r)$ 범위에서 초기화를 진행하며, 편차의 경우는 0으로 초기화 하는 것이 좋습니다.

대표적인 방법으로는 Xavier 초기화가 있으며 분산이 이전 층의 크기($n_{in}$)와 다음층의 크기($n_{out}$)에 반비례 합니다

$$Var(W_{i})=\frac{2}{n_{in}+n_{out}}$$

 

○ 옵티마이저(Optimizers)

우리는 SGD에 대해 간단이 배웠다. 모델을 학습할 때 가중치를 얼마나 조정할지 결정해주는 역할을 하며 다양하게 발전되어 왔다. 일반적으로 Adam이 좋으며 pytorch에서 제공하므로 이를 사용하기를 권장하고 자세한 내용은 넘어가겠다.

  • Adagrad
  • RMSprop
  • Adam
  • SparseAdam

○ 학습률(Learning rates)

학습률은 학습 시 기울기를 기반으로 얼마만큼 매개변수를 변화시킬지를 결정하는 상수이며 일반적으로 $10^{-3}$ 정도를 사용하면 무난하다.

  • 학습률이 큰 경우: 모델이 발산하거나 수렴에 실패
  • 학습률이 작은 경우: 모델이 수렴하는데 오랜 시간이 소요

즉, 효율적인 학습을 위해서는 매 에포크(epoch)마다 학습률을 점진적으로 낮추어 주는 것이 좋다.

$$ lr = lr_{0}^{-kt}$$

이 때 매 에포크(t) 내 배치의 순서는 섞어서 매번 다르게 들어가야 그 규칙을 학습하지 않는다.

최신 옵티마이저의 경우에도 학습률을 변수로서 요구하는데 이 경우에는 대부분 초기 학습률을 의미한다.


언어 모델링(Language Modeling) + RNNs

언어 모델링(Language Modeling)

언어 모델링 정의: 문맥을 보고 다음에 오는 단어가 무엇인지를 예측하는 작업

언어 모델링의 예시, 앞선 단어의 나열을 기반으로 빈칸의 단어가 무엇이 올지를 예측한다.

수식으로 표현하면 주어진 단어의 나열 $x^{(1)}, x^{(2)}, ..., x^{(t)}$에서 다음 단어 $x^{(t+1)}$의 확률 분포를 계산한다.

$$ P(x^{(t+1)}|x^{(t)}, ..., x^{(1)}) $$

이 때 $x^{(t+1)}$는 vocabulary $V = \{ w_{1},w_{2},...,w_{|V|}, \}$ 내의 어떤 단어든 가능하다.

이러한 시스템을 언어 모델이라고 한다.

 

언어 모델을 다르게 보면 문서의 일부를 확률로 변환하는 것으로 생각해볼 수 있다.

위의 수식 예시에서 해당 문서의 확률은:

$$ P(x^{(1)}, x^{(2)}, ..., x^{(t)}) = P(x^{(1)})\times P(x^{(2)}|x^{(1)})\times ... \times P(x^{(t)}|x^{(t-1)}, ..., x^{(1)}) $$

$$ = \prod_{i=1}^{t}P(x^{(i)}|x^{(i-1)}, ..., x^{(1)}) $$

 

이러한 언어 모델은 우리가 매일 접하고 있으며, 구글 검색엔진에서의 언어 모델이 휴대폰보다 더 좋은 이유는 휴대폰의 경우 하드웨어에 제한이 있기 때문에 컴팩트한 모델을 사용한다.

휴대폰의 언어 모델
구글 검색 엔진의 언어 모델

n-gram 언어 모델

Q: 어떻게 언어 모델을 학습시킬까?

A: n-gram 언어 모델을 학습시키자!!

정의: n-gram은 연속적인 n개의 단어이다

  • unigrams: “the”, “students”, “opened”, ”their”
  • bigrams: “the students”, “students opened”, “opened their”
  • trigrams: “the students opened”, “students opened their”
  • 4-grams: “the students opened their”

아이디어: 서로 다른 n-grams의 빈도와 통계값을 수집하여 다음 단어의 예측에 사용

위 아이디어를 구현하기 위해 우선 Markov assumption을 한다.

$x^{(t+1)}$은 선행하는 $n-1$개의 단어들에 의해 결정된다.

$$P(x^{(t+1)}|x^{(t)}, ..., x^{(1)}) = P(x^{(t+1)}|x^{(t)}, ..., x^{(t-n+2)})$$

$$=  \frac{P(x^{(t+1)},x^{(t)} ..., x^{(t-n+2)})}{P(x^{(t)}, ..., x^{(t-n+2)})}$$

이제 문제는 분모, 분자의 확률을 각각 어떻게 구할 것인가인데, 이는 단순히 문서의 큰 말뭉치에서 갯수를 세어서 근사할 수 있다. 그러면 수식은 다음과 같다.

$$ \approx \frac{count(x^{(t+1)},x^{(t)} ..., x^{(t-n+2)})}{count(x^{(t)}, ..., x^{(t-n+2)})}$$

 

4-gram 언어 모델의 예시)

as the proctor started the clock, the students opened their _____

$$ P(w|\texttt{students opened thier}) =\frac{count(\texttt{students opened thier }w)}{count(\texttt{students opened thier})}  $$

만약 "students opened thier"가 1000개 있을 시,

  • "students opened thier books"가 400개 있으면 → $ P(\texttt{books}|\texttt{students opened thier})=0.4$
  • "students opened thier exams"가 100개 있으면 → $ P(\texttt{exams}|\texttt{students opened thier})=0.1$

 n-gram 언어 모델 문제점

희소성 문제(Sparsity Problems)

  • 만약 분자가 0이 된다면? → 작은 값(δ)을 모든 단어 w에 대한 개수에 더해준다 (스무딩, smoothing 이라고 한다)
  • 만약 분모가 0이 된다면? → 조건을 작은 grams으로 완화한다. 위의 예시에서는 "opened their"를 사용한다. (이를 backoff라고 한다)

n-grams이 커질수록 희소성 문제는 더 악화한다. 일반적으로 n은 5보다 큰 수를 사용하지 않는다

 

용량 문제(Stoage Problems)

  • 말뭉치 내의 모든 n-grams에 대해 저장해야하기 때문에 n 또는 말뭉치가 증가하면 모델 크기도 증가한다.

 n-gram 언어 모델 연습

170만개의 말뭉치를(Reuters, business & financial news) 가지고 trigram 언어 모델을 노트북에서 수초만에 학습이 가능하다.

 *Try for yourself: https://nlpforhackers.io/language-models/

 

Building Language Models

Tutorial for building generative Natural Language models using Python and NLTK. Start with BOW model and work our way up to building a trigram model.

nlpforhackers.io

학습 모델에 "today the"를 입력하고 뒤를 예측한 경우, Sparsity problem 때문에 확률밀도가 조밀하지 못하다. italian과 emirate가 1번, price는 2번, company와 bank는 3번 등장한 것처럼 보인다.

추천해주는 단어들로 도출한 문장은 다음과 같다.

today the price of gold per ton , while production of shoe 
lasts and shoe industry , the bank intervened just after it 
considered and rejected an imf demand to rebuild depleted 
european stocks , sept 30 end primary 76 cts a share .

문법에 어긋나지 않는 문장이지만, 말이 되지 않고 일관성도 없다. 

따라서 n의 개수를 높여야했지만, 이 경우 희소성 문제가 심해지기 때문에 신경망을 이용한 것과 같은 더 좋은 언어 모델이 필요했다.  

○ 신경망 언어 모델 구축

입출력이 아래와 같을 때 우리가 Lecture 3에서 NER task 때 배운 window-based 신경망에 적용해보자

입력: $x^{(1)}, x^{(2)}, ..., x^{(t)}$
출력: $P(x^{(t+1)}|x^{(t)}, ..., x^{(1)}) $

NER task에서 사용한 신경망, Paris를 장소라고 분류하고 있다

단순히 단어 벡터를 concatenate하여 입력한 후 은닉층(hidden layer)를 통과시킨 후 해당 벡터에 softmax를 취해주면 다음 단어의 확률 분포를 얻을 수 있다.

Fixed-window 신경망 언어 모델

"Y. Bengio, et al. (2000/2003): A Neural Probabilistic Language Model" 논문에서 신경망을 적용하여 훌륭한 해결책은 아니였지만 흥미롭고 괜찮은 결과를 보여주었다. 이 논문에서 n-grams처럼 다음 단어 예측을 위해 더 큰 문맥을 봐야하는 문제를 해결하지는 못했지만 distributed representation을 이용하는 것에 큰 이점이 있다.

 

n-gram 언어 모델에서의 개선점

  • 희소성 문제가 없다   
    : distributed representation을 사용하기 때문에 말뭉치에 없더라도 유사한 단어라면 예측이 가능(students ~ pupils)
  • 모든 관측된 n-grams를 저장해둘 필요가 없다
    : 단어 벡터와 W만 저장하면 된다

남은 문제

  • Fixed-window가 너무 작다. (크게하면 W의 크기도 커진다)
  • $x^{1}$과 $x^{2}$가 각각 다른 W가 곱해진다.
    : 즉 위치 간에 정보 교환이 없기 때문에 어순에 대한 고려가 되지 않는다.

즉, 우리는 임의의 양의 문맥을 처리할 수 있고 인접한 단어에 더 민감하게 매개변수를 더 많이 공유할 수 있는 신경 아키텍처가 필요하다

 

순환 신경망(Recurrent Neural Networks, RNN)

위의 문제를 해결하기 위한 방법으로 적용한 아이디어가 같은 가중치(W)를 반복적으로 적용하는 것이다. 임의의 단어들의 나열이 들어올 때를 아래 그림을 보며 생각해보자.

순환 신경망 아키텍처

첫 번째 단어 $x^{(1)}$이 들어오면 이전과 같이 distributed representation으로 변환한 후 은닉층에 넣어 hidden state $h^{(1)}$을 만들어 준다. 이 후 두번째 단어가 들어갈 때 앞서 생성된 $h^{(1)}$의 W를 가져와서 $h^{(2)}$를 생성한다. 해당 작업을 모든 단어에 대해 반복적으로 수행해주게되고 이 때문에 recurrent하다고 한다. 

다시 위의 예시에 RNN을 적용해보자

똑같이 단어 혹은 원-핫 벡터를 임베딩해준 후 $W_{e}$를 곱한 값에 이전 상태에 $W_{h}$를 곱한 값을 더해준다. 이 때 

initial hidden state $h^{(0)}$의 경우 일반적으로 0으로 초기화 해주고, 비선형 함수 σ는 tanh를 사용한다. 이후 마지막 단어에서 나온 벡터 $U$를 softmax 함수를 통해 예측하면 다음 단어의 확률 분포를 얻을 수 있다.

RNN 장점

  • 임의의 입력값을 처리 가능하다
  • (이론상) 여러 timestep 전의 정보를 이용하여 계산이 가능하다
  • 모델의 크기가 입력 크기에 영향을 받지 않는다
  • 같은 가중치가 모든 timestep에 적용된다. 즉, 입력이 어떻게 처리되는지에 대칭성이 존재한다

RNN 단점

  • 은닉층 밖에서 반복 구문을 수행해야하기 때문에 연산이 느리다
  • 실 사용시 많은 timestep 전의 정보를 잘 기억하지 못한다

 

다음 강의에서 RNN에 대해 더 자세히 알아보겠다.

 

Reference)
Slide: cs224n-2021-lecture05-rnnlm.pdf (stanford.edu)
Note: CS224n: Natural Language Processing with Deep Learning Lecture Notes: Part V Language Models, RNN, GRU and LSTM (stanford.edu)
Video: https://youtu.be/PLryWeHPcBs?list=PLoROMvodv4rOSH4v6133s9LFPRHjEmbmJ 

 

'교육 > CS224N winter 2021' 카테고리의 다른 글

Lec 7) Translation, Seq2Seq  (0) 2022.06.14
Lec 6) Simple and LSTM RNNs  (0) 2022.05.18
Lec 4) Dependency Parsing  (0) 2022.04.29
Lec3) Backprop and Neural Networks  (0) 2022.04.22
Lec2) Neural Classifiers  (0) 2022.04.11