Glove
한마디 요약
풀고자 하는 문제 정의: 단어에 의미가 집약된 벡터표현을 찾는 문제
Glove의 접근법은 단어의 벡터표현의 의미를 어떤 방식으로 접근하는가?
중심단어를 기준으로 문맥(특정 윈도우)안에 등장하는 주변 단어와의 내적이 그 두 단어 사이의 동시 등장 확률(코퍼스내 통계 정보)이 되도록 만든다.
Word2Vec은 주변단어가 어떤 단어가 오는지 유사도 기반으로 예측하는 classification 문제(레이블 인덱스 예측) 로 접근하였다면, Glove 는 주변단어에 대한 동시등장 확률을 예측하는 regression 문제(실수 값 예측)로 접근하였다.
Notation
전체 단어 수: $V$
이름 | 수식 | 차원 | 의미 |
---|---|---|---|
Co-occurence matrix | $\mathbf{X}$ | $V \times V$ | corpus 내 전체 동시등장 수 정보, symmetric Matrix |
- | $X_{ij}$ | 1 | $word_i$ 의 문맥안에 $word_j$ 등장 수, $X_{ij} \in \mathbf{X}$ |
- | $X_i = \sum_{k}X_{ik}$ | 1 | $word_i$의 문맥안에 모든 단어들의 등장 수 합 |
Co-occurrence probability for target $word_i$ with probe $word_j$ | $P_{ij} = P(w_j \vert w_i) = \frac{X_{ij}}{X_i}$ | 1 | $word_i$의 문맥안에 $word_j$가 등장할 확률 |
“$word_i$ 의 문맥 안” 이라는 뜻은 $word_i$를 중심단어로하여 특정 윈도우 안에 있는 모든 단어들의 범위 의미.
Key Idea
-
Word2Vec 의 단점을 개선하고자함.
-
문제점 해결책 문맥을 파악하는데 일정 윈도우 내의 주변 단어들만 사용 전체 통계(co-occurence 정보)를 반영 문맥안의 두 단어 벡터 의미를 단순히 유사도로 학습 두 단어 벡터 의미가 동시 등장 확률로 학습
-
-
GloVe1의 아이디어를 한 줄로 요약하면 임베딩 된 중심 단어와 주변 단어 벡터의 내적이 전체 Corpus에서의 동시 등장 확률이 되도록 만드는 것이다. 즉, 이를 만족하도록 단어 임베딩 벡터를 만드는 것이 목표.
-
목표: 코퍼스내 전체 통계정보 $\mathbf{X}$ 와 두 단어 $word_i$와 $word_j$ 가 주어졌을때,
두단어의 임베딩 벡터 $w_i$, $w_j$사이의 관계가 다음과 같이 되도록 학습($w_k \in \mathbb{R}^d$, $d$는 임베딩 차원, $k\in [1, V]$)
\[w_i^T w_j = log P_{ij}\]
-
Stanford cs224n 강의2 와 ratsgo’s blog3 에 잘 정리되어있으며 구현된 pytorch 코드는 이곳4에 있다.
standford cs224n의 Lecture Note 와 Glove 원 논문을 통해 학습하는 것을 가장 추천한다.
3.1. Relationship to Other Model
Glove1 논문의 section 3. Glove Model 에서 목표 $w_i^T w_j = log P_{ij}$ 와 단어 임베딩 $w_i, w_j$ 배우기 위한 손실함수 $J$를 정의하는 부분이 있다.
이 포스팅에서는 section 3.1 Relationship to Other Model 에 집중해 보도록 하겠다.
Prerequisite: Word2Vec 이해, 참고 포스팅
우선적으로 기존방식인 Word2Vec (Skip-Gram 모델) 의 손실 함수에서 시작하겠다.
Word2Vec에서는 중심단어의 문맥(특정 윈도우 안)에 있는 주변단어와의 유사도를 높히기 위한 손실함수로서 Softmax함수 기반의 Cross Entropy를 다음과 같이 이용하였다.
\[\begin{align} J &= \sum_{i \in corpus,~ j\in context(i)} H(\mathbf{t}_j, softmax(\mathbf{y}_i)) \\ &= -\sum_{i \in corpus,~ j\in context(i)} \mathbf{t}_j \odot log(softmax(\mathbf{y}_i)) \\ &= -\sum_{i \in corpus,~ j\in context(i)} log Q_{ij} \\ \end{align}\]Cross Entropy 함수: $H(\mathbf{p},\mathbf{q}) = -\sum_k p_k log(q_k)$
주변단어 $word_j$에 대한 one-hot encoding 벡터 (target vector): $\mathbf{t}_j$
중심단어 $word_i$에 대한 one-hot encoding 벡터 (context vector): $\mathbf{s}_i$
중심단어 $word_i$에 대한 Skip-gram의 output 인 logit: $\mathbf{y}_i = \mathbf{W’}^T\mathbf{W}\mathbf{s}_i$
corpus는 전체 단어, context는 중심단어 의미
$Q_{ij} = \frac{exp(w_i^T w_j)}{\sum_{k=1}^Vexp(w_i^T w_k)}$
위의 $J$가 Word2Vec에서 최소화하고자 하는 손실함수였다.
전체 통계정보를 반영하기위해 각 $X_{ij}$를 이용하면 다음과 같이 전개된다.
\[\begin{align} J &= -\sum_{i=1}^{V}\sum_{j=1}^V X_{ij}logQ_{ij} \\ &= -\sum_{i=1}^{V}\sum_{j=1}^V X_{i}P_{ij} logQ_{ij} ~ \because P_{ij} = \frac{X_{ij}}{X_i}\\ &= -\sum_{i=1}^{V} X_i H(P_i, Q_i) ~ \text{, where } P_i \in \mathbb{R}^V, Q_i \in \mathbb{R}^V \end{align}\]$i$ 는 중심단어에 대한 인덱스, $j$는 주변단어에 대한 인덱스 임에 유의
위의 전개된 수식을 보면, 벡터 $P_i$와 $Q_i$사이의 유사도를 높히는 것.
즉, 중심단어 $word_i$ 에 대한 co-occurence probability 벡터 $P_i$를 예측하기 위한 $Q_i$가 학습되도록 하는 단어 임베딩을 찾는 것이 목표가 된다는 점을 알 수 있다.
그런데, $P_i, Q_i$ 벡터는 다음과 같이 구성되어 있어서 분모의 계산이 비싼 연산이다. \(\begin{align} P_i &= \frac{1}{\sum_{k=1}^V X_{ik}} \begin{bmatrix} X_{i1} \\ X_{i2} \\ ... \\ X_{iV} \\ \end{bmatrix} \\ Q_i &= \begin{bmatrix} \frac{exp(w_i^T w_1)}{\sum_{k=1}^Vexp(w_i^T w_k)} \\ \frac{exp(w_i^T w_2)}{\sum_{k=1}^Vexp(w_i^T w_k)} \\ ... \\ \frac{exp(w_i^T w_V)}{\sum_{k=1}^Vexp(w_i^T w_k)} \\ \end{bmatrix} = \frac{1}{\sum_{k=1}^Vexp(w_i^T w_k)} \begin{bmatrix} exp(w_i^T w_1) \\ exp(w_i^T w_2) \\ ... \\ exp(w_i^T w_V) \\ \end{bmatrix} \end{align}\)
이를 완화하기 위해 다음 2가지 사항을 적용한다.
- $P_i, Q_i$에서 분모를 버린 $\hat{P_{ij}} = X_{ij}, \hat{Q}_{ij} = exp(w_i^T w_j)$ (unnormalized)
- cross entropy 함수 $H(P_i, Q_i)$대신 least square 함수 $\sum_{j}(\hat{P_{ij}} - \hat{Q_{ij}})^2$를 사용
- $X_{ij}$값이 너무 클 수 있어 $log$를 취한 값 $\sum_{j}(log\hat{P_{ij}} - log\hat{Q_{ij}})^2$ 를 사용
정리하면 Glove 는 다음과 같은 손실함수 $J$를 최소화한다. \(\begin{align} J &= \sum_{i=1}^V X_i \sum_{j=1}^V(log\hat{P}_{ij} - log\hat{Q}_{ij})^2 \\ &= \sum_{i=1}^V \sum_{j=1}^V X_i (log\hat{P}_{ij} - log\hat{Q}_{ij})^2 \\ &= \sum_{i=1}^V \sum_{j=1}^V X_i (logX_{ij} - exp(w_i^T w_j))^2 \\ &= \sum_{i=1}^V \sum_{j=1}^V X_i (log(exp(w_i^T w_j)) - logX_{ij})^2 \\ &= \sum_{i=1}^V \sum_{j=1}^V X_i (w_i^T w_j - logX_{ij})^2 \\ &= \sum_{i, j=1}^V X_i (w_i^T w_j - logX_{ij})^2 \end{align}\) 이때, 이전에 언급 했듯이 특정 $X_{ij}$ 값이 너무 크면 학습하는데 방해가 될 수 있어,
이를 제한하고자 다음의 $f(X_{ij})$ 를 사용한다.
\(\begin{align} f(x) &= \begin{cases} (\frac{x}{x_{max}})^\alpha &\text{if } x < x_{max}\\ 1 & \text{otherwise} \end{cases} \end{align}\)
최종적으로, 손실함수 $J$를 다음과 같이 재 정의한다. \(J = \sum_{i, j = 1}^V f(X_{ij})(w_i^T w_j - logX_{ij})\)
이로써, least square regression 문제로 접근하여 두 단어 벡터의 내적이 통계정보의미를 지니는 동시 등장 확률이 되도록 단어 벡터를 학습하도록 한다.
논문의 단어 임베딩 방식은 중심단어에 대한 임베딩과 주변단어에 대한 임베딩을 따로 학습 시키고,
임베딩 값을 가져올때는 평균 값을 사용하였다.
시간적 여유가 되면, pytorch 구현을 해보면 재미있을 것 같다.
Leave a comment