Mark Chang's Blog

Machine Learning, Deep Learning and Python

Word2vec (Part 1 : Overview)

Introduction

文字的語意可以用向量來表示,在上一篇 Vector Space of Semantics 中提到,如果把每種字當成一個維度,假設總共有一萬總字,那向量就會有一萬個維度。有兩種方法可降低維度,分別是 singular value decompositionword2vec

本文講解 word2vec 的原理。 word2vec 流程,總結如下:

首先,將文字做 one-hot encoding ,然後再用 word2vec 類神經網路計算,求出壓縮後(維度降低後)的語意向量。

One-Hot Encoding

一開始,不知道哪個字和哪個字語意相近,所以就假設每個字的語意是不相干的。也就是說,每個字的向量都是互相垂直。

這邊舉個比較簡單的例子,假設總字彙量只有 4 個, 分別為 dog, cat, run, fly ,那麼,經過 one-hot encoding 的結果如下:

如上圖, dog 的向量為 (1,0,0,0) ,只有在第一個維度是 1 ,其他維度是 0 ,而 cat 的向量為 (0,1,0,0) 只有在第一個維度是 1 ,其他維度是 0 。

也就是說,每個字都有一個代表它的維度,而它 one hot encoding 的結果,只有在那個維度上是 1 ,其他維度都是 0 。這樣的話,任意兩個 one hot encoding 的向量內積結果,都會是 0 ,內積結果為 0 ,表示兩向量是垂直的。

註:實際應用中,字彙量即是語料庫中的單字種類,通常會有幾千個甚至一萬個以上。

word2vec

word2vec 的神經網路架構如下,總共有三層, input layeroutput layer 一樣大,中間的 hidden layer 比較小。

如上圖,總字彙量有 4 個,那麼 input layeroutput layer 的維度為 4, 每個維度分別代表一個字。 如果想要把向量維度降至三維, hidden layer 的維度為 3。

另外要注意的是, hidden layer 沒有非線性的 activation funciton ,而 output layeractivation functionsigmoid ,這兩點會有什麼影響,之後會提到。

其中,在 input layerhidden layer 之間, 有 weight ,在此命名為 ,而在 hidden layeroutput layer 之間, 有 weight ,在此命名為

由於 inputone hot encoding 的向量,又因為 hidden layer 沒有 sigmoid 之類的非線性 activation function。 輸入到類神經網路後,在 hidden layer 所取得的值,即是 中某個橫排的值,如下:

例如,輸入的是 dogone hot encoding ,只有在第 1 個維度是 1 ,與 作矩陣相乘後,在 hidden layer 取得的值是 中的第一個橫排: ,這個向量就是 dog 壓縮後的語意向量。運算過程如下:

因此, 中的某個橫排,就是某個字的語意向量。從反方向來看,由於 output layer 也是對應到字彙的 one hot encoding 因此, 中的某個橫排,就是某個字的語意向量。

所以,一個字分別在 中各有一個語意向量。但通常會選擇 中的語意向量,作為 word2vec 的輸出結果。

Initializing word2vec

至於如何訓練這個類神經網路? 訓練一個類神經網路的過程,第一步就是要先將 weight 作初始化。初始化即是隨機給每個 weight 不同的數值,這些數值介於 之間。

因此,在還沒開始訓練之前,這些向量的方向都是隨機的,跟語意無關。

dogcat 中的向量,為 ,以及 runfly 中的向量 為 ,為例:

由於 都是隨機初始化的,因此 這些向量的方向都是隨機的,跟語意無關,如下圖所示:

Training word2vec

訓練 word2vec 的目的,是希望讓語意向量真的跟語意有關。,在上一篇 Vector Space of Semantics 中提到,某字的語意,可從其上下文有哪些字來判斷。因此,可以用某字上下文的字,來做訓練,讓語意向量能抓到文字的語意。

dog 的上下文中有 run , 令 dogword2vecinputrunoutput 則輸入類神經網路後,在 run 的位置,在經過 sigmoid 之前,得到的結果是 的內積。經過了,sigmoid ,得到的值為:

由於 run 出現在 dog 的上下文中,所以要訓練類神經網路,在 run 位置可以輸出 1,如下:

過程如下圖所示:

根據上圖,如果要讓 run 的位置輸出為 1 ,則 的內積要越大越好。

內積要大,就是向量角度要越小,訓練過程中,會修正這兩個向量的角度,如下圖:

上圖左方為先正之前,各向量的方向,上圖右方為修正之後的方向,其中,深藍色為修正後的,淺藍色為修正前的,畫在一起以便作比較。修正完後, 的角度又更接近了。

同理,若 cat 的上下文中有 run ,則用 word2vec 做同樣訓練,如下圖:

修正向量的角度後, 的角度會更接近,結果如下圖:

不過,以上訓練方法有個問題,就是訓練完後, 所有的向量都會位於同一條直線上,而無法分辨出每個字語意的差異 。如果要讓 word2vec 學會分辨語意的差異,就需要加入反例,也就是 不是出現在上下文的字

如果 dog 的上下文中,不會出現 flyfly 的向量為 ,將 dog 輸入類神經網路後,在 fly 的位置,訓練其輸出結果為 0 ,如下:

如下圖所示:

如果要讓輸出結果接近 0,則 的內積要越小越好,也就是說,它們之間的角度要越大越好。修正這兩個向量的角度,如下圖:

同理,若 cat 的上下文中沒有 fly ,則訓練其輸出 0 :

修正 的夾角,如下圖:

訓練後,得出的這些語意向量,語意相近的,夾角越小,語意相差越遠的,夾角越大,如下圖:

Further Reading

  1. word2vecbackward propagation 公式要怎麼推導,請看:word2vec (part2 : Backward Propagation)

  2. 如何從無到有,不使用任何自動微分的套件,實作一個 word2vec ,請看:word2vec (part3 : Implementation)

註: 實際上, word2vecinput layeroutput layer 各有兩種架構。input layercbowskip-gram 兩種,output layerhierarchical sofrmaxnegative sampling 兩種,本文所寫的為 skip-gram 搭配 negative sampling 的架構。關於 hierarchical softmax 請參考hierarchical sofrmax

Comments