본문 바로가기
AI

자연어처리 : Word Embedding : Word2Vec, CBOW, Skip-Gram, Negative Sampling

by 월곡동로봇팔 2020. 3. 14.

1. 배경

'비슷한 위치에서 등장하는 단어들은 비슷한 의미를 가진다'라는 가정입니다.

예를들어 강아지란 단어는 귀엽다, 예쁘다, 애교 등의 단어가 주로 함께 등장하는데 분포 가설에 따라서 저런 내용을 가진 텍스트를 벡터화한다면 저 단어들은 의미적으로 가까운 단어가 됩니다. 분산 표현은 분포 가설을 이용하여 단어들의 셋을 학습하고, 벡터에 단어의 의미를 여러 차원에 분산하여 표현합니다.

 

요약하면 희소 표현이 고차원에 각 차원이 분리된 표현 방법이었다면,

분산 표현은 저차원에 단어의 의미를 여러 차원에다가 분산하여 표현합니다. 이런 표현 방법을 사용하면 단어 간 유사도를 계산할 수 있습니다.

이를 위한 학습 방법으로는 NNLM, RNNLM 등이 있으나 요즘에는 해당 방법들의 속도를 대폭 개선시킨 Word2Vec가 많이 쓰이고 있습니다.


2. CBOW(Continuous Bag of Words)

CBOW는 주변에 있는 단어들을 가지고, 중간에 있는 단어들을 예측하는 방법입니다.
  • 예문 : "The fat cat sat on the mat"
    {"The", "fat", "cat", "on", "the", "mat"}으로부터 sat을 예측하는 것은 CBOW가 하는 일입니다.
  • 예측해야하는 단어 sat을 중심 단어(center word)라고 하고, 예측에 사용되는 단어들을 주변 단어(context word)라고 합니다.

(1) window size 정하기

  • 윈도우 : 중심 단어를 맞추기위해 앞 뒤 단어들을 n 개까지 볼 것인지 정하는 척도, n입니다. 

(2) Sliding Window 정하기

  • 슬라이딩 윈도우 : 윈도우 크기를 정했다면, 윈도우를 계속 움직여서 주변 단어와 중심 단어 선택을 바꿔가며 학습을 위한 데이터 셋을 만들 수 있는 방법입니다.

위 그림에서 좌측의 중심 단어와 주변 단어의 변화는 윈도우 크기가 2일때, 슬라이딩 윈도우가 어떤 식으로 이루어지면서 데이터 셋을 만드는지 보여줍니다. 

 

(3) CBOW NN 구조

  • 입력층(Input layer)의 입력으로서 앞, 뒤로 사용자가 정한 윈도우 크기 범위 안에 있는 주변 단어들의 원-핫 벡터가 들어가게 됩니다.
  • 출력층(Output layer)에서 예측하고자 하는 중간 단어의 원-핫 벡터가 필요합니다. 뒤에서 설명하겠지만, Word2Vec의 학습을 위해서 이 중간 단어의 원-핫 벡터가 필요합니다.

cf) CBOW vs DL ?

Word2Vec은 딥 러닝 모델(Deep Learning Model)은 아니라는 점입니다

Word2Vec DL
은닉층 -> 하나만 존재한다. 은닉층 ->Deep 하게 여러개 존재한다.
은닉층 -> 활성화함수 존재하지 않음. 은닉층 -> 마다 활성화함수들이 존재한다.
은닉층 == lookup table이라는 연산을 담당 층 == 투사층  

(4) CBOW mechanism

(4)-1 Input Layer

하나는 투사층의 크기가 M이라는 점입니다.

CBOW에서 투사층의 크기 M은 임베딩하고 난 벡터의 차원이 됩니다. 다시 말해, 위의 그림에서 투사층의 크기는 M=5이기 때문에 CBOW를 수행하고나서 얻는 각 단어의 임베딩 벡터의 차원은 5가 될 것입니다.

 

두 번째는 입력층과 투사층 사이의 가중치 W는 V × M 행렬이며, 투사층에서 출력층사이의 가중치 W'는 M × V 행렬이라는 점입니다. 여기서 V는 단어 집합의 크기를 의미합니다. (one-hot encoding이니까, V의 크기가 곧 layer의 크기)

