使用simBert生成同義語句(全過程)

一、simbert介紹和下載

simbert模型端铛,是由蘇劍林開發(fā)的模型尉剩,以Google開源的BERT模型為基礎(chǔ)间坐,基于微軟的UniLM思想設(shè)計了融檢索與生成于一體的任務(wù),來進(jìn)一步微調(diào)后得到的模型少孝,所以它同時具備相似問生成和相似句檢索能力继低。

SimBERT屬于有監(jiān)督訓(xùn)練,訓(xùn)練語料是自行收集到的相似句對稍走,通過一句來預(yù)測另一句的相似句生成任務(wù)來構(gòu)建Seq2Seq部分袁翁,然后前面也提到過[CLS]的向量事實上就代表著輸入的句向量,所以可以同時用它來訓(xùn)練一個檢索任務(wù)婿脸。

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

項目介紹https://kexue.fm/archives/7427

已預(yù)訓(xùn)練的模型包含 Tiny(26M)粱胜、Small(49M)、Base(344M)三個模型狐树。

下載:

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

Tiny下載路徑焙压、Small下載路徑Base下載路徑

適合創(chuàng)建相似文本集

>>> gen_synonyms(u'微信和支付寶哪個好抑钟?')
[
    u'微信和支付寶涯曲,哪個好?',
    u'微信和支付寶哪個好',
    u'支付寶和微信哪個好',
    u'支付寶和微信哪個好啊',
    u'微信和支付寶那個好用?',
    u'微信和支付寶哪個好用',
    u'支付寶和微信那個更好',
    u'支付寶和微信哪個好用',
    u'微信和支付寶用起來哪個好味赃?',
    ...........
]

二掀抹、項目使用

2.1 創(chuàng)建conda 環(huán)境

1)查看虛擬環(huán)境

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

2)創(chuàng)建虛擬環(huán)境

(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進(jìn)行測試驗證

1)下載測試代碼

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

#! -*- coding: utf-8 -*-
# SimBERT base 基本例子
# 測試環(huán)境: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):
    """"含義: 產(chǎn)生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'微信支付寶哪個好用绍撞?有什么區(qū)別',
    u'微信和支付寶有什么區(qū)別正勒?誰比較好用',
    u'支付寶和微信哪個好玩'
]
 """

# print(gen_synonyms(u'微信和支付寶哪個好?'))
print("-----------------------------------")
print(gen_synonyms(u'apache-ywn-int部署在哪一臺主機呢傻铣?', n=100, k=10))

2)目錄結(jié)構(gòu)

將下載的simbert預(yù)訓(xùn)練模型章贞,放在項目中

(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)執(zhí)行腳本

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部署到哪個服務(wù)器上', 'apache ywn-int是怎么部署在哪一個服務(wù)器上']

有些輸出并不一定準(zhǔn)確,有一定的參考意義非洲。

由于tensorflow的版本較低鸭限,會出現(xiàn)以下過期提醒信息蜕径,不影響運行

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)])

說明:性能并不高,如果要用于生產(chǎn)環(huán)境败京,還需要基于實際硬件設(shè)備進(jìn)行驗證兜喻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喧枷,隨后出現(xiàn)的幾起案子虹统,更是在濱河造成了極大的恐慌,老刑警劉巖隧甚,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件车荔,死亡現(xiàn)場離奇詭異,居然都是意外死亡戚扳,警方通過查閱死者的電腦和手機忧便,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帽借,“玉大人珠增,你說我怎么就攤上這事】嘲” “怎么了蒂教?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脆荷。 經(jīng)常有香客問我凝垛,道長,這世上最難降的妖魔是什么蜓谋? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任梦皮,我火速辦了婚禮,結(jié)果婚禮上桃焕,老公的妹妹穿的比我還像新娘剑肯。我一直安慰自己,他們只是感情好观堂,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布让网。 她就那樣靜靜地躺著,像睡著了一般师痕。 火紅的嫁衣襯著肌膚如雪溃睹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天七兜,我揣著相機與錄音丸凭,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛惜犀,可吹牛的內(nèi)容都是我干的铛碑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虽界,長吁一口氣:“原來是場噩夢啊……” “哼汽烦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起莉御,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤撇吞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后礁叔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牍颈,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年琅关,在試婚紗的時候發(fā)現(xiàn)自己被綠了煮岁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡涣易,死狀恐怖画机,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情新症,我是刑警寧澤步氏,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站徒爹,受9級特大地震影響荚醒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瀑焦,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一腌且、第九天 我趴在偏房一處隱蔽的房頂上張望梗肝。 院中可真熱鬧榛瓮,春花似錦、人聲如沸巫击。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坝锰。三九已至粹懒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間顷级,已是汗流浹背凫乖。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人帽芽。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓删掀,卻偏偏與公主長得像,于是被迫代替她去往敵國和親导街。 傳聞我的和親對象是個殘疾皇子披泪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容