使用simBert生成同义语句(全过程)

一、simbert介绍和下载

simbert模型,是由苏剑林开发的模型,以Google开源的BERT模型为基础,基于微软的UniLM思想设计了融检索与生成于一体的任务,来进一步微调后得到的模型,所以它同时具备相似问生成和相似句检索能力。

SimBERT属于有监督训练,训练语料是自行收集到的相似句对,通过一句来预测另一句的相似句生成任务来构建Seq2Seq部分,然后前面也提到过[CLS]的向量事实上就代表着输入的句向量,所以可以同时用它来训练一个检索任务。

开源地址:https://github.com/ZhuiyiTechnology/simbert

项目介绍https://kexue.fm/archives/7427

已预训练的模型包含 Tiny(26M)、Small(49M)、Base(344M)三个模型。

下载:

https://github.com/ZhuiyiTechnology/pretrained-models

Tiny下载路径Small下载路径Base下载路径

适合创建相似文本集

>>> gen_synonyms(u'微信和支付宝哪个好?')
[
    u'微信和支付宝,哪个好?',
    u'微信和支付宝哪个好',
    u'支付宝和微信哪个好',
    u'支付宝和微信哪个好啊',
    u'微信和支付宝那个好用?',
    u'微信和支付宝哪个好用',
    u'支付宝和微信那个更好',
    u'支付宝和微信哪个好用',
    u'微信和支付宝用起来哪个好?',
    ...........
]

二、项目使用

2.1 创建conda 环境

1)查看虚拟环境

(base) C:\Users\user>conda info -e
# conda environments:
#
base                  *  D:\Programs\Anaconda3
pytorch                  D:\Programs\Anaconda3\envs\pytorch

2)创建虚拟环境

(base) C:\Users\user>conda create -n simbert

3)安装依赖包

因bert4keras的版本要求,推荐版本见:tensorflow 1.14 + keras 2.3.1 + bert4keras 0.7.7

版本 说明见:https://github.com/bojone/bert4keras

(base) C:\Users\user>conda activate simbert
(simbert) C:\Users\user>conda install keras
(simbert) C:\Users\user>pip install bert4keras
(simbert) C:\Users\user>pip install tensorflow

卸载安装错误的情况:

(simbert) C:\Users\user>pip uninstall tensorflow
(simbert) C:\Users\user>pip uninstall bert4keras

重新安装

conda create -n simbert python=3.6
(simbert) C:\Users\user>conda install tensorflow==1.14
(simbert) C:\Users\user>conda install keras==2.3.1
(simbert) C:\Users\user>pip install bert4keras==0.7.7

4)验证安装情况

from keras.layers import *
from bert4keras.backend import keras, K

2.2使用simbert进行测试验证

1)下载测试代码

https://github.com/ZhuiyiTechnology/pretrained-models/blob/master/examples/simbert_base.py

#! -*- coding: utf-8 -*-
# SimBERT base 基本例子
# 测试环境:tensorflow 1.14 + keras 2.3.1 + bert4keras 0.7.7

import numpy as np
from collections import Counter
from bert4keras.backend import keras, K
from bert4keras.models import build_transformer_model
from bert4keras.tokenizers import Tokenizer
from bert4keras.snippets import sequence_padding, AutoRegressiveDecoder
from bert4keras.snippets import uniout
from keras.layers import *

maxlen = 32

# bert配置
config_path = './bert/chinese_simbert_L-12_H-768_A-12/bert_config.json'
checkpoint_path = './bert/chinese_simbert_L-12_H-768_A-12/bert_model.ckpt'
dict_path = './bert/chinese_simbert_L-12_H-768_A-12/vocab.txt'

# 建立分词器
tokenizer = Tokenizer(dict_path, do_lower_case=True)  # 建立分词器

# 建立加载模型
bert = build_transformer_model(
    config_path,
    checkpoint_path,
    with_pool='linear',
    application='unilm',
    return_keras_model=False,
)

encoder = keras.models.Model(bert.model.inputs, bert.model.outputs[0])
seq2seq = keras.models.Model(bert.model.inputs, bert.model.outputs[1])


