重拾基礎 - Word2Vec

重拾基礎 - Word2Vec

Word2Vec

問題設定

對於One-hot的詞向量:

egin{aligned} I &= [1, 0, 0] \ Like &= [0, 1, 0] \ Apple &= [0, 0, 1] end{aligned}

無法通過兩向量夾角餘弦值計算其相似度,word2vec提供了Skip-Gram(跳字模型)與CBOW(連續詞袋模型)兩個詞嵌入模型,通過這種模型訓練出的詞向量可以較好的表示出詞之間的相似度。

Skip-Gram

即跳字模型,其核心思想是對於一個上下文,設定一個大小為m的滑窗,在滑窗內選擇1個中心詞,預測滑窗內m-1個背景詞。即如果上下文是:

I eat apple every day

對每一個詞進行One-hot編碼:

egin{aligned} I &= [1, 0, 0, 0, 0] \ eat &= [0, 1, 0, 0, 0] \ apple &= [0, 0, 1, 0, 0] \ every &= [0, 0, 0, 1, 0] \ day &= [0, 0, 0, 0, 1] end{aligned}

設定滑窗大小為2,如果選擇中心詞apple,那麼將會有以下訓練數據:

egin{aligned} x &= [0, 0, 1, 0, 0] \ y &= [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1] end{aligned}

設計一個只有1個輸入層、1個隱藏層、1個輸出層的神經網路,其中輸出層的神經元個數等於輸入層即等於One-hot編碼的維度,而隱含層的神經元個數通常遠小於輸出層,比如One-hot維度如果是10000,隱含層可以只有300個神經元:

我們通過最大化似然函數:

prod^{N}_{i=1} prod_{-m <= j <= m} mathbb{P} left( w^{i+j}  lvert  w^i 
ight)

即對於上下文內所有的詞,給定中心詞 w^i ,預測滑窗內其他詞,越準確越好。對上式取對數並展開:

egin{aligned} prod^{N}_{i=1} prod_{-m <= j <= m} mathbb{P} left( w^{i+j}  lvert  w^i 
ight) &= sum^{N}_{i=1} sum_{-m <= j <= m} log mathbb{P} left( w^{i+j}  lvert  w^i 
ight) \ &= sum^{N}_{i=1} sum_{-m <= j <= m} log left( frac{exp(mathrm{u^T_{i+j} cdot v_{i}} )}{ mathrm{sum^{N}_{k=1} exp(mathrm{u^T{k} cdot v_{i}})}} 
ight) \ end{aligned}

其中, mathrm{v_i} 即是隱藏層的權重,也是隱藏層的輸入 z_i ,也是第i個詞的詞向量, mathrm{u_{i+j}} 是輸出層的權重,也是第i+j個詞的詞向量的另一個表達。最大化上式的最大似然函數,即最小化下式交叉熵:

- sum^{N}_{i=1} mathrm{y_i} cdot log mathrm{p_i}

其中 mathrm{y_i}mathrm{p_i} 是維度為詞表長度的向量,分別代表觀測值與計算值,對 mathrm{v_i} 求梯度有:

egin{aligned} frac {partial log mathbb{P} left( w^{j}  lvert  w^i 
ight)} {mathrm{v_i}} &= frac {partial log left( exp(mathrm{u^T_{j} cdot v_{i}} ) 
ight) - log left ( mathrm{sum^{V}_{k=1} exp(mathrm{u^T{k} cdot v_{i}})} 
ight)}{partial mathrm{v_{i}}} \ &= mathrm{u_{j}} - frac{1}{sum^{V}_{w=1} exp(mathrm{u^T_w v_i}) } left[ sum^{V}_{k=1} exp(mathrm{u^T_k v_i) cdot mathrm{u_k}} 
ight] \ &= mathrm{u_{j}} - sum^{V}_{k=1} frac{ exp(mathrm{u^T_k v_i}) }{ sum^{V}_{w=1} exp(mathrm{u^T_w v_i}) } cdot mathrm{u_k} end{aligned}

然後使用梯度下降更新 mathrm{v_i} ,此處的 mathrm{v_i} 是向量,在網路中,即是輸入層的第i個神經元到隱含層的權重。

CBOW

即Continuous Bag of Words,連續詞袋模型,其核心思想是對於一個上下文,設定一個大小為m的滑窗,在滑窗內選擇1個背景詞,m - 1個中心詞,與Skip-Gram相反,設定滑窗大小為2,如果選擇中心詞  I, eat, every, day ,那麼將會有以下訓練數據:

egin{aligned} x &= [1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1] \ y &= [0, 0, 1, 0, 0] \ end{aligned}

而對於概率:

mathbb{P} left( w^{j}  lvert  w^{i-m}, cdots, w^i, cdots, w^{i+m} 
ight) = frac{exp(mathrm{u^T_{j} cdot (v_{i} + cdots + v_{i+2m}} ) / 2m)}{ mathrm{sum^{V}_{k=1} exp(mathrm{u^T{k} cdot (v_{i} + cdots + v_{i+2m}} ) / 2m})}

與Skip-Gram的不同之處在於將中心詞求和後平均,之後的梯度計算與更新和Skip-Gram相同,這裡就不展開了。

負採樣

可以直觀地從上面的梯度更新公式中看到,每一次更新都伴隨著巨量的計算開銷,這個計算開銷主要是因為Softmax函數的分母。可以使用負採樣替換Softmax,減少計算開銷。

相對於原條件概率:

mathbb{P} left( w^{j}  lvert  w^i 
ight) = frac{exp(mathrm{u^T_{j} cdot v_{i}} )}{ mathrm{sum^{V}_{k=1} exp(mathrm{u^T{k} cdot v_{i}})}}

將被改寫為:

mathbb{P} left( w^{j}  lvert  w^i 
ight) = log frac{1}{1 + exp(- mathrm{u^T_j v_i})} + sum^{K}_{k=1} log left( 1 - frac{1}{1 + exp(- mathrm{u^T_k v_i})} 
ight)

即篩選出K個不在滑窗內的詞向量,直觀地理解是希望中心詞儘可能地不預測出這些採樣出的詞,篩選出某個詞的概率由這個公式決定:

mathrm{P(w_i)} = frac{f(w_i)^{frac{3}{4}}}{sum^{V}_{k=1}f(w_k)^{frac{3}{4}}}

其中, f(w_i) 是這個單詞在上下文中出現的頻率。

結果

通過這種詞嵌入模型訓練出的詞向量能較好的表示兩個相近意思的詞的近似程度。

後續

  • 層序Softmax還沒預習太懂
  • 代碼也還沒寫完
  • 不知道明天能不能寫一下GloVe

推薦閱讀:

關於卷積神經網路處理情感分類的一些論文
【線上直播】NLP的未來—語義落地 (Semantic Grounding)
《Convolutional Sequence Modeling Revisited》 閱讀筆記
第二章自然語言處理的主要課題
NN4NLP課程筆記(一)

TAG:深度學習DeepLearning | 機器學習 | 自然語言處理 |