FastText是Tomas繼word2vec的又一力作,它其實是兩篇論文。一篇是Bag of Tricks for Efficient Text Classification,作用的是分類,速度快,效果也不差,在工業界中備受青睞;另一篇是Enriching Word Vectors with Subword Information,可以說是在word2vec基礎上的發展。

FastText原理介紹

FastText原理和word2vec的原理差不多,除了輸入不太一樣,FastText可以做分類任務,以及一些代碼細節外,其他都是一樣的。有一篇介紹word2vec的文章講的非常棒,word2vec中的數學原理詳解,如果是word2vec的初學者,強烈建議去看。

下面以CBOW為例簡單地介紹FastText的原理。

輸入層:黑色框代表的是詞向量,也是word2vec的輸入;黑色框+藍色框是FastText訓練embedding時的輸入,藍色框代表的是一個word的一個subword,比如當minn=1,maxn=2時,單詞「喜歡」首先包裝成「<喜歡>」,所以subwords是[<,喜,歡>,<喜,喜歡,歡>] ;黑色框+藍色框+紅色框是FastText分類時的輸入,紅色框代表的是單詞間word ngrams,比如當wordngrams=2時,「< 我 愛 北京 天安門 >」的wordngrams就是[<我,我愛,愛北京,北京天安門,天安門>]。

映射層:在word2vec中,映射層是各個word embedding的相加;FastText中是加和平均,加和平均後的映射層向量為 X_w

輸出層:輸出層可以是softmax,層次softmax或者負採樣。當訓練embedding時,或者label數量太多時,必須要算所有單詞或label得分,這個過程是非常耗時的,為了縮短訓練時間,Toams提出了層次softmax和負採樣。 層次softmax的核心是根據全部語料的詞頻建立Huffman樹,詞頻大的越靠近根節點,利用上下文只預測中心詞,從而調整樹節點的參數,這樣就預測的實際次數就變成了 log_2N , N 是單詞數。負採樣是根據值定的採樣演算法在諸多的負樣本中選取質量高的作為實際的負樣本,有效減少預測label的同時也提高了word embedding的質量。

以CBOW模型、層次softmax為例推導:

上圖中設一個單詞為 w ,上下文為 context(w) ,在word2vec中上下文只是指左右窗口中的單詞,在FastText中還包含subwords和wordNgrams。

上下文預測中心詞的概率表示為:

p(w|context(w))=prod_{j=2}^{l^w}p(d_j^w|X_w,	heta_{j-1}^w)

其中,

