“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+

汀、人工智慧發表於2023-05-19

“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+

相關文章推薦:

本專案主要完成基於UTC的多標籤應用,更多部署細節請參考推薦文章。本專案提供了小樣本場景下文字多標籤分類的解決方案,在 UTC的基礎上利用提示學習取得比微調更好的分類效果,充分利用標註資訊。

專案以及碼源見文末


  • 專案背景:

近年來,大量包含了案件事實及其適用法律條文資訊的裁判文書逐漸在網際網路上公開,海量的資料使自然語言處理技術的應用成為可能。現實中的案情錯綜複雜,案情描述通常涉及多個重要事實,以CAIL2019資料集中婚姻家庭領域的案情要素抽取為例:

"2013年11月28日原、被告離婚時自願達成協議,婚生子張某乙由被告李某某撫養,本院以(2013)寶渭法民初字第01848號民事調解書對該協議內容予以了確認,該協議具有法律效力,對原、被告雙方均有約束力。"

該案件中涉及婚後有子女、限制行為能力子女撫養兩項要素。接下來我們將講解在小樣本場景下如何利用多標籤模型,對輸入文字中進行案情重要要素抽取。

應用部署介面展示

1.UTC(Universal Text Classification介紹

本專案提供基於通用文字分類 UTC(Universal Text Classification) 模型微調的文字分類端到端應用方案,打通資料標註-模型訓練-模型調優-預測部署全流程,可快速實現文字分類產品落地。

文字分類是一種重要的自然語言處理任務,它可以幫助我們將大量的文字資料進行有效的分類和歸納。實際上,在日常生活中,我們也經常會用到文字分類技術。例如,我們可以使用文字分類來對新聞報導進行分類,對電子郵件進行分類,對社交媒體上的評論進行情感分析等等。但是,文字分類也面臨著許多挑戰。其中最重要的挑戰之一是資料稀缺。由於文字資料往往非常龐大,因此獲取足夠的訓練資料可能非常困難。此外,不同的文字分類任務也可能面臨著領域多變和任務多樣等挑戰。為了應對這些挑戰,PaddleNLP推出了一項零樣本文字分類應用UTC。該應用透過統一語義匹配方式USM(Unified Semantic Matching)來將標籤和文字的語義匹配能力進行統一建模。這種方法可以幫助我們更好地理解文字資料,並從中提取出有用的特徵資訊。

UTC具有低資源遷移能力,可以支援通用分類、評論情感分析、語義相似度計算、蘊含推理、多項式閱讀理解等多種“泛分類”任務。這使得開發者可以更加輕鬆高效地實現多工文字分類資料標註、訓練、調優和上線,從而降低文字分類技術門檻。

總之,文字分類是一項重要的自然語言處理任務,它可以幫助我們更好地理解和歸納文字資料。儘管它面臨著許多挑戰,但是透過使用PaddleNLP的零樣本文字分類應用UTC,開發者們可以簡單高效實現多工文字分類資料標註、訓練、調優、上線,降低文字分類落地技術門檻。

1.1 分類落地面臨難度

分類任務看似簡單,然而在產業級文字分類落地實踐中,面臨著諸多挑戰:

  • 任務多樣:單標籤、多標籤、層次標籤、大規模標籤等不同的文字分類任務,需要開發不同的分類模型,模型架構往往特化於具體任務,難以使用統一形式建模;

  • 資料稀缺:部分領域資料稀缺,難以獲取,且領域專業性使得資料標註門檻高;

  • 標籤遷移:不同領域的標籤多樣,並且遷移難度大,尤其不同領域間的標籤知識很難遷移。

1.2 UTC亮點

1.2.1 多工統一建模

在傳統技術方案中,針對不同的分類任務需要構建多個分類模型,模型需單獨訓練且資料和知識不共享。而在UTC方案下,單個模型能解決所有分類需求,包括但不限於單標籤分類、多標籤分類、層次標籤分類、大規模事件標籤檢測、蘊含推理、語義相似度計算等,降低了開發成本和機器成本。

UTC模型結構圖

1.2.2 零樣本分類和小樣本遷移能力強

UTC透過大規模多工預訓練後,可以適配不同的行業領域,不同的分類標籤,僅標註了幾條樣本,分類效果就取得大幅提升,大大降低標註門檻和成本。

UTC模型結構圖

在醫療、金融、法律等領域中,無需訓練資料的零樣本情況下UTC效果平均可達到70%+(如下表所示),標註少樣本也可帶來顯著的效果提升:每個標籤僅僅標註1條樣本後,平均提升了10個點!也就是說,即使在某些場景下表現欠佳,人工標幾個樣本,丟給模型後就會有大幅的效果提升。

1.3 UTC技術思路

UTC基於百度最新提出的統一語義匹配框架USM(Unified Semantic Matching)[1],將分類任務統一建模為標籤與文字之間的匹配任務,對不同標籤的分類任務進行統一建模。具體地說:

  1. 為了實現任務架構統一,UTC設計了標籤與文字之間的詞對連線操作(Label–>CLS-Token Linking),這使得模型能夠適應不同領域和任務的標籤資訊,並按需求進行分類,從而實現了開放域場景下的通用文字分類。
    例如,對於事件檢測任務,可將一系列事件標籤拼接為[L]上映[L]奪冠[L]下架 ,然後與原文字一起作為整體輸入到UTC中,UTC將不同標籤識別符號[L]與[CLS]進行匹配,可對不同標籤型別的分類任務統一建模,直接上圖:
UTC模型結構圖
  1. 為了實現通用能力共享,讓不同領域間的標籤知識跨域遷移,UTC構建了統一的異質監督學習方法進行多工預訓練,使不同領域任務具備良好的零/少樣本遷移效能。統一的異質監督學習方法主要包括三種不同的監督訊號:
    • 直接監督:分類任務直接相關的資料集,如情感分類、新聞分類、意圖識別等。
    • 間接監督:分類任務間接相關的資料集,如選項式閱讀理解、問題-文章匹配等。
    • 遠端監督:標籤知識庫或層級標題與文字對齊後弱標註資料。

更多內容參考論文見文末連結 or fork一下專案論文已上傳

2.文字分類任務Label Studio教程

2.1 Label Studio安裝

以下標註示例用到的環境配置:

  • Python 3.8+
  • label-studio == 1.7.2

在終端(terminal)使用pip安裝label-studio:

pip install label-studio==1.7.2

安裝完成後,執行以下命令列:

label-studio start

在瀏覽器開啟http://localhost:8080/,輸入使用者名稱和密碼登入,開始使用label-studio進行標註。

2.2 文字分類任務標註

  • 2.2.1 專案建立

點選建立(Create)開始建立一個新的專案,填寫專案名稱、描述,然後在Labeling Setup中選擇Text Classification

  • 填寫專案名稱、描述
“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
  • 資料上傳,從本地上傳txt格式檔案,選擇List of tasks,然後選擇匯入本專案
“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
  • 設定任務,新增標籤
“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
  • 資料上傳

專案建立後,可在Project/文字分類任務中點選Import繼續匯入資料,同樣從本地上傳txt格式檔案,選擇List of tasks

  • 2.2.2 標籤構建

專案建立後,可在Setting/Labeling Interface中繼續配置標籤,

預設模式為單標籤多分類資料標註。對於多標籤多分類資料標註,需要將choice的值由single改為multiple

“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
  • 2.2.3 任務標註
“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+
  • 2.2.4 資料匯出

勾選已標註文字ID,選擇匯出的檔案型別為JSON,匯出資料:

“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+

參考連結:

3.多標籤/層次分類資料轉換

這裡我們使用CAIL2019“中國法研杯”司法人工智慧挑戰賽—婚姻家庭要素提取任務資料集的子集作為示例資料集。該資料集中原始訓練集包括 14377 條標註樣本,我們按每條標籤隨機取樣 4 條樣本,得到 80 條樣本資料作為訓練集,剩餘訓練集資料作為測試集。

3.1 多標籤源資料格式

data/
├── train.txt  # 訓練資料集
├── dev.txt    # 驗證資料集
├── test.txt   # 測試資料集(可選)
├── data.txt   # 待預測資料(可選)
└── label.txt  # 分類標籤集

  • 訓練/驗證/測試資料

對於訓練/驗證/測試資料集檔案,每行資料表示一條樣本,包括文字和標籤兩部分,由tab符\t分隔,多個標籤以英文逗號,分隔。格式如下

<文字>'\t'<標籤>','<標籤>','<標籤>
<文字>'\t'<標籤>','<標籤>

資料集展示

本院認為,涉案房屋系2012年12月4日原、被告婚姻關係存續期間購買,且涉案樓房的產權登記在原、被告名下,依據法律規定,夫妻在婚姻關係存續期間所得的財產,歸夫妻共同所有;	不動產分割,有夫妻共同財產
原、被告之間的共同財產應依法分割。	有夫妻共同財產
協議不成時,由人民法院判決”的規定,由於被告後期治療還需大量費用,原告應給與原告必要的經濟幫助。	適當幫助
故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養費。	婚後有子女,支付撫養費,限制行為能力子女撫養
2014年12月22日,原告訴至本院,要求與被告離婚,後本院判決不準予原、被告離婚。	二次起訴離婚
男到女家生活,2006年12月婚生一女,取名張某甲。	婚後有子女
  • 預測資料

對於待預測資料檔案,每行包含一條待預測樣本,無標籤。格式如下

<文字>
<文字>

資料集展示

五松新村房屋是被告婚前購買的;
被告於2016年3月將車牌號為皖B×××××出售了2.7萬元,被告透過原告償還了齊荷花人民幣2.6萬元,原、被告尚欠齊荷花2萬元。
2、判令被告返還借婚姻索取的現金33萬元,婚前個人存款10萬元;
一、判決原告於某某與被告楊某某離婚;
  • 標籤資料

對於分類標籤集檔案,儲存了資料集中所有的標籤集合,每行為一個標籤名。如果需要自定義標籤對映用於分類器初始化,則每行需要包括標籤名和相應的對映詞,由==分隔。格式如下

<標籤>'=='<對映詞>
<標籤>'=='<對映詞>

例如,對於婚姻家庭要素提取資料集,原標籤字數較多,因此同一個標籤依賴的輸出也多。為了降低訓練難度,我們可以將其對映為較短的短語

有夫妻共同債務==共同債務
存在非婚生子==非婚生子
...

Note: 這裡的標籤對映詞定義遵循的規則是,不同對映詞儘可能長度一致,對映詞和提示需要儘可能構成通順的語句。越接近自然語句,小樣本下模型訓練效果越好。如果原標籤名已經可以構成通順語句,也可以不構造對映詞,每行一個標籤即可,即

3.2層次分類源資料格式

  • 訓練/驗證/測試資料
    對於訓練/驗證/測試資料集檔案,每行資料表示一條樣本,包括文字和標籤兩部分,由tab符\t分隔,多個標籤以英文逗號,分隔,同一標籤內不同層級以##字元連線。格式如下
<文字>'\t'<標籤>','<標籤>','<標籤>
<文字>'\t'<標籤>','<標籤>
...

紫光聖果副總經理李明雷辭職  組織關係,組織關係##辭/離職
無理取鬧辱罵扶貧幹部織金一居民被行拘    司法行為,司法行為##拘捕
...
  • 標籤資料

對於分類標籤集檔案,儲存了資料集中所有的標籤路徑集合,每行是一個標籤路徑,高層的標籤指向底層標籤,不同層級的標籤用'##'連線,本專案選擇為標籤層次結構中的每一個節點生成對應的標籤路徑,詳見層次分類任務介紹,標籤路徑格式如下

<一級標籤>
<一級標籤>'##'<二級標籤>
<一級標籤>'##'<二級標籤>'##'<三級標籤>
...

如果需要自定義標籤對映用於分類器初始化,則每行需要包括標籤名和相應的對映詞,由==分隔。格式如下

<一級標籤>'=='<對映詞>
<一級標籤>'##'<二級標籤>'=='<對映詞>
<一級標籤>'##'<二級標籤>'##'<三級標籤>'=='<對映詞>
...

例如,原標籤路徑交往##會見中包括特殊符號##,大機率不會在說話或者寫作中使用,因此我們將其對映為會見或者見面。
交往==交往
交往##會見==會見
...


3.3 轉換後格式

三種分類都可以在 UTC 框架下實現,其中 multi-class 2.5版本需要修改評估程式碼。multi-label: UTC 預設是 multi-label 形式。

#多分類資料示例
{"text_a": "、月經期間刮痧拔罐會引起身體什麼", "text_b": "", "question": "", "choices": ["病情診斷", "治療方案", "病因分析", "指標解讀", "就醫建議", "疾病表述", "後果表述", "注意事項", "功效作用", "醫療費用", "其他"], "labels": [5]}
#多標籤資料示例
{"text_a": "多標籤分類示例","text_b": "", "question": "","choices": ["體育", "時政", "娛樂", "電影"], "labels": [2, 3]}

hierachical: applications/text_classification/*/few-shot 目錄下 hierachical 的程式碼實現和 multi-label 是相同的,區別是資料層面將多級標籤用 ## 分隔符拼接了起來,形式上仍是 multi-label。在 UTC 中也可以使用這種實現,將多級標籤直接拼起來,如果只需要分類到細分層級,直接取細分層級效果可能更好。這裡就不在重複展示了

#層次分類資料示例
{"text_a": "多層次分類示例", "text_b": "", "question": "", "choices": ["環境 資質優",  "環境 資質差", "口味 口感好", "口味 口感差"], "labels": [0, 1]}
  • Note:2.5版本修改程式碼部分:原有程式碼中compute_metrics 函式的 sigmoid 實現 run_train.py 和 run_eval.py 均改為 softmax
def compute_metrics(eval_preds):
        labels = paddle.to_tensor(eval_preds.label_ids, dtype="int64")
        preds = paddle.to_tensor(eval_preds.predictions)
        preds = paddle.nn.functional.softmax(preds, axis=-1)
        preds = preds[labels != -100]
        labels = paddle.argmax(labels, axis=-1)

        metric = Accuracy()
        correct = metric.compute(preds, labels)
        metric.update(correct)
        acc = metric.accumulate()
        return {"accuracy": acc}
  • 最新版本已經增加:single_label超引數
    • 預設False,即可

    • 二分類時,開啟single_label時需要將執行指令碼中的 metric_for_best_model 引數改為accuracy

4.模型訓練預測

多工訓練場景可分別進行資料轉換再進行混合:通用分類、評論情感分析、語義相似度計算、蘊含推理、多項式閱讀理解等眾多“泛分類”任務

##程式碼結構
├── deploy/simple_serving/ # 模型部署指令碼
├── utils.py               # 資料處理工具
├── run_train.py           # 模型微調指令碼
├── run_eval.py            # 模型評估指令碼
├── label_studio.py        # 資料格式轉換指令碼
├── label_studio_text.md   # 資料標註說明文件
└── README.md

4.1 模型微調

推薦使用 PromptTrainer API 對模型進行微調,該 API 封裝了提示定義功能,且繼承自 Trainer API 。只需輸入模型、資料集等就可以使用 Trainer API 高效快速地進行預訓練、微調等任務,可以一鍵啟動多卡訓練、混合精度訓練、梯度累積、斷點重啟、日誌顯示等功能,Trainer API 還針對訓練過程的通用訓練配置做了封裝,比如:最佳化器、學習率排程等。

使用下面的命令,使用 utc-base 作為預訓練模型進行模型微調,將微調後的模型儲存至output_dir

4.1.1 單卡訓練

#安裝最新版本paddlenlp
!pip install --upgrade paddlenlp
# 單卡啟動:
!python run_train.py  \
    --device gpu \
    --logging_steps 100 \
    --save_steps 100 \
    --eval_steps 100 \
    --seed 1000 \
    --model_name_or_path utc-base \
    --output_dir ./checkpoint_1w/model_best \
    --dataset_path ./data/ \
    --max_seq_length 512  \
    --per_device_train_batch_size 32 \
    --per_device_eval_batch_size 32 \
    --gradient_accumulation_steps 8 \
    --num_train_epochs 20 \
    --learning_rate 1e-5 \
    --do_train \
    --do_eval \
    --do_export \
    --export_model_dir ./checkpoint_1w/model_best \
    --overwrite_output_dir \
    --disable_tqdm True \
    --metric_for_best_model macro_f1 \
    --load_best_model_at_end  True \
    --save_total_limit 1 \
    --save_plm

訓練樣本80下結果:

[2023-05-18 18:47:00,108] [    INFO] - ***** Running Evaluation *****
[2023-05-18 18:47:00,108] [    INFO] -   Num examples = 1611
[2023-05-18 18:47:00,108] [    INFO] -   Total prediction steps = 806
[2023-05-18 18:47:00,108] [    INFO] -   Pre device batch size = 2
[2023-05-18 18:47:00,108] [    INFO] -   Total Batch size = 2
[2023-05-18 18:47:23,035] [    INFO] - eval_loss: 2.9577677249908447, eval_micro_f1: 0.9739602731222843, eval_macro_f1: 0.9244269186423556, eval_runtime: 22.9266, eval_samples_per_second: 70.268, eval_steps_per_second: 35.156, epoch: 20.0

二分類時需要注意的問題

  • ModuleNotFoundError: No module named 'fast_tokenizer'
安裝一下fast tokenizer
pip install --upgrade fast_tokenizer
  • 開啟single_label時需要將執行指令碼中的 metric_for_best_model 引數改為accuracy
metric_value = metrics[metric_to_check]
KeyError: 'eval_macro_f1'

NOTE:

如需恢復模型訓練,則可以設定 init_from_ckpt , 如 init_from_ckpt=checkpoint/model_state.pdparams 。

4.1.2 多卡訓練

如果在GPU環境中使用,可以指定gpus引數進行多卡訓練:

!python -u -m paddle.distributed.launch --gpus "0,1,2,3" run_train.py \
   --device gpu \
    --logging_steps 100 \
    --save_steps 100 \
    --eval_steps 100 \
    --seed 1000 \
    --model_name_or_path utc-base \
    --output_dir ./checkpoint_1w/model_best \
    --dataset_path ./data/ \
    --max_seq_length 512  \
    --per_device_train_batch_size 32 \
    --per_device_eval_batch_size 32 \
    --gradient_accumulation_steps 8 \
    --num_train_epochs 20 \
    --learning_rate 1e-5 \
    --do_train \
    --do_eval \
    --do_export \
    --export_model_dir ./checkpoint_1w/model_best \
    --overwrite_output_dir \
    --disable_tqdm True \
    --metric_for_best_model macro_f1 \
    --load_best_model_at_end  True \
    --save_total_limit 1 \
    --save_plm

訓練樣本1.4w+下結果:

[2023-05-18 19:47:58,379] [    INFO] - ***** Running Evaluation *****
[2023-05-18 19:47:58,380] [    INFO] -   Num examples = 1611
[2023-05-18 19:47:58,380] [    INFO] -   Total prediction steps = 13
[2023-05-18 19:47:58,380] [    INFO] -   Pre device batch size = 32
[2023-05-18 19:47:58,380] [    INFO] -   Total Batch size = 128
[2023-05-18 19:48:01,395] [    INFO] - eval_loss: 1.095533847808838, eval_micro_f1: 0.9833333333333333, eval_macro_f1: 0.9492148827343941, eval_runtime: 3.0153, eval_samples_per_second: 534.28, eval_steps_per_second: 4.311, epoch: 19.9455

該示例程式碼中由於設定了引數 --do_eval,因此在訓練完會自動進行評估。

可配置引數說明:

  • single_label: 每條樣本是否只預測一個標籤。預設為False,表示多標籤分類。
  • device: 訓練裝置,可選擇 'cpu'、'gpu' 其中的一種;預設為 GPU 訓練。
  • logging_steps: 訓練過程中日誌列印的間隔 steps 數,預設10。
  • save_steps: 訓練過程中儲存模型 checkpoint 的間隔 steps 數,預設100。
  • eval_steps: 訓練過程中儲存模型 checkpoint 的間隔 steps 數,預設100。
  • seed:全域性隨機種子,預設為 42。
  • model_name_or_path:進行 few shot 訓練使用的預訓練模型。預設為 "utc-base", 可選"utc-xbase", "utc-base", "utc-medium", "utc-mini", "utc-micro", "utc-nano", "utc-pico"。
  • output_dir:必須,模型訓練或壓縮後儲存的模型目錄;預設為 None
  • dataset_path:資料集檔案所在目錄;預設為 ./data/
  • train_file:訓練集字尾;預設為 train.txt
  • dev_file:開發集字尾;預設為 dev.txt
  • max_seq_len:文字最大切分長度,包括標籤的輸入超過最大長度時會對輸入文字進行自動切分,標籤部分不可切分,預設為512。
  • per_device_train_batch_size:用於訓練的每個 GPU 核心/CPU 的batch大小,預設為8。
  • per_device_eval_batch_size:用於評估的每個 GPU 核心/CPU 的batch大小,預設為8。
  • num_train_epochs: 訓練輪次,使用早停法時可以選擇 100;預設為10。
  • learning_rate:訓練最大學習率,UTC 推薦設定為 1e-5;預設值為3e-5。
  • do_train:是否進行微調訓練,設定該參數列示進行微調訓練,預設不設定。
  • do_eval:是否進行評估,設定該參數列示進行評估,預設不設定。
  • do_export:是否進行匯出,設定該參數列示進行靜態圖匯出,預設不設定。
  • export_model_dir:靜態圖匯出地址,預設為None。
  • overwrite_output_dir: 如果 True,覆蓋輸出目錄的內容。如果 output_dir 指向檢查點目錄,則使用它繼續訓練。
  • disable_tqdm: 是否使用tqdm進度條。
  • metric_for_best_model:最優模型指標, UTC 推薦設定為 macro_f1,預設為None。
  • load_best_model_at_end:訓練結束後是否載入最優模型,通常與metric_for_best_model配合使用,預設為False。
  • save_total_limit:如果設定次引數,將限制checkpoint的總數。刪除舊的checkpoints 輸出目錄,預設為None。
  • --save_plm:儲存模型進行推理部署

NOTE:

如需恢復模型訓練,則可以設定 init_from_ckpt , 如 init_from_ckpt=checkpoint/model_state.pdparams 。

4.2 模型評估

透過執行以下命令進行模型評估預測:

#80樣本
!python run_eval.py \
    --model_path ./checkpoint/model_best \
    --test_path ./data/test.txt \
    --per_device_eval_batch_size 32 \
    --max_seq_len 512 \
    --output_dir ./checkpoint_test

測試結果

test.txt 結果

100%|█████████████████████████████████████████| 879/879 [01:38<00:00, 12.86it/s][2023-05-18 18:52:23,476] [    INFO] - ***** test metrics *****
[2023-05-18 18:52:23,477] [    INFO] -   test_loss               =     0.7952
[2023-05-18 18:52:23,477] [    INFO] -   test_macro_f1           =     0.9491
[2023-05-18 18:52:23,477] [    INFO] -   test_micro_f1           =     0.9833
[2023-05-18 18:52:23,477] [    INFO] -   test_runtime            = 0:01:39.72
[2023-05-18 18:52:23,477] [    INFO] -   test_samples_per_second =      141.0
[2023-05-18 18:52:23,477] [    INFO] -   test_steps_per_second   =      8.814
100%|█████████████████████████████████████████| 879/879 [01:48<00:00,  8.09it/s]

dev.txt結果

100%|█████████████████████████████████████████| 101/101 [00:10<00:00, 13.66it/s][2023-05-18 19:03:14,188] [    INFO] - ***** test metrics *****
[2023-05-18 19:03:14,188] [    INFO] -   test_loss               =     1.0405
[2023-05-18 19:03:14,188] [    INFO] -   test_macro_f1           =      0.934
[2023-05-18 19:03:14,188] [    INFO] -   test_micro_f1           =     0.9779
[2023-05-18 19:03:14,188] [    INFO] -   test_runtime            = 0:00:11.60
[2023-05-18 19:03:14,188] [    INFO] -   test_samples_per_second =    138.821
[2023-05-18 19:03:14,188] [    INFO] -   test_steps_per_second   =      8.703
100%|█████████████████████████████████████████| 101/101 [00:11<00:00,  8.56it/s]
#1.4w+樣本
!python run_eval.py \
    --model_path ./checkpoint_1w/model_best \
    --test_path ./data/dev.txt \
    --per_device_eval_batch_size 16 \
    --max_seq_len 512 \
    --output_dir ./checkpoint_1w_test

測試結果

test.txt 結果

[2023-05-18 19:51:21,323] [    INFO] -   test_loss               =     1.0959
[2023-05-18 19:51:21,323] [    INFO] -   test_macro_f1           =     0.9576
[2023-05-18 19:51:21,323] [    INFO] -   test_micro_f1           =     0.9831
[2023-05-18 19:51:21,323] [    INFO] -   test_runtime            = 0:00:01.23
[2023-05-18 19:51:21,323] [    INFO] -   test_samples_per_second =     64.911
[2023-05-18 19:51:21,323] [    INFO] -   test_steps_per_second   =      4.057

dev.txt結果

[2023-05-18 19:52:19,646] [    INFO] -   test_loss               =     1.0903
[2023-05-18 19:52:19,646] [    INFO] -   test_macro_f1           =     0.9492
[2023-05-18 19:52:19,646] [    INFO] -   test_micro_f1           =     0.9833
[2023-05-18 19:52:19,646] [    INFO] -   test_runtime            = 0:00:10.98
[2023-05-18 19:52:19,646] [    INFO] -   test_samples_per_second =    146.627
[2023-05-18 19:52:19,646] [    INFO] -   test_steps_per_second   =      9.193

可配置引數說明:

  • model_path: 進行評估的模型資料夾路徑,路徑下需包含模型權重檔案model_state.pdparams及配置檔案model_config.json
  • test_path: 進行評估的測試集檔案。
  • per_device_eval_batch_size: 批處理大小,請結合機器情況進行調整,預設為16。
  • max_seq_len: 文字最大切分長度,輸入超過最大長度時會對輸入文字進行自動切分,預設為512。
  • single_label: 每條樣本是否只預測一個標籤。預設為False,表示多標籤分類。

4.3模型預測

paddlenlp.Taskflow裝載定製模型,透過task_path指定模型權重檔案的路徑,路徑下需要包含訓練好的模型權重檔案model_state.pdparams

from pprint import pprint
import json
from paddlenlp import Taskflow

def openreadtxt(file_name):
    data = []
    file = open(file_name,'r',encoding='UTF-8')  #開啟檔案
    file_data = file.readlines() #讀取所有行
    for row in file_data:
        data.append(row) #將每行資料插入data中     
    return data

data_input=openreadtxt('/home/aistudio/input/data2.txt')
# print(data_input)


schema = ["婚後生育", "撫養孩子", "共同財產", "付撫養費", "分不動產", "婚後分居", "二次起訴", "按月付費", "同意離婚", "共同債務", "婚前財產",
 "法定離婚", "家庭義務", "非婚生子", "適當幫助", "無視協議", "損害賠償", "分居兩年", "子女分開", "個人財產"]

my_cls = Taskflow("zero_shot_text_classification", model="utc-base", schema=schema, task_path='/home/aistudio/checkpoint/model_best/plm')
results=my_cls(data_input)

with open("/home/aistudio/output/output.txt", "w+",encoding='UTF-8') as f:    #a :   寫入檔案,若檔案不存在則會先建立再寫入,但不會覆蓋原檔案,而是追加在檔案末尾
    for result in results:
        print(result)
        line = json.dumps(result, ensure_ascii=False)  #對中文預設使用的ascii編碼.想輸出真正的中文需要指定ensure_ascii=False
        f.write(line + "\n")

print("資料結果已匯出")
[2023-05-18 19:14:41,567] [    INFO] - We are using <class 'paddlenlp.transformers.ernie.tokenizer.ErnieTokenizer'> to load 'utc-base'.
[2023-05-18 19:14:41,572] [    INFO] - Already cached /home/aistudio/.paddlenlp/models/utc-base/utc_base_vocab.txt
[2023-05-18 19:14:41,610] [    INFO] - tokenizer config file saved in /home/aistudio/.paddlenlp/models/utc-base/tokenizer_config.json
[2023-05-18 19:14:41,616] [    INFO] - Special tokens file saved in /home/aistudio/.paddlenlp/models/utc-base/special_tokens_map.json
[2023-05-18 19:14:41,622] [    INFO] - Assigning ['[O-MASK]'] to the additional_special_tokens key of the tokenizer


{'predictions': [{'label': '適當幫助', 'score': 0.9990043954170514}], 'text_a': '協議不成時,由人民法院判決”的規定,由於被告後期治療還需大量費用,原告應給與原告必要的經濟幫助。\t\n'}
{'predictions': [{'label': '婚後生育', 'score': 0.9994037939529928}, {'label': '撫養孩子', 'score': 0.9991192036976089}, {'label': '付撫養費', 'score': 0.9995337863092342}], 'text_a': '故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養費。\t\n'}
{'predictions': [{'label': '二次起訴', 'score': 0.9996573067393362}], 'text_a': '2014年12月22日,原告訴至本院,要求與被告離婚,後本院判決不準予原、被告離婚。\t\n'}
{'predictions': [{'label': '婚後生育', 'score': 0.9981496013638776}], 'text_a': '男到女家生活,2006年12月婚生一女,取名張某甲。\t'}
資料結果已匯出

抽樣測試:

  • 協議不成時,由人民法院判決”的規定,由於被告後期治療還需大量費用,原告應給與原告必要的經濟幫助。 適當幫助
  • 故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養費。 婚後生育,付撫養費,撫養孩子
  • 2014年12月22日,原告訴至本院,要求與被告離婚,後本院判決不準予原、被告離婚。 二次起訴
  • 男到女家生活,2006年12月婚生一女,取名張某甲。 婚後生育

{'predictions': [{'label': '適當幫助', 'score': 0.9990043954170514}], 'text_a': '協議不成時,由人民法院判決”的規定,由於被告後期治療還需大量費用,原告應給與原告必要的經濟幫助。\t\n'}
{'predictions': [{'label': '婚後生育', 'score': 0.9994037939529928}, {'label': '撫養孩子', 'score': 0.9991192036976089}, {'label': '付撫養費', 'score': 0.9995337863092342}], 'text_a': '故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養費。\t\n'}
{'predictions': [{'label': '二次起訴', 'score': 0.9996573067393362}], 'text_a': '2014年12月22日,原告訴至本院,要求與被告離婚,後本院判決不準予原、被告離婚。\t\n'}
{'predictions': [{'label': '婚後生育', 'score': 0.9981496013638776}], 'text_a': '男到女家生活,2006年12月婚生一女,取名張某甲。\t'}

抽樣準確率100%

5.基於gradio視覺化展示

6.總結

6.1 UTC提示學習和微調預訓練學習模型對比

Macro F1和Micro F1都是評估分類模型效能的指標,但是它們計算方式不同。

  • Macro F1是每個類別的F1值的平均值,不考慮類別的樣本數。它適用於資料集中各個類別的樣本數量相近的情況下,可以更好地反映每個類別的效能。

  • Micro F1是所有類別的F1值的加權平均,其中權重為每個類別的樣本數。它將所有類別的預測結果彙總為一個混淆矩陣,並計算出整個資料集的精確率、召回率和F1值。Micro F1適用於多分類問題,尤其是在資料集不平衡的情況下,可以更好地反映整體的效能。

總之,Micro F1更關注整個資料集的效能,而Macro F1更關注每個類別的效能。

model_name 模型結構 Micro F1(%) Macro F1(%)
UTC-base-1.4w+樣本 12-layer, 768-hidden, 12-heads 98.33 94.92
UTC-base-80樣本 12-layer, 768-hidden, 12-heads 97.79 93.4
ERNIE 1.0 Large Cw 24-layer, 1024-hidden, 20-heads 91.14 81.68
ERNIE 3.0 Base 12-layer, 768-hidden, 12-heads 90.38 80.14
ERNIE 3.0 Medium 6-layer, 768-hidden, 12-heads 90.57 79.36
ERNIE 3.0 Mini 6-layer, 384-hidden, 12-heads 89.27 76.78
ERNIE 3.0 Micro 4-layer, 384-hidden, 12-heads 89.43 77.20
ERNIE 3.0 Nano 4-layer, 312-hidden, 12-heads 85.39 75.07

專案連結&碼源連結

“中國法研杯”司法人工智慧挑戰賽:基於UTC的多標籤/層次分類小樣本文字應用,Macro F1提升13%+

相關文章