class SynonymsGenerator(AutoRegressiveDecoder):
    """seq2seq解码器
    """
    @AutoRegressiveDecoder.set_rtype('probas')
    def predict(self, inputs, output_ids, step):
        token_ids, segment_ids = inputs
        token_ids = np.concatenate([token_ids, output_ids], 1)
        segment_ids = np.concatenate(
            [segment_ids, np.ones_like(output_ids)], 1)
        return seq2seq.predict([token_ids, segment_ids])[:, -1]

    def generate(self, text, n=1, topk=5):
        token_ids, segment_ids = tokenizer.encode(text, max_length=maxlen)
        output_ids = self.random_sample([token_ids, segment_ids], n, topk)  # 基于随机采样
        return [tokenizer.decode(ids) for ids in output_ids]


synonyms_generator = SynonymsGenerator(start_id=None,
                                       end_id=tokenizer._token_end_id,
                                       maxlen=maxlen)


def gen_synonyms(text, n=100, k=20):
    """"含义: 产生sent的n个相似句,然后返回最相似的k个。
    做法:用seq2seq生成,并用encoder算相似度并排序。
    """
    r = synonyms_generator.generate(text, n)
    r = [i for i in set(r) if i != text]
    r = [text] + r
    X, S = [], []
    for t in r:
        x, s = tokenizer.encode(t)
        X.append(x)
        S.append(s)
    X = sequence_padding(X)
    S = sequence_padding(S)
    Z = encoder.predict([X, S])
    Z /= (Z**2).sum(axis=1, keepdims=True)**0.5
    argsort = np.dot(Z[1:], -Z[0]).argsort()
    return [r[i + 1] for i in argsort[:k]]


"""
gen_synonyms(u'微信和支付宝哪个好?')
[
    u'微信和支付宝,哪个好?',
    u'微信和支付宝哪个好',
    u'支付宝和微信哪个好',
    u'支付宝和微信哪个好啊',
    u'微信和支付宝那个好用?',
    u'微信和支付宝哪个好用',
    u'支付宝和微信那个更好',
    u'支付宝和微信哪个好用',
    u'微信和支付宝用起来哪个好?',
    u'微信和支付宝选哪个好',
    u'微信好还是支付宝比较用',
    u'微信与支付宝哪个',
    u'支付宝和微信哪个好用一点?',
    u'支付宝好还是微信',
    u'微信支付宝究竟哪个好',
    u'支付宝和微信哪个实用性更好',
    u'好,支付宝和微信哪个更安全?',
    u'微信支付宝哪个好用?有什么区别',
    u'微信和支付宝有什么区别?谁比较好用',
    u'支付宝和微信哪个好玩'
]
 """

# print(gen_synonyms(u'微信和支付宝哪个好?'))
print("-----------------------------------")
print(gen_synonyms(u'apache-ywn-int部署在哪一台主机呢?', n=100, k=10))

2)目录结构

将下载的simbert预训练模型,放在项目中

(simbert_test) D:\tmp\20220508\simbert_base>tree /F
卷 新加卷 的文件夹 PATH 列表
卷序列号为 549E-27B0
D:.
│  simbert_base.py
│
└─bert
    │  chinese_simbert_L-12_H-768_A-12.zip
    │
    └─chinese_simbert_L-12_H-768_A-12
            bert_config.json
            bert_model.ckpt.data-00000-of-00001
            bert_model.ckpt.index
            checkpoint
            vocab.txt

3)执行脚本

python simbert_base.py
['apache-ywn-int的部署在哪一台主机上呢', 'apache-ywn-int部署在哪一台主机', 'apache-ywn-int部署在哪台主机', 'apache ywn-int部署在哪一个主机上', 'apache-ywn-int部署到哪一台主机', 'apache中ywn-int部署在哪个主机', 'apache的ywn-int在哪一台主机', '如何查看apache-ywn-int是否部署在哪个主机里', 'apache-ywn-int部署到哪个服务器上', 'apache ywn-int是怎么部署在哪一个服务器上']

有些输出并不一定准确,有一定的参考意义。

由于tensorflow的版本较低,会出现以下过期提醒信息,不影响运行

D:\Programs\Anaconda3\envs\simbert\lib\site-packages\tensorboard\compat\tensorflow_stub\dtypes.py:541: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.
_np_qint8 = np.dtype([("qint8", np.int8, 1)])

说明:性能并不高,如果要用于生产环境,还需要基于实际硬件设备进行验证。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容