윤제로의 제로베이스

워드투벡터(Word2Vec) 본문

Background/Pytorch 기초

워드투벡터(Word2Vec)

윤_제로 2022. 1. 26. 12:36

https://wikidocs.net/60854

 

03. 워드투벡터(Word2Vec)

앞서 원-핫 인코딩 챕터에서 원-핫 벡터는 단어 간 유사도를 계산할 수 없다는 단점이 있음을 언급한 적이 있습니다. 그래서 단어 간 유사도를 반영할 수 있도록 단어의 의미를 ...

wikidocs.net

1. 희소 표현(Sparse Representation)

벡터 또는 행렬(matrix)의 값이 대부분이 0으로 표현되는 방법희소 표현(Sparse representation)이라고 한다.

 

하지만 이러한 표현 방법은 각 단어간 유사성을 표현할 수 없다는 단점이 있고, 이를 위한 대안으로 '의미'를 다차원 공간에 벡터화 하는 방법을 찾았고 이러한 방법을 분산 표현(distributed representation)이라고 한다.

이렇게 분산 표현을 이용하여 단어의 유사도를 벡터화 하는 작업은 워드 임베딩(embedding) 작업에 속하기 때문에 이렇게 표현된 벡터 또한 임베딩 벡터라고 하며, 저차원을 가지므로 바로 앞의 챕터에서 배운 밀집 벡터(dense vector)에 속한다.

2. 분산 표현(Distributed Representation)

분산 표현 방법은 기본적으로 분포 가설(distributed hypothesis)이라는 가정 하에 만들어진 표현 방법이다.

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

강아지란 단어는 귀엽다, 예쁘다, 애교 등의 단어와 주로 함께 등장하는데 분포 가설에 따라서 저런 내용을 가진 텍스트를 벡터화 한다면 저 단어들은 의미적으로 가까운 단어가 된다.

 

이렇게 표현된 벡터들은 원-핫 벡터처럼 벡터의 차원이 단어의 집합 크기일 필요가 없으므로, 벡터의 차원이 상대적으로 저차원으로 줄어들게 된다.

 

희소 표현고차원에 각 차원이 분리된 표현 방법이라면, 분산 표현저차원에 단어의 의미를 여러 차원에 분산하여 표현한다.

이러한 표현 방법을 사용하면 단어간 유사도를 계산할 수 있다. 

3. CBOW(Continuous Bag of Words)

Word2Vec에는 CBOW와 Skip-Gram 두가지 방식이 있다.

CBOW주변에 있는 단어들을 가지고 중간에 있는 단어를 예측하는 방법이다.

반대로, Skip-Gram중간에 있는 단어로 주변 단어들을 예측하는 방법이다.

 

 

중심 단어를 예측하기 위해서 앞뒤 몇개의 단어를 볼지 결정하는 범위 윈도우(window)라고 한다.

윈도우 크기를 정했다면 위도를 움직여 주변 단어와 중심 단어 선택을 바꿔가며 데이터셋을 만들 수 있는데, 이 방법을 슬라이딩 윈도우(sliding window)라고 한다.

 

위는 CBOW의 인공 신경망을 도식화한 모습이다.

입력층의 입력으로 앞, 뒤로 사용자가 정한 윈도우 크기 범위 안에 있는 주변 단어들의 원-핫 벡터가 들어가게 되고, 출력 층에서 예측하고자 하는 중간 단어의 원-핫 벡터가 필요하다.

 

또한 Word2Vec은 딥러닝 모델이 아니라는 것을 알 수 있다.

딥러닝 모델은 입력층과 출력층 사이 은닉층의 개수가 충분히 쌓인 신경망을 말하는데, Word2Vec의 경우 은닉층이 1개밖에 없다. 

이렇게 은닉층이 1개만 있는 경우 일반적으로 얕은 신경망(Shallow Neural Network)라고 부른다.

또한 Word2Vec의 은닉층은 일반적인 은닉층과는 달리 활성화 함수가 존재하지 않으며 룩업테이블이라는 연산을 담당하는 층으로 일반적인 은닉층과 구분하기 위해 투사층(projection layer)이라고 부르기도 한다.

 

 

CBOW의 신경망을 확대하여 동작 메커니즘에 대해 알아보자.

이 그림에서 주목해야할 점은 첫번째 투사층의 크기가 M이라는 점이다. 

CBOW에서 투사층의 크기 M은 임베딩하고 난 벡터의 차원이 된다.

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

두번째는 입력층과 투사층 사이의 가중치 W는 V * M 행렬이며, 투사층에서 출력층 사이의 가중치 W'는 M * V의 행렬이라는 점이다.

여기서 V는 단어 집합의 크기를 의미한다.

즉, 위의 그림처럼 원-핫 벡터의 차원이 7이고, M이 5라면 가중치 W의 행렬은 7 * 5이고 W'의 행렬은 5 * 7이 된다.

주의할 점은 두 행렬은 동일한 행렬을 전치 한 것이 아니라 서로 다른 행렬이다.

인공 신경망의 훈련 전에 이 가중치 행렬은 굉장히 작은 랜덤값을 가지게 된다.