즉, 위의 그림처럼 원-핫 벡터의 차원이 7이고, M은 5라면 가중치 W는 7 × 5 행렬이고, W'는 5 × 7 행렬이 될 것입니다. 주의할 점은 이 두 행렬은 동일한 행렬을 전치(transpose)한 것이 아니라, 서로 다른 행렬이라는 점입니다.

인공 신경망의 훈련 전에 이 가중치 행렬 W와 W'는 대게 굉장히 작은 랜덤 값을 가지게 됩니다. CBOW는 주변 단어로 중심 단어를 더 정확히 맞추기 위해 계속해서 이 W와 W'를 학습해가는 구조입니다.

(4)-2 Projection Layer = Lookup Table

입력으로 들어오는 주변 단어의 원-핫 벡터와 가중치 W 행렬의 곱이 어떻게 이루어지는지 보겠습니다.

입력 벡터는 원-핫 벡터입니다.

i번째 인덱스에 1이라는 값을 가지고 그 외의 0의 값을 가지는 입력 벡터 == 가중치 W 행렬의 곱은 사실 W행렬의 i번째 행을 그대로 읽어오는 것과(lookup) 동일합니다.

 

그래서 이 작업을 룩업 테이블(lookup table)이라고 부릅니다.

처리과정에서 연산 횟수를 줄이기 위해, 미리 연산의 결과를 메모리에 저장 후 이를 이용하여 신속히 처리하는 행렬이다. 마치 미리 해답표를 만드는 느낌이다.

룩업테이블은 결과값을 가진 배열이다.
룩업테이블 배열의 인덱스는 입력값이다. 배열의 값은 출력값이다.

앞서 CBOW의 목적은 W와 W'를 잘 훈련시키는 것이라고 언급한 적이 있는데, 사실 그 이유가 여기서 lookup해온 W의 각 행벡터 == 사실 Word2Vec을 수행한 후의 각 단어의 M차원의 크기를 갖는 임베딩 벡터들이기 때문입니다.

(4)-3 v 연산

이렇게 각 주변 단어의 원-핫 벡터에 대해서 가중치 W가 곱해서 생겨진 결과 벡터들은 투사층에서 만나 이 벡터들의 평균인 벡터를 구하게 됩니다.

평균을 구할 때는 window 크기가 2라면, 4개의 결과 벡터에 대해서 평균을 구하게 됩니다.

투사층에서 벡터의 평균을 구하는 부분은 CBOW가 Skip-Gram과 다른 차이점이기도 합니다.

뒤에서 보게되겠지만, Skip-Gram은 입력이 중심 단어 하나이기때문에 투사층에서 벡터의 평균을 구하지 않습니다.

(4)-4 Output Layer : softmax function

이렇게 구해진 평균 벡터는 두번째 가중치 행렬 W'와 곱해집니다. 곱셈의 결과로는 원-핫 벡터들과 차원이 V로 동일한 벡터가 나옵니다. 만약 입력 벡터의 차원이 7이었다면 여기서 나오는 벡터도 마찬가지입니다.

평균벡터 & W' 가 제대로 된 값이라면, softmax를 취하면 제대로 된 index를 가르킬 것이다.

 

이 벡터에 CBOW는 소프트맥스(softmax) 함수를 취하는데, 소프트맥스 함수로 인한 출력값은 0과 1사이의 실수로, 각 원소의 총 합은 1이 되는 상태로 바뀝니다. 이렇게 나온 벡터를 스코어 벡터(score vector)라고 합니다. 

 

스코어 벡터의 j번째 인덱스가 가진 0과 1사이의 값은 j번째 단어가 중심 단어일 확률을 나타냅니다.

그리고 이 스코어 벡터는 우리가 실제로 값을 알고있는 벡터인 중심 단어 원-핫 벡터의 값에 가까워져야 합니다.

 

(4)-5 Output Layer : cross entropy

스코어 벡터를 y^hat라고 하겠습니다. 중심 단어를 y로 했을 때, 이 두 벡터값의 오차를 줄이기위해 CBOW는 손실 함수(loss function)로 cross-entropy 함수를 사용합니다.

cross-entropy 함수에 실제 중심 단어인 원-핫 벡터와 스코어 벡터를 입력값으로 넣고, 이를 식으로 표현하면 위와 같습니다.


