專注於文本分類、關鍵詞抽取、文本摘要、FQA問答系統、對話系統語義理解NLU、知識圖譜等。結合工業界具體案例和學術界最新研究成果實現NLP技術場景落地。本文主要分析NER 在小規模數據集下BERT上快速驗證,關於完成的意圖識別和槽位抽取將在後續博客中總結分享。
博客:https://wenjie.blog.csdn.net/
作者:走在前方
更多精彩內容加入“NLP技術交流羣” 學習。
主要內容
-
任務描述介紹
- 領域意圖識別判斷
- 槽位填充
-
數據預處理
- 預料中有多種標籤,我們重點關注 singer,songer 標籤進行實驗
-
數據可視化處理
- 整體樣本統計
- 句子長度分析,提供模型輸入參數max_seq_len 設置多少合適
- 數據集標籤類別分佈,保證數據標籤式均衡的
- 針對數據可視化這裏採用pyecharts ,更加清晰效果非常好
-
模型訓練
- 這裏僅對槽位抽籤進行訓練(意圖部分後續考慮),典型NER任務
- 數據格式轉爲規定的標準格式就可以直接訓練了
-
在線服務測試
- 提供API Restfull 服務(小型業務python 即可,大型藉助C++,go…語言進行推測)
任務描述
對話系統是自然語言處理中一個重要的研究方向,也是人機交互的一種重要形式。其中,用戶話語(utterance)可以根據意圖的不同進一步分爲聊天、問答、命令等。對於任務完成式系統而言,能夠正確解析用戶命令是完成指定任務的基礎。因此,本任務主要關注口語對話系統中的命令理解問題。
音樂領域的命令理解分爲兩個子任務:
- 音樂領域意圖判斷;
- 音樂領域槽填充接下里
音樂領域意圖判斷
音樂領域意圖判斷的目標爲判斷用戶的某條話語(utterance)是否表達了一個音樂領域內的意圖。
音樂領域槽填充
用戶的某條話語(utterance)被標註爲音樂領域意圖後,爲了完成該意圖,需要將該話語中提及的相關參數提取出來,在此,話語中的相關參數被稱爲“槽”(slot)。比如說,在音樂領域中,最常見的槽是“歌手”和“歌曲”等。將相關參數識別出來的任務,稱爲槽填充。
數據預處理
訓練預料
標籤的示例數據:(這裏每個標籤給出3個數據進行slot抽取)
song=['大西安', '洛陽', '剎不住']
code=['no-music', 'random']
genre=['戲曲', '流行', '古典']
artist=['龍飄飄', '陳奕迅', '陳思思']
tag=['佛歌', '吉他曲', '流行']
lyrics=['東方紅太陽昇', '媽媽月光之下', '一閃一閃亮晶晶']
scene=['郊遊', '胎教', '春天的']
mood=['快樂', '開心', '悲傷']
language=['en', '閩南語', 'th']
album=['中國音樂', '遠方', '夜色鋼琴曲']
關於NER slot抽取我們選擇’artist’, ‘song’,其他TAG 我們填充‘O’(這個數據集比較小,大家也可以自己標註)。我們領域是音樂類,這裏artist變更singer,更容易理解
最終,我們訓練NER數據格式
這裏最終提取seq.in 和 seq.out 兩個文件作爲我們後續訓練NER 的輸入
數據可視化分析
分析query的長度分佈,爲bert超參max_seq_len 服務。我們這裏藉助 pyecharts 可視化工具來完成效果展示。
關於更多的pyecharts內容請參考
樣本數量分佈
樣本的數據量不是很多,我們選擇bert進行ner模型訓練,效果如何?(後續
句子長度可視化分析
我們的query句子的長度可以設置max_seq_len = 16即可。
更多seaborn 可視化操作可以參考
數據集標籤類別分佈
分別對train、dev、test數據進行標籤可視化展示分析
模型訓練
python3 main.py \
--model_name_or_path ../pretrained_models/bert-base-chinese/ \
--task ccks2018task2 \
--model_type bert \
--model_dir ccks2018task2_model \
--do_train --do_eval --use_crf \
--num_train_epochs 5 \
--train_batch_size 64 \
--eval_batch_size 64 \
--max_seq_len 16
下面我們截取訓練過程主要日誌數據,詳細分析主要內容。
- bert模型輸入,原始數據預處理過程
05/19/2020 13:38:20 - INFO - data_loader - guid: train-2
05/19/2020 13:38:20 - INFO - data_loader - tokens: [CLS] 我 要 聽 起 牀 好 。 [SEP]
05/19/2020 13:38:20 - INFO - data_loader - input_ids: 101 2769 6206 1420 6629 2414 1962 511 102 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - attention_mask: 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - token_type_ids: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - slot_labels: 0 2 2 2 5 6 6 2 0 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - *** Example ***
05/19/2020 13:38:20 - INFO - data_loader - guid: train-3
05/19/2020 13:38:20 - INFO - data_loader - tokens: [CLS] 搜 索 護 花 使 者 。 [SEP]
05/19/2020 13:38:20 - INFO - data_loader - input_ids: 101 3017 5164 2844 5709 886 5442 511 102 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - attention_mask: 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - token_type_ids: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
05/19/2020 13:38:20 - INFO - data_loader - slot_labels: 0 2 2 5 6 6 6 2 0 0 0 0 0 0 0 0
- 驗證數據集效果
數據量比較小,在進行第2個epoch就已經獲得最後的模型了
05/19/2020 13:38:57 - INFO - train - precision recall f1-score support
song 0.89 0.93 0.91 461
singer 0.85 0.89 0.87 106
micro avg 0.88 0.92 0.90 567
macro avg 0.88 0.92 0.90 567
05/19/2020 13:38:57 - INFO - train - loss = 1.059001863002777
05/19/2020 13:38:57 - INFO - train - sementic_frame_acc = 0.900952380952381
05/19/2020 13:38:57 - INFO - train - slot_f1 = 0.8990509059534082
05/19/2020 13:38:57 - INFO - train - slot_precision = 0.8800675675675675
05/19/2020 13:38:57 - INFO - train - slot_recall = 0.9188712522045855
- 測試數據集效果
05/19/2020 13:39:18 - INFO - train - precision recall f1-score support
song 0.89 0.91 0.90 467
singer 0.91 0.94 0.93 106
micro avg 0.90 0.92 0.91 573
macro avg 0.90 0.92 0.91 573
05/19/2020 13:39:18 - INFO - train - loss = 1.171002409938309
05/19/2020 13:39:18 - INFO - train - sementic_frame_acc = 0.8954372623574145
05/19/2020 13:39:18 - INFO - train - slot_f1 = 0.9059534081104401
05/19/2020 13:39:18 - INFO - train - slot_precision = 0.8959044368600683
05/19/2020 13:39:18 - INFO - train - slot_recall = 0.9162303664921466
在線服務預測
- 通過api.py 啓動服務
python3 api.py \
--model_name_or_path ../pretrained_models/bert-base-chinese/ \
--task ccks2018task2 \
--model_type bert \
--model_dir ccks2018task2_model \
--use_crf
- 通過命令行模式在線預測(也可以postman測試)
這裏/predict/ 就是提取在線服務的一個接口。
我們發現雖然數據比較小,但是效果還不錯。隨着我們數據的不斷增加,可以再次訓練我們的模型,提升我們的效果。在gpu下推理大概13ms。(也可以嘗試cpu下,效果上會慢些)。
關於性能推理是工業界追求的一個目標,有的時候爲了保證線上推理速度,寧願希望模型微小的效果,也要保證性能。
$ curl http://0.0.0.0:8000/predict \
> -H "Content-Type:application/json" \
> -X POST \
> --data '{"text": "播放一首周杰倫東風破","lang":"zh"}'
{
"errno": 0,
"errmsg": "success",
"time": 13,
"data": [
{
"word": "播",
"tag": "O"
},
{
"word": "放",
"tag": "O"
},
{
"word": "一",
"tag": "O"
},
{
"word": "首",
"tag": "O"
},
{
"word": "周",
"tag": "B-singer"
},
{
"word": "傑",
"tag": "I-singer"
},
{
"word": "倫",
"tag": "I-singer"
},
{
"word": "東",
"tag": "B-song"
},
{
"word": "風",
"tag": "I-song"
},
{
"word": "破",
"tag": "I-song"
}
]
}
- 後端日誌數據
附錄-擴展部分
大家可以嘗試下面的方案,自己進行探索,這裏不在進行詳細的描述
- 規則方式抽取實體
規則方式抽取實體,是一種精確的匹配方式。對模型訓練數據不足
- 訓練數據擴充
自己標註或者從nlp相關的比賽獲取數據