【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源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索