【NLP實戰】基於ALBERT的文本類似度計算

實戰是學習一門技術最好的方式,也是深刻了解一門技術惟一的方式。所以,NLP專欄推出了實戰專欄,讓有興趣的同窗在看文章之餘也能夠本身動手試一試。
python


ALBERT是一個比BERT要輕量,效果更好的模型,本篇實踐介紹如何用ALBERT計算兩個文本的類似度。git


做者&編輯 | 小Dream哥github

1 ALBERT介紹 web

ALBERT利用詞嵌入參數因式分解和隱藏層間參數共享兩種手段,顯著減小了模型的參數量的同時,基本沒有損失模型的性能。筆者在下面的文章中詳細介紹了ALBERT的理論,感興趣的同窗能夠戳進去了解:算法


【NLP】ALBERT:更輕更快的的預訓練微信


albert_tiny模型,可以顯著提升模型的推理速度,可是效果依然很棒,這裏介紹如何基於albert_tiny模型進行文本類似度計算。網絡

2  BERT4KERAS機器學習

原本本身寫了個基於tensorflow的ALBERT模型,後來看到蘇劍林老師的bert4keras,以爲確實實現簡潔,易懂。遂決定分享給你們。ide


感興趣的同窗能夠看看蘇劍林老師的網站:函數

https://spaces.ac.cn/archives/6915


BERT4KERAS是蘇老師基於kears實現的幾個BERT模型,包括BERT,ALBERT和ROBERTA,基於BERT4KERAS能夠快速的使用這些模型,也可以快速的實現對BERT改進的想法。


快速安裝:

pip install git+https://www.github.com/bojone/bert4keras.git

3 如何獲取ALBERT-zh  

從以下的github中可以獲取訓練好的ALBERT-zh 模型:


https://github.com/brightmart/albert_zh

4  開始實戰

ALBERT輸出的第一個向量,能夠用來表徵總體的輸入文本,在本篇實戰中,利用這個向量來計算文本之間的類似度。


類似度的計算大體能夠分爲這麼幾個步驟:

1. 構建模型,加載ALBERT預訓練模型。

2. 構建分詞器,處理輸入。

3. 利用模型,計算輸入文本的向量表徵。

4. 利用文本向量,計算兩個文本之間距離或者類似度。

1)構建模型,加載ALBERT預訓練模型

# 加載預訓練模型
bert = build_bert_model(
config_path=config_path,
checkpoint_path=checkpoint_path,
   with_pool=True,
albert=True,
   return_keras_model=False,
)

這裏直接調用bert4keras的build_bert_model接口,構建albert模型,並直接加載albert的中文模型的權重。


config_path用來指定模型的配置文件路徑;

checkpoint_path用來指定模型權重文件的路徑;

albert表示指定用albert模型;


2) 構建分詞器,處理輸入

#構建分詞器

tokenizer = Tokenizer(dict_path)


#格式化輸入

token_ids1, segment_ids1 = tokenizer.encode(u'我想去北京')
token_ids2, segment_ids2 = tokenizer.encode(u'我想去香港')
token_ids3, segment_ids3 = tokenizer.encode(u'目前的局勢,止暴制亂,刻不容緩')

首先構建分詞器這裏直接用了bert4keras定義的分詞器Tokenizer。


而後用分詞器處理輸入,得到輸入文本在詞典中的序號表示及分段信息表示。這裏解釋下爲何要將輸入文本轉化成這兩個表示:

1.albert模型的輸入與bert相似,須要接受詞、分段以及位置三個輸入,位置信息由模型內的代碼處理;


2.將詞轉化爲詞在詞典中的序號便於後續的詞嵌入操做。

3) 利用模型,計算輸入文本的向量表徵

#計算文本的向量表徵,獲取albert的第一個位置的輸出

