1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        NLP(三十九)使用keras-bert實(shí)現(xiàn)完形填空及簡(jiǎn)單的文本糾錯(cuò)功能

        共 4588字,需瀏覽 10分鐘

         ·

        2021-01-26 16:02

        ??在之前的系列文章中,筆者介紹了如何使用keras-bert來(lái)調(diào)用BERT模型,實(shí)現(xiàn)文本多分類,文本多標(biāo)簽分類以及序列標(biāo)注任務(wù),文章如下:

        在本文中,筆者將介紹如何使用keras-bert來(lái)調(diào)用BERT模型使用完形填空及簡(jiǎn)單的文本糾錯(cuò)功能。

        完形填空

        ??首先,我們來(lái)了解下什么是完形填空。所謂完形填空,指的是將句子中缺失的單詞(或字)補(bǔ)充成正確的單詞(或字)。舉個(gè)簡(jiǎn)單的例子:

        完形填空的例子

        在上圖中,第一行是原始句子,第二行是需要完形填空的句子,在這里我們把閔行區(qū)的行字缺失掉,即MASK掉,第三行為補(bǔ)充的漢字:行。
        ??在BERT模型中,它的任務(wù)是由兩個(gè)自監(jiān)督任務(wù)組成,即MLM和NSP。我們需要了解下MLM。
        ??MLM的全稱是Masked Language Model,所謂MLM是指在訓(xùn)練的時(shí)候隨即從輸入語(yǔ)料上mask掉一些單詞,然后通過(guò)的上下文預(yù)測(cè)該單詞,該任務(wù)非常像我們?cè)谥袑W(xué)時(shí)期經(jīng)常做的完形填空。
        ??在BERT的實(shí)驗(yàn)中,15%的WordPiece Token會(huì)被隨機(jī)Mask掉。在訓(xùn)練模型時(shí),一個(gè)句子會(huì)被多次喂到模型中用于參數(shù)學(xué)習(xí),但是Google并沒(méi)有在每次都mask掉這些單詞,而是在確定要Mask掉的單詞之后,80%的時(shí)候會(huì)直接替換為[Mask],10%的時(shí)候?qū)⑵涮鎿Q為其它任意單詞,10%的時(shí)候會(huì)保留原始Token。
        ??基于BERT模型的這個(gè)特性,我們嘗試著利用keras-bert來(lái)調(diào)用它解決完形填空問(wèn)題。實(shí)現(xiàn)完形填空的代碼(cloze_predict.py)如下:

        #?-*-?coding:?utf-8?-*-
        import?numpy?as?np
        from?keras_bert?import?Tokenizer
        from?keras_bert?import?load_trained_model_from_checkpoint

        #?加載詞典
        dict_path?=?'./chinese_L-12_H-768_A-12/vocab.txt'
        token_dict?=?{}
        with?open(dict_path,?'r',?encoding='utf-8')?as?reader:
        ????for?line?in?reader:
        ????????token?=?line.strip()
        ????????token_dict[token]?=?len(token_dict)

        id_token_dict?=?{v:?k?for?k,?v?in?token_dict.items()}


        class?OurTokenizer(Tokenizer):
        ????def?_tokenize(self,?text):
        ????????R?=?[]
        ????????for?c?in?text:
        ????????????if?c?in?self._token_dict:
        ????????????????R.append(c)
        ????????????else:
        ????????????????R.append('[UNK]')
        ????????return?R


        tokenizer?=?OurTokenizer(token_dict)

        #?加載模型
        model_path?=?"./chinese_L-12_H-768_A-12/"
        bert_model?=?load_trained_model_from_checkpoint(
        ????model_path?+?"bert_config.json",
        ????model_path?+?"bert_model.ckpt",
        ????training=True
        )
        #?bert_model.summary()


        #?完形填空,預(yù)測(cè)MASK的字符
        def?get_mask_character(start_string,?mask_num,?end_string):
        ????string?=?list(start_string)?+?['MASK']?*?mask_num?+?list(end_string)
        ????token_ids,?segment_ids?=?tokenizer.encode(string,?max_len=512)
        ????for?i?in?range(mask_num):
        ????????token_ids[len(start_string)+i+1]?=?tokenizer._token_dict['[MASK]']

        ????#?mask
        ????masks?=?[0]?*?512
        ????for?i?in?range(mask_num):
        ????????masks[len(start_string)+i+1]?=?1

        ????#?模型預(yù)測(cè)被mask掉的部分
        ????predicts?=?bert_model.predict([np.array([token_ids]),?np.array([segment_ids]),?np.array([masks])])[0]
        ????pred_indice?=?predicts[0][len(start_string)+1:len(start_string)+mask_num+1].argmax(axis=1).tolist()
        ????return?[id_token_dict[_]?for?_?in?pred_indice]


        if?__name__?==?'__main__':
        ????#?原句1:?白云山,位于廣東省廣州市白云區(qū),為南粵名山之一,自古就有“羊城第一秀”之稱。
        ????start_str1?=?"白云山,位于"
        ????end_str1?=?"廣州市白云區(qū),為南粵名山之一,自古就有“羊城第一秀”之稱。"
        ????pred_chars?=?get_mask_character(start_str1,?3,?end_str1)
        ????print(pred_chars)

        ????#?原句2:首先,從市值看,騰訊和阿里市值已經(jīng)有2500億,而百度才500多億,是BAT體量中最小的一家公司。
        ????start_str2?=?"首先,從"
        ????end_str2?=?"看,騰訊和阿里市值已經(jīng)有2500億,而百度才500多億,是BAT體量中最小的一家公司。"
        ????pred_chars?=?get_mask_character(start_str2,?2,?end_str2)
        ????print(pred_chars)

        ????#?原句3:特斯拉CEO埃隆·馬斯克的個(gè)人凈資產(chǎn)升至1850億美元,超越亞馬遜CEO貝索斯榮登全球第一大富豪。
        ????start_str3?=?"特斯拉CEO埃隆·馬斯克的個(gè)人凈資產(chǎn)升至1850億美元,超越亞馬遜CEO貝索斯榮登"
        ????end_str3?=?"第一大富豪。"
        ????pred_chars?=?get_mask_character(start_str3,?2,?end_str3)
        ????print(pred_chars)

        ????#?原句4:我在上海閔行區(qū)工作。
        ????start_str4?=?"我在上海閔"
        ????end_str4?=?"區(qū)工作。"
        ????pred_chars?=?get_mask_character(start_str4,?1,?end_str4)
        ????print(pred_chars)

        注意keras-bert來(lái)調(diào)用BERT時(shí),如果需要開(kāi)啟MLM和NSP任務(wù)時(shí),需要將training設(shè)置為True,然后再調(diào)用MLM模型對(duì)文本中MASK掉的部分進(jìn)行預(yù)測(cè)。運(yùn)行腳本的輸出結(jié)果如下:

        ['廣',?'東',?'省']
        ['市',?'值']
        ['全',?'球']
        ['行']

        簡(jiǎn)單的文本糾錯(cuò)功能

        ??基于上述的完形填空,我們還可以完成簡(jiǎn)單的文本糾錯(cuò)功能,前提是我們已經(jīng)知道文本的哪個(gè)字是錯(cuò)誤的,并且進(jìn)行一對(duì)一糾錯(cuò),即把這個(gè)字糾正為正確的字,并不會(huì)將其去掉或者添加其它字。我們的思路是這樣的:在知道文本中的哪個(gè)字是錯(cuò)誤的之后,將其MASK掉,轉(zhuǎn)化為完形填空任務(wù),從而預(yù)測(cè)出MASK掉的字作為糾正后的字。
        ??實(shí)現(xiàn)簡(jiǎn)單的文本糾錯(cuò)功能的Python代碼如下:

        #?-*-?coding:?utf-8?-*-
        #?該腳本使用BERT的mask技術(shù)進(jìn)行文本糾錯(cuò)
        from?cloze_predict?import?get_mask_character

        sentence?=?"我要去埃及金子塔玩。"??#?金子塔中的子為錯(cuò)別字
        sentence?=?"白云山,位于廣東省廣州市白云區(qū),為南粵名山之一,自古就有“羊城第一秀”只稱。"??#?只稱中的只為錯(cuò)別字
        sentence?=?"請(qǐng)把這個(gè)快遞送到上海市閔航區(qū)。"??#?閔航區(qū)中的航為錯(cuò)別字
        sentence?=?"少先隊(duì)員因該為老人讓坐"??#?因該中的因?yàn)殄e(cuò)別字
        sentence?=?"隨然今天很熱"??#?隨然中的隨為錯(cuò)別字
        sentence?=?"我生病了,咳數(shù)了好幾天"??#?咳數(shù)中的數(shù)為錯(cuò)別字
        sentence?=?"一群羅威納犬寶寶打架,場(chǎng)面感忍。"??#?感忍中的忍為錯(cuò)別字
        wrong_char_index?=?sentence.index("忍")

        for?i?in?range(len(sentence)):
        ????if?i?==?wrong_char_index:
        ????????start_string?=?sentence[:i]
        ????????end_string?=?sentence[i+1:]
        ????????pred_char?=?get_mask_character(start_string,?1,?end_string)
        ????????print("wrong?char:?{},?correct?char:?{}".format(sentence[i],?pred_char[0]))

        輸出結(jié)果為:

        wrong?char:?忍,?correct?char:?人

        ??這種文本糾錯(cuò)方式利用了BERT的MLM模型來(lái)實(shí)現(xiàn)的,有一定的效果,但不能作為文本糾錯(cuò)的完美實(shí)現(xiàn)方式,只是作為文本糾錯(cuò)的一種實(shí)現(xiàn)方式,實(shí)際上,現(xiàn)實(shí)中的文本糾錯(cuò)是由多種模型組成的復(fù)雜策略實(shí)現(xiàn)的,還得考慮效果和運(yùn)行效率等因素。另外,真正的文本糾錯(cuò)還應(yīng)當(dāng)能指出文本中哪個(gè)字錯(cuò)了并對(duì)其糾錯(cuò),本文只考慮了后一步,而沒(méi)有指出文本中哪個(gè)字錯(cuò)了,只能算文本糾錯(cuò)的一次嘗試。

        總結(jié)

        ??本文給出的腳本已上傳至Github,網(wǎng)址為:https://github.com/percent4/keras_bert_cloze ,上面有更多的例子,歡迎大家參考~
        ??感謝大家的閱讀~
        ??2021.1.24于上海浦東


        瀏覽 67
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            天天日天天撸 | 善交bbw搡bbbb搡bbbb | 欧美特黄一级片 | 曰本手机在线 | 成人免费一级A片视频蜜臀 | 欧美黄色成人片 | 麻酥酥在线观看 | 国产精品日韩无码有码 | 美国一级黄色 | 亚洲综合第一 |