1. BERT 语义相似度

BERT的全称是Bidirectional Encoder Representation from Transformers,是Google2018年提出的预训练模型,即双向Transformer的Encoder,因为decoder是不能获要预测的信息的。模型的主要创新点都在pre-train方法上,即用了Masked LM和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。

有一个这样的场景,QA对话系统,希望能够在问答库中找到与用户问题相似的句子对,然后把答案返回给用户。这篇就是要解决这个问题的。

关于 BERT 的原理知识请访问: http://mantchs.com/2019/09/28/NLP/BERT/

下面介绍一个封装好的 BERT 工具,利用该工具能够快速的得到词向量表示。该工具的名称叫做: bert-as-service,从名称就可以看出作者是把 BERT 作为一种服务了,只要调用该服务就能够得到我们想要的向量表示,得到向量以后,就可以通过余弦相似度的计算公式计算向量之间的相似度。

bert-as-service 源码详见: https://github.com/hanxiao/bert-as-service

bert-as-service 使用文档: https://bert-as-service.readthedocs.io/en/latest/index.html

步骤如下:

  1. 安装 bert-as-service 的服务端和客户端。
  2. 预训练 BERT 模型。
  3. 客户端编写代码请求服务端得到句向量。
  4. 句子与句子向量之间计算相似度,并返回 top_k 个结果。

2. 安装 bert-as-service

  1. 环境要求:

    Python版本 >= 3.5,Tensorflow版本 >= 1.10

    (本人环境,Python = 3.7 Tensorflow = 1.13.1)

  2. 安装服务端和客户端

    pip install -U bert-serving-server bert-serving-client

3. 启动 BERT 服务

  1. 下载预训练模型

    Google AI发布的经过预训练的BERT模型。这里我们下载 BERT-Base, Chinese,12-layer, 768-hidden, 12-heads, 110M parameters。

    链接:

    https://pan.baidu.com/s/1jJudiTj__vbFb0WkEQUxWw

    密码:mf4p

  2. 启动服务

    解压缩后,运行如下命令进行启动,目录换成解压后的路径。(-num_worker指定使用多少个CPU)

    bert-serving-start -model_dir /Users/mantch/Downloads/chinese_L-12_H-768_A-12 -num_worker=4

    运行后会看到如下结果:

        http_max_connect = 10
    http_port = None
    mask_cls_sep = False
    max_batch_size = 256
    max_seq_len = 25
    model_dir = /Users/mantch/Downloads/chinese_L-12_H-768_A-12
    no_position_embeddings = False
    no_special_token = False
    num_worker = 4
    pooling_layer = [-2]
    pooling_strategy = REDUCE_MEAN
    port = 5555
    port_out = 5556
    prefetch_size = 10
    priority_batch_size = 16
    show_tokens_to_client = False
    tuned_model_dir = None
    verbose = False
    xla = False

    其中就已经显示了port = 5555,port_out = 5556 等端口号信息。

    如果显示以下信息就表示可以使用了

    I:WORKER-0:[__i:gen:559]:ready and listening!
    I:WORKER-3:[__i:gen:559]:ready and listening!
    I:WORKER-1:[__i:gen:559]:ready and listening!
    I:WORKER-2:[__i:gen:559]:ready and listening!
    I:VENTILATOR:[__i:_ru:164]:all set, ready to serve request!

4. 相似度计算

  1. 数据集

    我们使用蚂蚁金服语义相似度比赛的一份数据集,该数据集分为 4 列,第一列是索引,第二列和第三列是句子,第四列中的 1 表示这两个句子是同义句,否则表示为 0。

    数据集下载地址: https://www.lanzous.com/ia9dg8b

  2. 编写代码

    import pandas as pd
    import numpy as np
    from bert_serving.client import BertClient
    from termcolor import colored num = 100 # 采样数
    topk = 5 # 返回 topk 个结果 # 读取数据集
    sentence_csv = pd.read_csv('atec_nlp_sim_train_all.csv', sep='\t', names=['idx', 's1', 's2', 'label'])
    sentences = sentence_csv['s1'].tolist()[:num]
    print('%d questions loaded, avg.len %d' % (len(sentences), np.mean([len(d) for d in sentences]))) with BertClient(port=5555, port_out=5556) as bc: # 获取句子向量编码
    doc_vecs = bc.encode(sentences) while True:
    query = input(colored('your question:', 'green'))
    query_vec = bc.encode([query])[0] # 余弦相似度 分数计算。
    # np.linalg.norm 是求取向量的二范数,也就是向量长度。
    score = np.sum(query_vec * doc_vecs, axis=1) / np.linalg.norm(doc_vecs, axis=1) '''
    argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引) [::-1]取从后向前(相反)的元素, 例如[ 1 2 3 4 5 ]
    则输出为[ 5 4 3 2 1 ]
    '''
    topk_idx = np.argsort(score)[::-1][:topk]
    print('top %d questions similar to "%s"' % (topk, colored(query, 'green')))
    for idx in topk_idx:
    print('> %s\t%s' % (colored('%.1f' % score[idx], 'cyan'), colored(sentences[idx], 'yellow')))

