<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【NLP】NLP重鑄篇之Fasttext

          共 9931字,需瀏覽 20分鐘

           ·

          2020-12-22 17:26

          文本分類

          論文標(biāo)題:Bag of Tricks for Efficient Text Classification
          論文鏈接:https://arxiv.org/pdf/1607.01759.pdf
          代碼地址:https://github.com/facebookresearch/fastText
          復(fù)現(xiàn)代碼地址:https://github.com/wellinxu/nlp_store/blob/master/papers/fasttext.py

          文本表示

          論文標(biāo)題:Enriching Word Vectors with Subword Information
          論文鏈接:https://arxiv.org/pdf/1607.04606.pdf
          代碼地址:https://github.com/facebookresearch/fastText
          復(fù)現(xiàn)代碼地址:https://github.com/wellinxu/nlp_store/blob/master/papers/fasttext.py

          fasttext主要有兩個模型,一個是【Bag of Tricks for Efficient Text Classification】提出的文本分類模型,一個是【Enriching Word Vectors with Subword Information】提出的文本表示模型,其結(jié)構(gòu)跟word2vec非常相似,最大區(qū)別是,分類模型添加了詞粒度的ngram特征,表示模型添加了字符粒度的ngram特征(subword特征)。本文會分別介紹fasttext的分類與表示模型,并復(fù)現(xiàn)相關(guān)代碼,具體可查看https://github.com/wellinxu/nlp_store。

          • fasttext
          • 文本分類
            • 模型結(jié)構(gòu)
            • ngram特征
            • 論文結(jié)果
          • 文本表示
            • 模型結(jié)構(gòu)
            • subword特征
            • 論文結(jié)果
          • fasttext與word2vec結(jié)果比較
          • 參考

          fasttext

          fasttext是facebook在2016年左右提出的模型,在相關(guān)代碼里面,主要包含了兩個模型:文本分類模型和文本表示模型,因為兩個模型都在同一個代碼包里,所以都被大家稱為fasttext模型。根據(jù)原始論文來看,fasttext的文本分類模型就是word2vec中的cbow+huffman樹的結(jié)構(gòu),區(qū)別在于添加了詞級別的ngram特征(并對ngram特征做了hash處理)并且預(yù)測的標(biāo)簽是具體的類別;而fasttext的文本表示模型就是word2vec中的skip-gram+負(fù)采樣的結(jié)構(gòu),區(qū)別在于添加了字符級別的ngram特征(即subword,也進(jìn)行了hash處理)。因為fasttext與word2vec模型非常相似,所以建議先看【NLP重鑄篇之Word2vec】。

          文本分類

          【Bag of Tricks for Efficient Text Classification】論文中提出了一種文本分類模型fasttext,可以作為一種高效的文本分類基準(zhǔn),其精度較高,且速度飛快,使用標(biāo)準(zhǔn)的多核CPU,可以在10分鐘內(nèi)訓(xùn)練包含10億詞的文本,在一分鐘內(nèi)可以對包含30多萬類別的500萬句文本進(jìn)行分類(復(fù)現(xiàn)代碼的速度則遠(yuǎn)遠(yuǎn)不如,原代碼在工程上做了很多優(yōu)化)。

          模型結(jié)構(gòu)


          如上圖所示,與word2vec的CBOW結(jié)構(gòu)類似,特征輸入模型后,直接進(jìn)行求和(或平均)然后就輸出預(yù)測模型,為了提高運算速度,當(dāng)類別比較多的時候,fasttext文本分類模型也采用了層次softmax的方法,具體的也是使用的huffman樹的形式。更多關(guān)于COBW結(jié)構(gòu)與huffman樹的loss計算可參考【NLP重鑄篇之Word2vec】,這邊給出前向傳播相關(guān)代碼:

          ????def?call(self,?inputs,?training=None,?mask=None):
          ????????#?x:[context_len]
          ????????#?huffman_label:?[label_size,?code_len]
          ????????#?huffman_index:?[label_size,?code_len]
          ????????#?y?:?[label_size]
          ????????#?negative_index:?[negatuve_num]
          ????????x,?huffman_label,?huffman_index,?y,?negative_index?=?inputs
          ????????x?=?self.embedding(x)????#?[context_len,?emb_dim]
          ????????x?=?tf.reduce_sum(x,?axis=-2)????#?[emb_dim]

          ????????loss?=?0
          ????????#?huffman樹loss計算
          ????????if?self.is_huffman:
          ????????????for?tem_label,?tem_index?in?zip(huffman_label,?huffman_index):
          ????????????????#?獲取huffman樹編碼上的各個結(jié)點參數(shù)
          ????????????????huffman_param?=?self.huffman_params(tem_index)????#?[code_len,?emb_dim]
          ????????????????#?各結(jié)點參數(shù)與x點積
          ????????????????huffman_x?=?tf.einsum("ab,b->a",?huffman_param,?x)????#?[code_len]
          ????????????????#?獲取每個結(jié)點是左結(jié)點還是右結(jié)點
          ????????????????tem_label?=?tf.squeeze(self.huffman_choice(tem_label),?axis=-1)????#?[code_len]
          ????????????????#?左結(jié)點:sigmoid(-WX),右結(jié)點sigmoid(WX)
          ????????????????l?=?tf.sigmoid(tf.einsum("a,a->a",?huffman_x,?tem_label))????#?[code_len]
          ????????????????l?=?tf.math.log(l)
          ????????????????loss?-=?tf.reduce_sum(l)

          當(dāng)使用模型對文本進(jìn)行分類的時候,層次softmax也有其優(yōu)點。

          其中表示結(jié)點,的父結(jié)點。
          如上計算公式,每個結(jié)點的概率,都是根結(jié)點到當(dāng)前結(jié)點路徑上所有結(jié)點的概率乘積,這也就導(dǎo)致了每個結(jié)點的概率,一定小于其父結(jié)點的概率,那選擇最優(yōu)類別的時候,通過深度優(yōu)先遍歷,計算葉子結(jié)點概率,并保存最大概率,在遍歷過程中可以丟棄概率小于當(dāng)前最大概率的分支?;诖?,模型的預(yù)測代碼為:

          ????def?predict_one(self,?x,?huffman_tree:?HuffmanTree):
          ????????x?=?self.embedding(x)??#?[context_len,?emb_dim]
          ????????x?=?tf.reduce_sum(x,?axis=-2)??#?[emb_dim]

          ????????#?使用huffman樹做分類
          ????????ps?=?{}
          ????????ps[0]?=?1.0
          ????????maxp,?resultw?=?0,?0
          ????????for?w,?code?in?huffman_tree.word_code_map.items():
          ????????????index,?curp?=?0,?1.0
          ????????????for?c?in?code:
          ????????????????left_index?=?huffman_tree.nodes_list[index]
          ????????????????if?left_index?not?in?ps.keys():
          ????????????????????param?=?tf.squeeze(self.huffman_params(np.array([index])))
          ????????????????????p?=?tf.sigmoid(tf.einsum("a,a->",?param,?x))
          ????????????????????p?=?p.numpy()
          ????????????????????ps[left_index]?=?1?-?p
          ????????????????????ps[left_index?+?1]?=?p
          ????????????????index?=?left_index?+?c
          ????????????????curp?*=?ps[index]
          ????????????????if?curp?break
          ????????????if?curp?>?maxp:
          ????????????????maxp?=?curp
          ????????????????resultw?=?w
          ????????return?resultw,?maxp

          ngram特征

          fasttext分類模型與CBOW最大的不同,則是使用了ngram特征,CBOW丟棄了詞序特征,但如果精確地使用詞序特征會讓計算復(fù)雜度提高很多,所以fasttext中使用ngram特征作為附加特征來獲取局部詞序特征信息。具體的,分類中的ngram特征是將連續(xù)n個詞作為一個特征添加到模型中,但是ngram的數(shù)量巨大,為了減少內(nèi)存消耗,模型使用hash技巧,將具有同樣hash值的ngram視為同一個特征。在復(fù)現(xiàn)過程中,為了簡單,直接使用的python自帶的hash函數(shù),相關(guān)ngram特征獲取方式以及hash方式如下:

          ???def?_get_ngram(self,?alist,?is_train=True):
          ????????#?獲取alist中包含的ngram特征
          ????????result,?l?=?set(),?len(alist)
          ????????for?n?in?self.ngram:
          ????????????for?i?in?range(l?-?n?+?1):
          ????????????????w?=?"".join(alist[i:i?+?n])
          ????????????????result.add(w)
          ????????????????if?is_train:
          ????????????????????#?如果是訓(xùn)練階段,則將ngram特征添加到相應(yīng)map中
          ????????????????????if?self.is_embedding:
          ????????????????????????self.ngram_num_map[w]?=?self.ngram_num_map.get(w,?0)?+?self.word_num_map[alist[1:-1]]
          ????????????????????else:
          ????????????????????????self.ngram_num_map[w]?=?self.ngram_num_map.get(w,?0)?+?1
          ????????return?result

          ????def?reduce_ngram_num_by_hash(self):
          ????????#?如果ngram特征數(shù)量大于制定數(shù)量,則讓具有同樣hash值的ngram特征指向同一個表示向量
          ????????for?w,?v?in?self.ngram_num_map.items():
          ????????????if?v?>=?self.min?and?w?not?in?self.ngram2id_map.keys():
          ????????????????self.ngram2id_map[w]?=?len(self.ngram2id_map)?+?self.voc_size
          ????????
          ????????if?len(self.ngram2id_map)?>?self.ngram_num:
          ????????????idmap?=?{}
          ????????????for?w?in?self.ngram2id_map.keys():
          ????????????????h?=?abs(hash(w))
          ????????????????h?=?h?%?self.ngram_num????#?用hash值的最后幾位作為新hash值
          ????????????????if?h?not?in?idmap.keys():
          ????????????????????idmap[h]?=?len(idmap)?+?self.voc_size
          ????????????????self.ngram2id_map[w]?=?idmap[h]

          論文結(jié)果

          如下面兩圖所示,fasttext在許多文本分類任務(wù)上,都有不錯的精度,且速度上會比其他模型快很多很多。下圖只顯示了添加了2gram特征的情況,論文中也有實驗,在Sogou等數(shù)據(jù)集上,使用3gram特征可以進(jìn)一步提高準(zhǔn)確性;同樣的,論文也實驗了不同維度(下圖中特征是10維)對文本分類效果的影響,一般來說,維度越大效果越好(論文中比較了200維跟50維的效果)。

          文本表示

          【Enriching Word Vectors with Subword Information】論文提出了一種文本表示模型fasttext。類似wod2vec等模型,在學(xué)習(xí)詞表示的時候都忽略了詞的形態(tài)特征(如詞由哪些結(jié)構(gòu)組成),這就對那些詞匯量大和生僻詞多的語言不友好,也難以處理oov的詞語。而論文中提出的fasttext模型,則使用了subword特征(字符級別的ngram),每一個subword都會學(xué)一個表示,最終的詞向量,由該詞所有的subword向量的和來表示。

          模型結(jié)構(gòu)

          fasttext文本表示模型,是基于word2vec的skip-gram進(jìn)行擴展,添加了subword特征。為了提高訓(xùn)練速度,模型也使用了負(fù)采樣的方式,根據(jù)之前文章【NLP重鑄篇之Word2vec】,負(fù)采樣的loss如下:

          這是skip-gram結(jié)構(gòu)的負(fù)采樣loss,其中表示輸入向量,表示正樣本索引,表示負(fù)采樣的索引,表示索引為i的詞向量,表示索引為i的輸出參數(shù)向量,s是得分函數(shù)。
          同樣的,更多關(guān)于skip-gram結(jié)構(gòu)與負(fù)采樣內(nèi)容,可參考【NLP重鑄篇之Word2vec】,下面給出前向傳播的代碼:

          ????def?call(self,?inputs,?training=None,?mask=None):
          ????????#?x:[context_len]
          ????????#?huffman_label:?[label_size,?code_len]
          ????????#?huffman_index:?[label_size,?code_len]
          ????????#?y?:?[label_size]
          ????????#?negative_index:?[negatuve_num]
          ????????x,?huffman_label,?huffman_index,?y,?negative_index?=?inputs
          ????????x?=?self.embedding(x)????#?[context_len,?emb_dim]
          ????????x?=?tf.reduce_sum(x,?axis=-2)????#?[emb_dim]

          ????????loss?=?0
          ????????#?負(fù)采樣loss計算
          ????????if?self.is_negative:
          ????????????y_param?=?self.negative_params(y)????#?[label_size,?emb_dim]
          ????????????negative_param?=?self.negative_params(negative_index)????#?[negative_num,?emb_dim]
          ????????????y_dot?=?tf.einsum("ab,b->a",?y_param,?x)????#?[label_size]
          ????????????y_p?=?tf.math.log(tf.sigmoid(y_dot))????#?[label_size]
          ????????????negative_dot?=?tf.einsum("ab,b->a",?negative_param,?x)????#?[negative_num]
          ????????????negative_p?=?tf.math.log(tf.sigmoid(-negative_dot))????#?[negative_num]
          ????????????l?=?tf.reduce_sum(y_p)?+?tf.reduce_sum(negative_p)
          ????????????loss?-=?l
          ????????return?loss

          subword特征

          每一個詞都可以被表示為一組字符級別的ngram集合,為了區(qū)分詞的開頭和結(jié)尾,會在詞的前后添加"<"和">"兩個字符,同時也會將整個詞添加到ngram集合中去。舉個例子,如果詞為“自然語言”,n為3,此時字符ngram為:<自然、自然語、然語言、語言>、<自然語言>。需要注意的事,“<自然語言>”跟“自然語言”是兩個不同的token,前面是一個整詞,后面是一個詞中的4gram特征。添加了subword特征,改變了skip-gram的輸入(從一個變成多個),那得分函數(shù)也有所改變,如下:

          其中表示詞w的字符ngram的索引集合,表示索引為g的向量表示,表示索引為c的輸出參數(shù)向量。跟分類模型類似,這里也會使用hash函數(shù),將具有同樣hash值的ngram特征用同一個向量表示。在訓(xùn)練完成后,每個詞的詞向量,則由該詞的所有ngram特征向量之和來表示,對于oov的詞,類似的也用該詞存在的ngram向量之和表示。論文中,ngram的范圍是3-6。
          subword的獲取方式以及hash方式與上面ngram一致,fasttext詞向量尤其是某些oov詞語向量的獲取方式如下:

          ????????#?獲取詞向量(模型訓(xùn)練完之后)
          ????????if?self.is_embedding:
          ????????????self.embeddings?=?self.model.embedding.embeddings.numpy()
          ????????????self.word_embeddings?=?[]
          ????????????self.ngram_embeddings?=?{v:?self.embeddings[v]?for?v?in?self.ngram2id_map.values()}
          ????????????for?k,?v?in?self.word_map.items():
          ????????????????ngrams?=?self.w2ngram_map[k]
          ????????????????ngrams.append(v)
          ????????????????nemb?=?[self.embeddings[n]?for?n?in?ngrams]
          ????????????????emb?=?np.mean(nemb,?axis=0)
          ????????????????self.word_embeddings.append(emb)
          ????????????self.word_embeddings?=?np.array(self.word_embeddings)
          ????????????norm?=?np.expand_dims(np.linalg.norm(self.word_embeddings,?axis=1),?axis=1)
          ????????????self.word_embeddings?/=?norm????#?歸一化

          ????def?get_word_emb(self,?words):
          ????????#?獲取詞向量,當(dāng)詞不存在時用該詞的ngram之和表示
          ????????word_emb?=?[]??#?[word_len,?embedding]
          ????????for?w?in?words:
          ????????????if?w?in?self.word_map.keys():
          ????????????????word_emb.append(self.word_embeddings[self.word_map[w]])
          ????????????else:
          ????????????????ngrams?=?self._get_ngram("<"?+?w?+?">",?False)
          ????????????????indexs?=?[self.ngram2id_map[n]?for?n?in?ngrams?if?n?in?self.ngram2id_map.keys()]
          ????????????????tem_emb?=?[self.ngram_embeddings[i]?for?i?in?indexs]
          ????????????????emb?=?np.mean(tem_emb,?axis=0)
          ????????????????norm?=?np.linalg.norm(emb)
          ????????????????emb?/=?norm
          ????????????????word_emb.append(emb)
          ????????return?word_emb

          論文結(jié)果


          如上圖所示,論文對比了word2vec跟fasttext模型在各種語言上,人類判斷跟模型計算的相似度得分的相關(guān)性,其中sg與cbow分別表示word2vec中的skip-gram與CBOW結(jié)構(gòu)的模型,sisg-與sisg都是fasttext模型,sisg-在處理oov詞的時候直接使用null的向量表示,sisg則使用該詞的ngram向量之和來表示,可看出sisg的結(jié)果基本都優(yōu)于其他結(jié)果,側(cè)面證明了subword帶來的有效信息。上圖的結(jié)果,則顯示了詞向量在不同語言上語義跟句法任務(wù)的準(zhǔn)確性,可以看出fasttext對大部分語言的句法任務(wù)都有顯著提升。

          fasttext與word2vec結(jié)果比較

          根據(jù)本文復(fù)現(xiàn)的fasttext文本表示模型,以及【NLP重鑄篇之Word2vec】中復(fù)現(xiàn)的word2vec模型,基于THUCNews文本分類驗證數(shù)據(jù)集cnews.val.txt的5000條文本進(jìn)行訓(xùn)練,得到的詞向量部分展示結(jié)果如下圖所示:
          從上圖可以看出,fasttext的結(jié)果會偏向于具有相似的subword的詞,比如基金跟政策兩個詞的相似詞,fasttext的結(jié)果會偏向包含詞本身的結(jié)果,word2vec則不是;另外對于出現(xiàn)頻率較低的詞,但這個詞的subword出現(xiàn)頻率不低,則fasttext的效果略好,如上海大學(xué)這個詞;而對于oov的詞,word2vec是給不出結(jié)果的,fasttext則能給出相對還可以的結(jié)果,如南京大學(xué)這個詞。

          參考

          【1】基于tf2的word2vec模型復(fù)現(xiàn):https://github.com/wellinxu/nlp_store/blob/master/papers/word2vec.py
          【2】基于tf2的fasttext模型復(fù)現(xiàn):https://github.com/wellinxu/nlp_store/blob/master/papers/fasttext.py

          往期精彩回顧





          獲取本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:

          https://t.zsxq.com/qFiUFMV

          本站qq群704220115。

          加入微信群請掃碼:

          瀏覽 77
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色坐爱视频 | 欧美乱伦小说 | 蜜臀久久精品久久久久消防站 | 五月丁香爱 | 在线观看日韩毛片 |