天天看點

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)前言一、優化進階-使用預訓練的詞向量優化模型效果二、概念解釋總結

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)

作者簡介:在校大學生一枚,華為雲享專家,阿裡雲專家部落客,騰雲先鋒(TDP)成員,雲曦智劃項目總負責人,全國高等學校計算機教學與産業實踐資源建設專家委員會(TIPCC)志願者,以及程式設計愛好者,期待和大家一起學習,一起進步~

.

部落格首頁:ぃ靈彧が的學習日志

.

本文專欄:機器學習

.

專欄寄語:若你決定燦爛,山無遮,海無攔

.

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)前言一、優化進階-使用預訓練的詞向量優化模型效果二、概念解釋總結

(文章目錄)

前言

(一)、任務描述

命名實體識别任務主要識别文本中的實體,并且給識别出的實體進行分類,比如人名、地名、機構名或其它類型。本質上,對于給定的文本,隻需要對其中的每個單詞進行分類,隻不過需要對分類的标簽進行重新定義。

(二)、環境配置

本示例基于飛槳開源架構2.0版本。

import paddle
import numpy as np
import matplotlib.pyplot as plt
print(paddle.__version__)
           

輸出結果如下圖1所示:

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)前言一、優化進階-使用預訓練的詞向量優化模型效果二、概念解釋總結

一、優化進階-使用預訓練的詞向量優化模型效果

在Baseline版本中,我們調用了

paddle.nn.Embedding

擷取詞的向量表示。這裡,我們調用

paddlenlp.embeddings

中内置的向量表示

TokenEmbedding

(一)、導入相關包

from paddlenlp.embeddings import TokenEmbedding # EMB

del model
del preds
del network
           

(二)、定義BiGRUWithCRF2

class BiGRUWithCRF2(nn.Layer):
    def __init__(self,
                 emb_size,
                 hidden_size,
                 word_num,
                 label_num,
                 use_w2v_emb=True):
        super(BiGRUWithCRF2, self).__init__()
        if use_w2v_emb:
            self.word_emb = TokenEmbedding(
                extended_vocab_path='./data/word.dic', unknown_token='OOV')
        else:
            self.word_emb = nn.Embedding(word_num, emb_size)
        self.gru = nn.GRU(emb_size,
                          hidden_size,
                          num_layers=2,
                          direction='bidirectional')
        self.fc = nn.Linear(hidden_size * 2, label_num + 2)  # BOS EOS
        self.crf = LinearChainCrf(label_num)
        self.decoder = ViterbiDecoder(self.crf.transitions)

    def forward(self, x, lens):
        embs = self.word_emb(x)
        output, _ = self.gru(embs)
        output = self.fc(output)
        _, pred = self.decoder(output, lens)
        return output, lens, pred
           

(三)、模型建構

network = BiGRUWithCRF2(300, 300, len(word_vocab), len(label_vocab))
model = paddle.Model(network)
optimizer = paddle.optimizer.Adam(learning_rate=0.001, parameters=model.parameters())
crf_loss = LinearChainCrfLoss(network.crf)
chunk_evaluator = ChunkEvaluator(label_list=label_vocab.keys(), suffix=True)
model.prepare(optimizer, crf_loss, chunk_evaluator)
           
model.fit(train_data=train_loader,
            eval_data=dev_loader,
            epochs=10,
            save_dir='./results',
            log_freq=1)
           
model.evaluate(eval_data=test_loader)

           

(四)、模型驗證

outputs, lens, decodes = model.predict(test_data=test_loader)
preds = parse_decodes(test_ds, decodes, lens, label_vocab)

print('\n'.join(preds[:5]))
           

二、概念解釋

(一)、門控循環單元GRU

BIGRU是一種經典的循環神經網絡(RNN,Recurrent Neural Network),前面一些步驟基本是把該模型當做是黑盒子來用,這裡我們重點解釋下其概念和相關原理。一個 RNN 的示意圖如下所示:

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)前言一、優化進階-使用預訓練的詞向量優化模型效果二、概念解釋總結

左邊是原始的 RNN,可以看到綠色的點代碼輸入 x,紅色的點代表輸出 y,中間的藍色是 RNN 模型部分。橙色的箭頭由自身指向自身,表示 RNN 的輸入來自于上時刻的輸出,這也是為什麼名字中帶有循環(Recurrent)這個詞。

右邊是按照時間序列展開的示意圖,注意到藍色的 RNN 子產品是同一個,隻不過在不同的時刻複用了。這時候能夠清晰地表示序列标注模型的輸入輸出。

GRU為了解決長期記憶和反向傳播中梯度問題而提出來的,和LSTM一樣能夠有效對長序列模組化,且GRU訓練效率更高。

(二)、條件随機場CRF

長句子的問題解決了,序列标注任務的另外一個問題也亟待解決,即标簽之間的依賴性。舉個例子,我們預測的标簽一般不會出現 P-B,T-I 并列的情況,因為這樣的标簽不合理,也無法解析。無論是 RNN 還是 LSTM 都隻能盡量不出現,卻無法從原理上避免這個問題。下面要提到的條件随機場(CRF,Conditional Random Field)卻很好的解決了這個問題。

條件随機場這個模型屬于機率圖模型中的無向圖模型,這裡我們不做展開,隻直覺解釋下該模型背後考量的思想。一個經典的鍊式 CRF 如下圖所示,

【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)【自然語言處理(NLP)】基于LSTM的命名實體識别(進階)前言一、優化進階-使用預訓練的詞向量優化模型效果二、概念解釋總結

CRF 本質是一個無向圖,其中綠色點表示輸入,紅色點表示輸出。點與點之間的邊可以分成兩類,一類是 $x$ 與 $y$ 之間的連線,表示其相關性;另一類是相鄰時刻的 $y$ 之間的相關性。也就是說,在預測某時刻 $y$ 時,同時要考慮相鄰的标簽解決。當 CRF 模型收斂時,就會學到類似 P-B 和 T-I 作為相鄰标簽的機率非常低。

總結

本系列文章内容為根據清華社出版的《自然語言處理實踐》所作的相關筆記和感悟,其中代碼均為基于百度飛槳開發,若有任何侵權和不妥之處,請私信于我,定積極配合處理,看到必回!!!

繼續閱讀