자연어처리

[자연어처리 CS224N] #2-1. Word2Vec Optimization (SGD)

ima9ine4 2024. 3. 19. 23:54
728x90

CS224N 강의자료를 활용하여 글을 작성하였습니다. 모든 이미지의 출처는 cs224n입니다.

 


지난 포스팅에서 우리는 Word2vec으로 워드 임베딩을 하기 위한 손실 함수를 구했다. 우리가 학습해야 하는 벡터들(u,v)은 다 파라미터이다. 우리가 가진 목적 함수 J(θ)를 최소화 하기 위해서는 경사하강법(gradient descent)이라는 알고리즘을 사용한다. 경사하강법이란 J(θ)의 gradient를 계산해서, 기울기가 작아지는 방향으로 조금씩 나아가는 것이다. 우리는 u와 v를 이용해서 목적 함수를 만들었으므로 이 목적 함수를 최소화하는 파라미터를 찾는다면, 워드 임베딩이 잘 된 것이라고 할 수 있을 것이다. 

Gradient Descent(경사하강법)

아래 식을 보자. θ new 를 구하기 위해서는 θ old에서 (J(θ)를 편미분한 값 * α)를 빼주면 된다. α는 step size 혹은 learning rate라고 한다. 이는 학습되는 정도를 조절하기 위해 사람이 지정하는 매개변수이다.

 

하지만  gradient descent는 한계점을 가진다. corpus 안에는 word가 엄청 많이 존재할텐데, 이 word 단위의 dataset을 모두 사용해야한다는 것이다. 한 번의 step을 내딛을 때마다 전체 dataset(Batch)을 사용하므로, 어마어마하게 시간이 오래 걸릴 것이다. 그래서 사실상 처리해야 하는 데이터 양이 방대한 자연어처리(NLP)에서는 그냥 Gradient Descent를 사용할 수가 없다고 한다. 이를 해결하기 위한 방법이 Stochastic Gradient Descent(SGD)이다. Stochastic Gradient Descent는 모든 dataset을 사용하는 대신 몇 개를 샘플링하여서 일부를 사용한다. 즉 일부 데이터의 모음(Mini Batch)을 사용한다. 그래서 Stochastic Gradient Descent를 Mini Batch Gradient Descent라고도 한다. 이 방법은 전체 dataset을 전부 사용하는 Batch Gradienet Descent보다 훨씬 빠른 속도를 제공한다. 정확도가 더 낮을 수도 있지만 오히려 더 좋을 수도 있다.


자 그러면 다음에 나오는 이 슬라이드가 난관인데... 정보가 굉장히 압축되어 있으므로 뜯어서 살펴보자.

내가 이해한 것을 정리해 본 것이다. 분홍색 형광펜으로 넘버링된 1~4를 순서대로 살펴보자.
(제 이해가 잘못되었을 가능성이 매우 충분하니, 이상한 것이 있다면 알려주세요.)

  1. 먼저 위 슬라이드의 V는 중심 단어를 담고 있다. 여기서는 6개의 행과 5개의 열로 이루어져 있는데, 각 행은 하나의 단어를 나타낸다. 각 단어마다 벡터를 가지고 있고(행벡터) 그 벡터는 5차원이라고 할 수 있다. 

  2. V벡터는 여러 개의 중심단어를 담고 있다고 했다. 여기서 특정 단어만 추출하려면 one-hot vector를 사용해야 한다. 예를 들어 세 번째에 위치한 단어를 뽑아내고 싶다면 그림의 a 벡터를 이용하면 될 것이다. 벡터 a와 행렬 v를 곱해주면 v의 3행만 결과로 나올 것이다. 이렇게 추출된 v의 3행에 해당하는 벡터를 v3이라고 하자.

  3. 중심단어 벡터(v3)을 구했으니 이를 모든 주변 단어들과 내적해야 한다. 주변 단어들의 집합 U와 v3를 내적(dot product)해주면 유사도를 담고 있는 벡터가 나온다.(참고로 벡터의 내적은 순서가 무관하다.) 각 벡터의 오른쪽에 보라색 글씨로 쓰여 있듯이 첫 번째 원소는 첫 번째 단어와 중심 단어를 내적한 값이고, 두 번째 원소는 두 번째 단어와 중심단어를 내적한 값이고, 그 이하도 마찬가지이다. 그림에는 표현되지 않았는데 이 벡터에 soft max 함수를 씌워 실수 값의 벡터를 확률 값의 분포로 변환한다. 그 결과 벡터의 6개 원소의 합은 1이 될 것이다.
  4. 마지막으로 window size에 포함되는 단어들만 1, 나머지 단어들은 모두 0으로 채운 벡터를 만든다. 이 벡터는 정답 벡터가 된다. 아까 3에서 softmax 를 씌운 확률 분포 벡터와 정답 벡터로 Cross entropy 연산을 한다. Cross entropy 연산을 하여 오차를 구하고, 이로부터 임베딩 테이블에 있는 모든 단어에 대한 임베딩 벡터 값을 업데이트 한다. 이렇게 하는 이유는 window size 안에 포함된 인접한 단어들만 유사도를 올려주기 위함이다. ( + Cross entropy란 두 개의 확률 분포 간의 거리(차이)를 의미한다. 따라서 두 확률 분포가 비슷하면 cross entropy 값이 작고, 다르면 값이 크다.)

 

이렇게 학습하여 나온 결과를 시각화한 것이다. 유사도가 높은 단어는 가까이 배치되어 있다. 자세히 살펴보면 어느정도 학습이 잘 되어 있다는 것을 알 수 있다. 예를 들어 좌측 가운데에 보면 tuesday, saturday, christmas 등 날짜와 관련된 단어들이 뭉쳐져 있는 것을 볼 수 있다.

위 슬라이드는 Word2vec에 대해 좀 더 정리되어 있다.

  • 단어 당 벡터를 2개(중심 단어일 때의 벡터, 주변 단어일 때의 벡터) 사용하는 이유는 최적화 계산을 편하게 하기 위해서이다. Gradient 계산을 할 때 미분을 더 수월하게 해주기 때문이다.
  • Word2vec을 구현하는 방법은 2가지가 있다. 2가지로 구분하기는 하지만 사실상 핵심 원리는 같다.
    1. Skip-grams (SG) : 우리가 지금까지 배운 방식이다. 주어진 중심 단어를 보고 -> 주변에 어떤 단어가 올 지를 예측한다.
    2. Continuous Bag of Words (CBOW) : 주어진 주변 단어를 보고 -> 어떤 중심 단어가 올 지를 예측한다. 

Word2vec은 corpus 내의 모든 단어를 사용하여 임베딩 벡터를 구하게 되므로 연산량이 어마어마하게 많다는 문제점이 있다. 이 문제점을 해결해 효율을 높일 수 있는 방법 중 하나는 negative sampling이다. negative sampling에 대해서는 다음 포스팅으로 알아보자

728x90
반응형