sentence_vec1 = model.predict([np.array([token_ids1]), np.array([segment_ids1])])[0]
sentence_vec2 = model.predict([np.array([token_ids2]), np.array([segment_ids2])])[0]
sentence_vec3 = model.predict([np.array([token_ids3]), np.array([segment_ids3])])[0]

由於咱們本次是直接利用預訓練模型的知識,直接計算文本的向量表徵,所以沒有訓練過程,直接predict便可得到文本的向量表徵。這裏,獲取albert的第一個位置的輸出做爲輸入文本的向量表徵。


4) 計算文本類似度

# 引入兩個類似度計算包,歐氏距離和餘弦距離

from sklearn.metrics.pairwise import euclidean_distances
from sklearn.metrics.pairwise import cosine_similarity

#定義類似度計算函數
def similarity_count(vec1, vec2, mode='cos'):
   if mode == 'eu':
       return euclidean_distances([vec1,vec2])[0][1]
   if mode == 'cos':
       return cosine_similarity([vec1, vec2])[0][1]


#類似度計算

#餘弦距離

similarity_count(sentence_vec1, sentence_vec2)

#歐式距離
similarity_count(sentence_vec1, sentence_vec2, mode='eu')

這裏引入sklearn中的兩個計算歐氏距離和餘弦距離的包來計算文本之間的距離。具體過程相對簡單,直接看上面的代碼吧。

5 結果展現

如上圖所示,計算了「我想去北京」和「我想去香港」兩句話的餘弦距離和歐式距離;計算了「我想去北京」和「目前的局勢,止暴制亂,刻不容緩」兩句話的餘弦距離和歐式距離。兩句表達意思相近的話,類似度較高,距離較短。可是區隔度不是特別大,因此,在生產中,在一些特別的領域,須要用特別的語料,進行fintune,會有更好的效果。


至此,介紹瞭如何利用bert4keras搭建albert模型進行文本類似度計算,代碼在咱們有三AI的github能夠下載:https://github.com/longpeng2008/yousan.ai/tree/master/natural_language_processing

找到albert文件夾,執行python3 similarity.py就能夠運行了。

總結


ALBERT利用詞嵌入參數因式分解和隱藏層間參數共享兩種手段,顯著減小了模型的參數量的同時,基本沒有損失模型的性能,是一個不錯的工做。


除了使用它,更關鍵的是albert模型的實現和理論。咱們會在知識星球討論相關的內容,感興趣的話能夠掃描下面的二維碼瞭解。


讀者們能夠留言,或者加入咱們的NLP羣進行討論。感興趣的同窗能夠微信搜索jen104,備註"加入有三AI NLP羣"


下期預告:命名實體識別實踐

知識星球推薦

掃描上面的二維碼,就能夠加入咱們的星球,助你成長爲一名合格的天然語言處理算法工程師。


知識星球主要有如下內容:


(1) 聊天機器人。考慮到聊天機器人是一個很是複雜的NLP應用場景,幾乎涵蓋了全部的NLP任務及應用。因此小Dream哥計劃以聊天機器人做爲切入點,經過介紹聊天機器人的原理和實踐,逐步系統的更新到大部分NLP的知識,會包括語義匹配,文本分類,意圖識別,語義匹配命名實體識別、對話管理以及分詞等。


(2) 知識圖譜。知識圖譜對於NLP各項任務效果好壞的重要性,就比如基礎知識對於一個學生成績好壞的重要性。他是NLP最重要的基礎設施,目前各大公司都在着力打造知識圖譜,做爲一個NLP工程師,必需要熟悉和了解他。


(3) NLP預訓練模型。基於海量數據,進行超大規模網絡的無監督預訓練。具體的任務再經過少許的樣本進行Fine-Tune。這樣模式是目前NLP領域最火熱的模式,頗有可能引領NLP進入一個全新發展高度。你怎麼不深刻的瞭解?


轉載文章請後臺聯繫

侵權必究

往期精選


本文分享自微信公衆號 - 有三AI(yanyousan_ai)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索