BERT实现QA中的问句语义相似度计算的更多相关文章

  1. 孪生网络(Siamese Network)在句子语义相似度计算中的应用

    1,概述 在NLP中孪生网络基本是用来计算句子间的语义相似度的.其结构如下 在计算句子语义相似度的时候,都是以句子对的形式输入到网络中,孪生网络就是定义两个网络结构分别来表征句子对中的句子,然后通过曼 ...

  2. NLP 语义相似度计算 整理总结

    更新中 最近更新时间: 2019-12-02 16:11:11 写在前面: 本人是喜欢这个方向的学生一枚,写文的目的意在记录自己所学,梳理自己的思路,同时share给在这个方向上一起努力的同学.写得不 ...

  3. 深度学习解决NLP问题:语义相似度计算

    在NLP领域,语义相似度的计算一直是个难题:搜索场景下query和Doc的语义相似度.feeds场景下Doc和Doc的语义相似度.机器翻译场景下A句子和B句子的语义相似度等等.本文通过介绍DSSM.C ...

  4. DSSM 深度学习解决 NLP 问题:语义相似度计算

    https://cloud.tencent.com/developer/article/1005600

  5. 用BERT做语义相似度匹配任务:计算相似度的方式

    1. 自然地使用[CLS] 2. cosine similairity 3. 长短文本的区别 4. sentence/word embedding 5. siamese network 方式 1. 自 ...

  6. 对C++11中的`移动语义`与`右值引用`的介绍与讨论

    本文主要介绍了C++11中的移动语义与右值引用, 并且对其中的一些坑做了深入的讨论. 在正式介绍这部分内容之前, 我们先介绍一下rule of three/five原则, 与copy-and-swap ...

  7. 纸壳CMS3.0中的规则引擎,表达式计算

    纸壳CMS3.0中的规则引擎,用于计算通用表达试结果.通常业务逻辑总是复杂多变的,使用这个规则引擎可以灵活的修改计算表达式. IRuleManager IRuleManager,是使用规则引擎的主要接 ...

  8. 图解BERT(NLP中的迁移学习)

    目录 一.例子:句子分类 二.模型架构 模型的输入 模型的输出 三.与卷积网络并行 四.嵌入表示的新时代 回顾一下词嵌入 ELMo: 语境的重要性 五.ULM-FiT:搞懂NLP中的迁移学习 六.Tr ...

  9. 全网最硬核 Java 新内存模型解析与实验单篇版(不断更新QA中)

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

随机推荐

  1. django框架进阶-使用缓存-长期维护

    ###############   django-缓存页面    ############### ########################################### # 全站缓存, ...

  2. 四、RabbitMQ Exchange类型

    RabbitMQ整体上是一个生产者与消费者模型,主要负责接收.存储和转发消息.可以把消息传递的过程想象成:当你将一个包裹送到邮局,邮局会暂存并最终将邮件通过邮递员送到收件人的手上,RabbitMQ就好 ...

  3. CF-552E-Two Teams

    pro:给出n, k和长度为n的数组a, 两个人轮流取数1先取,设a[i]是当前数组中最大值,则取走a[i - k]到a[i + k]这段数,然后把a[i + k + 1]和后面的补到 a[i - k ...

  4. hadoop配置文件详解、安装及相关操作补充版

    一.      Hadoop伪分布配置           首先应该现在profile文件添加hadoop_home操作如下: export JAVA_HOME=/usr/java/jdk expor ...

  5. 与项目欧拉速度比较:C vs Python与Erlang vs Haskell

    我从问题#12 ProjectEuler作为编程练习,并比较我在C,Python,Erlang和Haskell中的实现(当然不是最优)实现.为了获得更高的执行时间,我搜索了第一个有1000个以上因子的 ...

  6. supervised learning|unsupervised learning

    监督学习即是supervised learning,原始数据中有每个数据有自己的数据结构同时有标签,用于classify,机器learn的是判定规则,通过已成熟的数据training model达到判 ...

  7. 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?(python语言)

    # 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? # 斐波那契数列:0,1,1,2,3,5,8,13, ...

  8. <SCOI2009>粉刷匠の思路

    emm.dp真的是写不来啊难过 不边写边注释我就挂了 #include<cstdio> #include<cstring> #include<iostream> # ...

  9. Python爬虫实战之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 对百度贴吧的任意帖子进行抓取 指定是否只抓取楼主发帖 ...

  10. vue watch和computed的使用场景

    watch 监听某个数据的变化(监听完调用什么函数) 一个数据影响多个数据 (比如:浏览器自适应.监控路由对象.监控自身属性变化) computed 计算后返回新 一个数据受多个数据影响(比如:计算总 ...