egin{equation}   p(d_j^w|X_w,	heta_{j-1}^w)= left{                egin{array}{**lr**}                sigma(X_w^	op	heta_{j-1}^w), & d_j^w=1\                1-sigma(X_w^	op	heta_{j-1}^w), &  d_j^w=0              end{array}   
ight.   end{equation}

                         =left[ sigma(X_w^	op	heta_{j-1}^w) 
ight]^{d_j^w}left[ 1-sigma(X_w^	op	heta_{j-1}^w) 
ight]^{1-d_j^w}

損失函數為:

L=sum_{win C}^{}{log p(w|context(w))}

=sum_{win C}^{}{log prod_{j=2}^{l^w}{left[ sigma(X_w^	op	heta_{j-1}^w) 
ight]^{d_j^w}left[ 1-sigma(X_w^	op	heta_{j-1}^w) 
ight]^{1-d_j^w}}}

=sum_{win C}^{}{sum_{j=2}^{l^w}{{d_j^wlogsigma(X_w^	op	heta_{j-1}^w)+(1-d_j^w)log(1-sigma(X_w^	op	heta_{j-1}^w))}}}

其中 C 是整個語料庫。

取出上面最裡面的公式來看,

L(w,j)=d_j^wlogsigma(X_w^	op	heta_{j-1}^w)+(1-d_j^w)log(1-sigma(X_w^	op	heta_{j-1}^w))

左右兩邊同時對 	heta_{j-1}^w 求導有,

frac{partial L(w,j)}{partial 	heta_{j-1}^w} = (d_j^w-sigma(X_w^	op	heta_{j-1}^w))X_w^	op

根據對稱性有,

frac{partial L(w,j)}{partial X_w} = (d_j^w-sigma(X_w^	op	heta_{j-1}^w))	heta_{j-1}^w

先對詞向量進行更新,一個同事說的好,前向傳播和反向傳播的時候的確應該是同一套參數:

v(	ilde{w})=v(	ilde{w})+etasum_{j=2}^{l^w}{frac{partial L(w,j)}{partial X_w}} ,

	ilde{w} 是context(w)中的一個詞, v(	ilde{w}) 表示 	ilde{w} 的詞向量。

再對對參數 	heta_{j-1}^w 更新,順序不能變:

	heta_{j-1}^w = 	heta_{j-1}^w +etafrac{partial L(w,j)}{partial 	heta_{j-1}^w}

以CBOW模型、Negsampling為例:

對於一個給定的正樣本 (context(w), w) ,我們想要最大化

g(w)=prod_{uin{{w}}cup NEG(w)}^{}p(u|context(w))

其中, NEG(w) 是使用負採樣演算法得到的負樣本集合,

egin{equation}   p(u|context(w))= left{                egin{array}{**lr**}                sigma(X_w^	op	heta_{}^u), & L^w(u)=1\                1-sigma(X_w^	op	heta^u), &  L^w(u)=0              end{array}   
ight.   end{equation}

                         =left[ sigma(X_w^	op	heta^u) 
ight]^{L^w(u)}left[ 1-sigma(X_w^	op	heta_{}^u) 
ight]^{1-L^w(u)}

最終的損失函數就是:

L=logprod_{win C}^{}g(w)=sum_{win C}^{}{log g(w)}

那負採樣演算法是什麼呢?一個詞被選作負樣本的概率為:

P(w)=frac{[counter(u)]^{0.5}}{sum_{uin D}^{}{[counter(u)]^{0.5}}}

冪次是0.5,比冪次是1更能選中低頻詞。

FastText數據格式

分類時的輸入:

     word_1 word_2 word_3 … word_n \_\_label\_\_1

空格,tab都可以分割,"__label__"分隔符可以由參數-label指定,以行為單位,最大數目不超過1024,否則強行截斷。

訓練embedding時的輸入:

     word_1 word_2 word_3 … word_n

同樣空格,tab都可以分割。

subwords和wordNgrams都是程序自動計算的,不需要人工輸入。

FastText代碼架構

FastText源碼的結構如下圖所示。左邊是代碼文件,右邊是代碼架構。

main文件是入口,會根據用戶參數調用fasttext文件不同的函數。

fasttext文件可以用CBOW或者Skip-gram的方式訓練word embedding,也可以做分類的訓練和預測。

model文件負責模型具體邏輯的實現,比如CBOW或者Sg的具體訓練過程,前向反饋後向傳播等。

dictionary文件主要是前期對語料的處理,比如建立字典,統計詞頻,過濾低頻詞等。

args文件主要是涉及到用戶可操作的參數。

matrix, real, vector文件主要是向量計算的輔助。

utils就兩個函數,功能是文件大小和指針定位。

productquantizer, qmatrix文件主要是參數壓縮的相關操作,不會涉及這塊。

FastText參數

下面的參數都是用戶可以指定的,簡單介紹一下這些參數,具體意義可以看下圖中的注釋。

loss可以是softmax,h-softmax,negsampling。

model可以是skipgram(sg)和cbow。

neg代表負採樣的個數。

wordNgrams代表將一個單詞和其後面的片語合在一起,如FastText原理介紹中輸入層使用的例子。

minn和maxn分別代表subwords的最小長度和最大長度,如FastText原理介紹中輸入層使用的"喜歡"的例子。

bucket表示可容納的subwords和wordNgrams的數量,可以理解成是它們存放的表,與word存放的表是分開的。

t表示過濾高頻詞的閾值,像"the","a"這種高頻但語義很少的詞應該過濾掉。

推薦閱讀:

相关文章