그런데 y가 원-핫 벡터라는 점을 고려하면, 이 식은 위와 같이 간소화시킬 수 있습니다. 이 식이 왜 loss function으로 적합한지 알아보겠습니다. c를 중심 단어에서 1을 가진 차원의 값의 인덱스라고 한다면, 

 y^hat y를 정확하게 예측한 경우가 됩니다. 이를 식에 대입해보면 -1 log(1) = 0이 되기 때문에, 결과적으로 y^hat y를 정확하게 예측한 경우의 cross-entropy의 값은 0이 됩니다. 즉, 

이 값을 최소화하는 방향으로 학습해야 합니다.

 

(4)-6 Backpropagation

이제 역전파(Back Propagation)를 수행하면 W와 W'가 학습이 되는데, 학습이 다 되었다면 M차원의 크기를 갖는 W의 행이나 W'의 열로부터 어떤 것을 임베딩 벡터로 사용할지를 결정하면 됩니다. 때로는 W와 W'의 평균치를 가지고 임베딩 벡터를 선택하기도 합니다.


3. Skip-gram

Skip-gram은 중심 단어에서 주변 단어를 예측하려고 합니다.

앞서 언급한 동일한 예문에 대해서 인공 신경망을 도식화해보면 위와 같습니다. 이제 중심 단어에 대해서 주변 단어를 예측하기 때문에, 투사층에서 벡터들의 평균을 구하는 과정은 없습니다.

여러 논문에서 성능 비교를 진행했을 때, 전반적으로 Skip-gram이 CBOW보다 성능이 좋다고 알려져 있습니다.


4. NNLM vs Word2Vec

NNLM vs Word2Vec

2020/03/11 - [machine_learning/natural language] - 자연어처리 : RNN의 언어 모델 (RNNLM)

 

자연어처리 : RNN의 언어 모델 (RNNLM)

NN 언어 모델(Recurrent Neural Network Language Model, RNNLM) 2020/03/05 - [machine_learning/natural language] - 자연어처리 : 언어모델 : N-gram 자연어처리 : 언어모델 : N-gram 정의 SLM의 일종이지만,..

mambo-coding-note.tistory.com

NNLM Word2Vec
다음 나올 단어를 예측 다음 단어가 아닌 중심 단어를 예측하게 하여 학습
이전 단어만 참고 앞, 뒤 단어들을 모두 참고
은닉층이 존재 은닉층이 X
연산량 : n*m + n*m*h + h*v 연산량 : n*m + m*logv
  계층적 소프트맥스, 네거티브 샘플링 -> 학습속도 증가

6. 네거티브 샘플링(Negative Sampling)

대체적으로 Word2Vec를 사용한다고 하면 SGNS(Skip-Gram with Negative Sampling)을 사용합니다.

 

위에서 배운 Word2Vec 모델에는 한 가지 문제점이 있습니다. 바로 속도입니다.

softmax function을 거치고 이에 대한 오차를 cross entropy로 구하고 모든 단어에 대한 임베딩을 조정합니다.

그 단어가 중심 단어나 주변 단어와 전혀 상관없는 단어라도 마찬가지 입니다. 그런데 만약 단어 집합의 크기가 수백만에 달한다면 이 작업은 굉장히 무거운 작업입니다.

 

여기서 중요한 건 Word2Vec이 모든 단어 집합에 대해서 소프트맥스 함수를 수행하고, 역전파를 수행하므로 주변 단어와 상관 없는 모든 단어까지의 워드 임베딩 조정 작업을 수행한다는 겁니다.

만약 마지막 단계에서 '강아지'와 '고양이'와 같은 단어에 집중하고 있다면, Word2Vec은 사실 '돈가스'나 '컴퓨터'와 같은 연관 관계가 없는 수많은 단어의 임베딩을 조정할 필요가 없습니다.

 

  1. '강아지', '고양이', '애교'와 같은 주변 단어들을 가져옵니다. 이를 positive로 둔다.
  2. '돈가스', '컴퓨터', '회의실'과 같은 랜덤으로 선택된 주변 단어가 아닌 상관없는 단어들을 일부만 갖고옵니다. 이를 negative로 둔다.

이렇게 전체 단어 집합보다 훨씬 작은 단어 집합을 만들어놓고 마지막 단계를 이진 분류 문제로 바꿔버리는 겁니다.

이는 기존의 다중 클래스 분류 문제를 이진 분류 문제로 바꾸면서도 연산량에 있어서 훨씬 효율적입니다.

댓글