CBOW는 주변 단어로 중심 단어를 정확히 맞추기 위해 W와 W'를 학습해가는 구조이다.

 

 

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

각 주변 단어의 원-핫 벡터를 x로 표기하였다.

입력 벡터는 원-핫 벡터이고 i 번째 인덱스에 1이라는 값을 가지고 그 외의 0의 값을 가진다.

또한 가중치 W 행렬의 곱은 사실 W 행렬의 i 번째 행을 그대로 읽어오는 것과 동일하다.

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

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

 

 

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

만약 윈도우 크기가 2라면 입력 벡터의 개수는 총 2n개 이므로 중간 단어를 예측하기 위해 총 4개의 입력 벡터가 사용된다.

그렇기 때문에 평균을 구할 때는 4개의 결과 벡터에 대한 평균을 구하게 된다.

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

Skip-Gram의 경우 중심 단어가 하나이기 때문에 투사층에서 벡터의 평균을 구하지 않는다.

 

 

이렇게 구해진 평균 벡터는 두번째 가중치 행렬 W'와 곱해진다.

곱셈의 결과로는 원-핫 벡터들과 차원 V로 동일한 벡터가 나온다. 

만약 입력 벡터 차원이 7이었다면 여기서 나오는 벡터도 마찬가지이다.

 

이 벡터에 CBOW는 소프트맥스(softmax) 함수를 취하는데, 소프트맥스 함수로 인한 출력값은 0과 1 사이의 실수로, 각 원소의 총 합은 1이 되는 상태로 바뀐다.

이렇게 나온 벡터를 스코어 벡터(score vector)라고 한다.

스코어 벡터의 각 차원 안에서의 값이 의미하는 것은 아래와 같다.

 

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

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

스코어 벡터를 y^이라 하고 중심 단어를 y라 했을 때 이 두 벡터의 오차를 줄이기 위해 CBOW는 손실 함수로 cross-entropy 함수를 사용한다.

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

y가 원-핫 벡터라는 것을 고려하면, 식을 위와 같이 간소화 할 수 있다.

c를 중심 단어에서 1을 가진 인덱스라고 한다면 y^c=1는 y^이 y를 정확하게 예측한 경우가 된다. 

이를 식에 대입해보면 -1log(1)=0이 되기 때문에 y^이 y를 정확하게 예측한 경우의 오류가 0이 된다.

즉, 위 식의 값을 최소화 하는 방향으로 학습해야한다는 이야기이다.

 

역전파를 수행하려면 W와 W'이 학습되어야 하는데, 학습이 되었다면 M차원의 크기를 갖는 W의 행이나 W'의 열로부터 어떤 것을 임베딩 벡터로 사용할지 결정하면 된다.

때로 W와 W'의 평균치를 가지고 임베딩 벡터를 선택하기도 한다.

4. Skip-Gram

Skip-Gram은 CBOW를 이해했다면 쉽게 이해할 수 있다.

Skip-Gram은 중심단어에서 주변단어를 예측하려 한다.

 

Skip-Gram

 

중심 단어에서 주변 단어를 예측하기 때문에 투사층에서 벡터들의 평균을 구하는 과정은 필요가 없다.

Skip-Gram과 CBOW의 성능을 비교 했을 때 Skip-Gram이 더 높은 성능을 가졌다고 알려져 있다.

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

Skip-Gram을 사용하는데 네거티브 샘플링(Negative Sampling)이란 방법까지 추가로 사용하게 된다.

 

위에서 배운 Word2Vec 모델에는 한가지 문제점이 있다.

바로 속도이다.

Word2Vec의 마지막 단계를 보았을 때 출력층에 있는 소프트맥스 함수는 단어 집합 크기의 벡터 내의 모든 값을 0과 1 사이의 값이면서 모두 더하면 1이 되도록 바꾸는 작업을 수행한다.

그리고 이에 대한 오차를 구하고 모든 단어에 대한 임베딩을 조정한다.

만약 단어 집합이 수백만에 달하는 큰 집합이라면 이 작업은 무거운 작업이 된다.

 

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

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

 

이 때 사용하는 것이 네거티브 샘플링이다.

전체 단어 집합이 아니라 일부 단어 집합에 대해서만 고려하는 것이다.

'강아지', '고양이', '애교'와 같은 주변 단어와 관련이 없는 랜덤 단어 '돈가스',  '컴퓨터' 와 같은 일부를 가져온다.

이렇게 작은 딥합을 만들어 놓고 마지막 단계를 이진 분류 문제로 바꾸는 것이다.

Word2Vec은 주변 단어를 긍정으로 두고 랜덤으로 샘플링 된 단어들을 부정으로 둔 다음 이진 분류 문제를 수행한다.

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

 

'Background > Pytorch 기초' 카테고리의 다른 글

파이토치의 nn.Embedding()  (0) 2022.01.26
글로브(GloVe)  (0) 2022.01.26
워드 임베딩(Word Embedding)  (0) 2022.01.19
NLP에서의 원-핫 인코딩(One-hot encoding)  (0) 2022.01.19
토치텍스트(Torchtext)의 batch_first  (0) 2022.01.19