이전의 히스토리 h (“history”)가 주어졌을때 다음에 이어지는 목표 단어 w_t (“target”)의 확률을 최대화하기 위해서 소프트맥스 함수를 사용한다.
현재 콘텍스트 h에서 단어 w_t의 적합성을 나타낸다. (보통 내적을 이용한다.) 우리는 학습셋에서 log-likelihood를 최대화하는 방향으로 학습을 진행, 즉, 아래의 식을 최대화
이런 모델은 언어 모델링(language)을 위한 적당히 정규화된 확률 모델(normalized probabilistic model)을 산출
하지만 이 모델은 계산 비용이 매우 크다. 왜냐하면 모든 트레이닝 스텝에서, 현재 콘텍스트 h에서 어휘(Vocab)에 포함된 모든 단어 w’에 대한 확률을 계산하고 정규화해야하기 때문이다.
이에 반해, word2vec을 이용한 특징 학습(feature learning) 방법에서는 전체 확률 모델이 필요하지 않다.
CBOW와 skip-gram 모델은 이진 분류 (binary classification) 방법(로지스틱 회귀분석-logistic regression)을 이용
같은 콘텍스트에서 k개의 상상의 (noise) 단어 ~w와 진짜 타겟 단어 w_t를 식별
는 데이터셋 D에서 콘텍스트 h에서 관찰한 단어가 w일 이진 로지스틱 회귀분석에서의 확률이다. 이는 학습된 embedding vectors theta 를 이용해서 계산(즉, 몬테 카를로 평균을 계산한다.)
이 목적함수는 모델이 실제 단어에는 높은 확률을 부여하고 노이즈 단어들에는 낮은 확률을 부여하면 최대화
기술적으로, 이런 방법을 Negative Sampling
계산 비용의 측면에서, 이런 방식은 매우 효율적이다.
왜냐하면 전체 어휘 V를 계산하는 것이 아니라 우리가 선택한 k개의 noise 단어들만 계산하면 되기 때문
noise-contrastive estimation (NCE) 손실 함수를 사용할 것 > tf.nn.nce_loss() 함수를 이용 (이거 사용한다는 말을 하려고.ㅠ)
CBOW와 Skip-gram 모델을 그대로 구현해서 돌릴 경우 생각보다 학습이 오래 걸리는 것을 확인할 수 있을 것
즉, 사전의 크기가 엄청나게 크면 문제가 생김.
디테일하게 가면, Output Layer에서 Softmax 계산를 위해 전체 단어를 위해 normalized 계산을 하게되어 계산량이 엄청나게 많아짐.
이런한 방법을 해결하기 위한 방법이 바로 Hierarchical Softmax vs Negative Sampling\
dict 크기 즉, 단어가 아주 많을때는 어떻게 처리하는 방법이 따로 있는가?
Hierarchical Softmax
빠르게 계산가능한 multinomial distribution function
각 단어들을 leaves로 가지는 binary tree를 하나 만들어놓은 다음, 해당하는 단어의 확률을 계산할 때 root에서부터 해당 leaf로 가는 path에 따라서 확률을 곱해나가는 식으로 해당 단어가 나올 최종적인 확률을 계산
L(w)는 w라는단어가 leaf에 도달하기 까지의 path의 길이를 의미
n(w, i) : w라는 leaf에 도달하는 path에서, i번째 노드를 의미 예를 들어, n(w, 1)은 루트이고, n(w, L(w))는 w가 된다.
ch(node): node의 고정된 임의의 한 자식을 의미, 여기서는 단순하게 node의 왼쪽 자식이라고 생각해도 무방.
[[x]] 는 x가 true일 경우 1, false일 경우 -1을 반환하는 함수
Hierarchial Softmax를 사용할 경우 기존 CBOW나 Skip-gram에 있던 W’ matrix를 사용하지 않게 된다. 대신, V-1개의 internal node가 각각 길이 N짜리 weight vector를 가지게 된다. 이를 v’_i 라고 하고 학습에서 update 해준다.
h는 hidden layer의 값 벡터
sigma(x)는 sigmoid function 1/(1+exp(-x))
위의 식 p(w)를 계산한다면,
각 스텝마다 길이 N짜리 벡터 두 개의 내적이 일어나므로 계산량 N이 필요
binary tree는 평균적으로 루트로부터 leaf까지의 거리는 평균 O(lnV) 그래서, N번시도한다면, 총 N x lnV의 계산량만으로 특정 단어가 나올 확률을 계산
네트워크의 Error Function을 Categorical Cross-entropy 로 사용할 경우(뜬금없이 이런단어가 나와서 이해안가지만) , 최종 Error를 계산하기 위해서 해당하는 단어에 대해서만 확률을 계산하면 되므로, 다른 추가적인 연산 없이 O(N x lnV)의 계산량만으로 계산이 끝난다.
특정 hidden layer 값에 대해 모든 단어들의 확률을 더한 sigma p(w_i | hidden layer) 를 생각
v_node와 h의 내적 값을 x 라고 하고
특정 node에서 왼쪽 자식으로 갈 때의 확률 = sigmoid(x)
특정 node에서 오른쪽 자식으로 갈 때의 확률 = sigmoid(-x) = 1-sigmoid(x)
특정 노드에서 왼쪽, 오른쪽 자식으로 갈 확률을 더하면 1(sigmoid(x)+1-sigmoid(x)) 이를 이용하면, sigma p(w_i | hidden layer) 값이 1 (?? 모든 단어의..가 빠진듯것이 아니라 위의 식에서 볼때, 그 step에서의..)
softmax function의 계산이 오래 걸렸던 것은 확률 계산을 위해 모든 결과에 대한 합을 1로 만들어주기 위함
이 과정에서 최종적으로 나온 output값에 대해 일일히 계산을 해주어서 전체 합으로 normalize를 해주었기 때문에 V 만큼의 계산이 더 필요했던 것
Hierarchical Softmax를 사용하면 전체 확률에 대한 계산 없이 전체 합을 1로 만들어 줄 수 있어 좋은 multinomial distribution function으로 사용할 수 있게 되는 것
word2vec 논문에서는 이러한 Binary Tree로 Binary Huffman Tree를 사용했다고 한다. Huffman Tree를 사용할 경우 자주 등장하는 단어들은 보다 짧은 path로 도달할 수 있기 때문에 전체적인 계산량이 더 낮아지는 효과를 볼 수 있을 것이다. 또한 Huffman Tree는 Full Binary Tree이기 때문에 Hierarchical Softmax의 조건에도 부합
빈도가 아주 많은 단어 와 빈도가 극히 낮은(=1정도)단어들은 어떻게 전처리를 할까?
Hierarchical Softmax와 Negative Sampling은 모델 자체의 계산복잡도를 줄이기 위한 테크닉이었다. 여기서 추가적인 방법으로, 논문에서는 ‘the’, ‘a’, ‘in’ 등 자주 등장하는 단어들을 확률적으로 제외하여 학습 속도를 향상시켰을 뿐만 아니라 성능까지 향상시켰다. 단어 w의 등장 빈도를 f(w)라고 할 때, 학습할 때 각 단어는
의 확률로 제외된다. 이 때 t는 빈도가 일정값 이상일 때만 제외하겠다는 느낌의 threshold 값인데, 논문에서는 t = 10^-5 의 값을 사용했을 때 가장 좋은 결과를 얻을 수 있었다고 한다.
https://arxiv.org/abs/1301.3781 시차를 두고 여기저기 붙이다보니 두서없이 써놓은 경향이 있음.