在NLP領域中,爲了能表示人類的語言符號,通常會把這些符號轉成一種數學向量形式以方便處理,咱們把語言單詞嵌入到向量空間中就叫詞嵌入(word embedding)。谷歌開源的word2vec則是這麼一種詞嵌入工具,它能生成詞向量,經過詞向量能夠很好地度量詞與詞之間的類似性。word2vec採用的模型包含了連續詞袋模型(CBOW)和Skip-Gram模型。經過它能夠在大數據量上進行高效訓練從而獲得詞向量。html
在討論詞向量時先看NLP中很重要的統計語言模型,簡單來講就是計算某個句子出現的機率,好比「我今天上班遲到了」這句話在整個語言下的機率,通常咱們會經過一個大的語料庫來進行統計。算法
用數學語言來描述,假設咱們的句子爲bash
其中P(w1)表示第一個詞w1出現的機率;P(w2|w1)是第一個詞出現的前提下第二個詞出現的機率;以此類推。好比s=「我今天上班遲到了」,那麼P(s)=P(我)P(今天|我)P(上班|我,今天)P(遲到了|我,今天,上班)。網絡
上面的語言模型的參數空間太大並且數據稀疏,致使在實際中基本沒法使用。因此咱們須要一個假設,某個詞出現的機率只與它前面的一個或幾個詞有關,這個假設就是馬爾科夫假設。有了它問題就變簡單了,某個句子出現的機率就能夠用下面表示(這裏假設某詞只與前面一個詞相關)。分佈式
n-gram這種處理序列信息的方式依然存在侷限性,好比當n大於3時基本就沒法處理了,參數空間太大。另外它不能表示詞與詞之間的關聯性。因而咱們看下另一種語言模型——神經網絡語言模型,雖然它並不能徹底解決n的問題,但它提供了另一種語言模型思路。實際上,在深度學習中有另外的處理方式,好比RNN、LSTM等,能夠克服n-gram中n沒法取太大(即沒法關聯距離較遠的詞)的缺點。函數
在繼續瞭解神經網絡語言模型以前咱們先看怎麼用向量來表示詞,前面咱們說過詞向量就是用來表示人類語言的一種數學化的方式,其包含了不少種表示方式。其中最簡單的向量方式便是one-hot形式。工具
它的處理方式簡單粗暴,通常就是統計詞庫包含的全部V個詞,而後將這V個詞固定好順序,而後每一個詞就能夠用一個V維的稀疏向量來表示,向量中只有在該詞出現的位置的元素才爲1,其它元素全爲0。好比下面這幾個詞,第一個元素爲1的表示中國,第六個元素爲1的表示美國,第五個元素爲1的表示日本。學習
中國 [1,0,0,0,0,0,0,0,0,……,0,0,0,0,0,0,0]
美國 [0,0,0,0,0,1,0,0,0,……,0,0,0,0,0,0,0]
日本 [0,0,0,0,1,0,0,0,0,……,0,0,0,0,0,0,0]複製代碼
從中能夠看到one-hot形式的維數一般會很大,由於詞數量通常在10W級別,這會致使訓練時難度大大增長,形成維數災難。另外這麼多維只以順序信息而且只用1和0來表示單詞,很浪費空間。再一個是這種方式的任意兩個詞都是孤立的,無法看出兩個詞之間的類似性。因而看看有沒有改進的方法。大數據
鑑於one-hot形式詞向量的缺點,出現了另一種詞向量表示方式——分佈式詞向量(distributed word representation)。 分佈式詞向量則乾脆直接用普通的向量來表示詞向量,而元素的值爲任意實數,該向量的維數能夠在事前肯定,通常能夠爲50維或100維。這時的詞向量相似以下(這裏假設用5維來表示):優化
中國 [1.25, 0.2, 0.3, 0.5, 0.6]
美國 [0.1, 0.3, 0.5, 0.1, 1.5]
日本 [2.2, 0.2, 0.4, 0.6, 1.0]複製代碼
其中每一個元素的具體數值則由訓練來肯定。這樣一來就克服了在深度學習中可能的維度災難,並且充分利用了空間,若是使用適當的訓練方法訓練出來的詞向量能夠直接根據兩個詞之間的距離來計算類似性。
神經網絡語言模型即用神經網絡來訓練語言模型,最經典的模型是Bengio等人提出的三層神經網絡,它思路大概是對於語料C任意一個詞w,取它的前n-1個詞做爲輸入,這個跟n-gram的思路是一樣的,而w則爲它的輸出,有了輸入和輸出就組成了訓練樣本了。
下面根據上圖進行講解,首先設每一個詞w用m維向量來表示,則每一個詞都有對應着本身的m維向量,另外設語料的總詞數爲v。接着分別看三層網絡,
如今樣本集及神經網絡結構都有了,接下去使用梯度降低法對其進行優化訓練就能獲得一個語言模型。
經過神經網絡訓練出來的語言模型自帶平滑,這個歸功於咱們的激活函數,而傳統的n-gram方式則須要咱們額外作平滑化處理。並且詞向量還能表示詞語的類似性。
神經網絡語言模型解決了機率平滑、數據稀疏及維度災難等問題,但它仍然沒法完全解決n的問題,即經過前n個詞來預測接着的單詞,這裏認爲神經網絡語言模型沒法取n大於5。另一個是訓練須要花費不少時間。
爲了克服這些缺點,出現了CBOW模型和Skip-gram模型。它們都是經過對原始的神經網絡語言模型進行改良。
另外CBOW模型和Skip-gram模型的輸入向量中再也不使用one-hot形式,而是能夠假設一個m維向量,初始值能夠隨機設置,而後經過訓練不斷優化最後獲得具體的向量值。這也就是爲何說咱們在訓練CBOW模型和Skip-gram模型時會產生一個詞向量的副產品,該詞向量是一個分佈式詞向量。
它對原始的神經網絡語言模型作了一些改造,好比把原來的隱含層去掉了,投影層直接與輸出層相連,這是由於隱含層增長了計算量,並且去掉後基本不會影響效果。投影層作的操做就是累加輸入層的全部向量,再回想一下傳統神經網絡語言模型是怎麼處理輸入層的?就是向量的鏈接操做,將輸入層的全部向量首尾相鏈接。這種方式也就意味着丟棄詞語的序列信息,這很好理解,原來方式是輸入向量首尾先連,而如今是作累和操做。
訓練其實就是根據某個詞先後若干詞來預測該詞,這其實能夠當作是多分類。最樸素的想法就是直接使用softmax來分別計算每一個詞的對應的歸一化的機率。但對於動輒十幾萬詞彙量的場景中使用softmax計算量太大,因而須要用一種二分類組合形式的hierarchical softmax,即輸出層爲一棵二叉樹。
如今看看怎麼來訓練這棵二叉樹。以下圖,每一個二叉樹葉子結點表示一個詞,非葉子結點則表明詞,但它有一個權重參數\theta,每一個非葉子結點的權重參數都不一樣,另外再約定每一個節點的左邊的子節點編碼爲1,右邊的子節點編碼爲0。那麼從根節點開始(根節點不做編碼),詞「天天」的編碼爲10,詞「運動」的編碼爲00。
如今假設正確輸出爲「天天」,對應的編碼爲10,那麼具體是怎麼更新參數的?實際上除了葉子結點,其餘節點均可以當作是一個神經元,能夠看到它是一個二分類的結構,那麼經過logistic迴歸就能夠實現二分類。爲了找到「天天」這個詞,首先經過根節點,通過logistic分類後應該分到左邊子節點,即編碼爲1,接着繼續進行logistic分類到右邊子節點,即編碼爲0,而後獲得最後的結果。
設w爲某個詞,w先後若干個詞用$w_m$表示,二叉樹總共有s層,設從根節點到w節點通過的節點的參數爲$\theta_1,\theta2,...\theta{s-1}$,好比「天天」通過的參數爲$\theta_1,\theta_2$,再設從第二層節點到w節點通過的節點的編碼爲$b_2,b_3,...,b_s$,則w的條件機率爲,
咱們知道除了葉子結點外,其餘每一個節點都是作logistic迴歸,有
爲方便計算取對數似然函數做爲目標函數,獲得
其中l爲語料庫,接着對目標函數作最大化優化,能夠看到目標函數中有兩個參數須要學習,一個是$\theta$一個是輸入x,x學習就是獲得咱們的詞向量副產品,而$\theta$則是CBOW模型的參數。分別對二者求偏導,有
有了偏導就能夠用梯度上升法了,繼續求另一個偏導,有
這樣,兩個向量參數均可以經過梯度上升法更新訓練了。
========廣告時間========
鄙人的新書《Tomcat內核設計剖析》已經在京東銷售了,有須要的朋友能夠到 item.jd.com/12185360.ht… 進行預約。感謝各位朋友。
=========================
歡迎關注: