“中國法研杯”司法人工智能挑戰(zhàn)賽:基于UTC的多標(biāo)簽/層次分類小樣本文本應(yīng)用,Macro

“中國法研杯”司法人工智能挑戰(zhàn)賽:基于UTC的多標(biāo)簽/層次分類小樣本文本應(yīng)用,Macro F1提升13%+
相關(guān)文章推薦:
小樣本文本分類應(yīng)用:基于UTC的醫(yī)療意圖多分類,訓(xùn)練調(diào)優(yōu)部署一條龍:(https://blog.csdn.net/sinat_39620217/article/details/130237035)
本項(xiàng)目主要完成基于UTC的多標(biāo)簽應(yīng)用,更多部署細(xì)節(jié)請參考推薦文章。本項(xiàng)目提供了小樣本場景下文本多標(biāo)簽分類的解決方案,在 UTC的基礎(chǔ)上利用提示學(xué)習(xí)取得比微調(diào)更好的分類效果,充分利用標(biāo)注信息。
項(xiàng)目以及碼源見文末
項(xiàng)目背景:
近年來,大量包含了案件事實(shí)及其適用法律條文信息的裁判文書逐漸在互聯(lián)網(wǎng)上公開,海量的數(shù)據(jù)使自然語言處理技術(shù)的應(yīng)用成為可能?,F(xiàn)實(shí)中的案情錯綜復(fù)雜,案情描述通常涉及多個重要事實(shí),以CAIL2019數(shù)據(jù)集中婚姻家庭領(lǐng)域的案情要素抽取為例:
"2013年11月28日原、被告離婚時自愿達(dá)成協(xié)議,婚生子張某乙由被告李某某撫養(yǎng),本院以(2013)寶渭法民初字第01848號民事調(diào)解書對該協(xié)議內(nèi)容予以了確認(rèn),該協(xié)議具有法律效力,對原、被告雙方均有約束力。"
該案件中涉及婚后有子女、限制行為能力子女撫養(yǎng)兩項(xiàng)要素。接下來我們將講解在小樣本場景下如何利用多標(biāo)簽?zāi)P?,對輸入文本中進(jìn)行案情重要要素抽取。
應(yīng)用部署界面展示

1.UTC(Universal Text Classification介紹
本項(xiàng)目提供基于通用文本分類 UTC(Universal Text Classification) 模型微調(diào)的文本分類端到端應(yīng)用方案,打通數(shù)據(jù)標(biāo)注-模型訓(xùn)練-模型調(diào)優(yōu)-預(yù)測部署全流程,可快速實(shí)現(xiàn)文本分類產(chǎn)品落地。
文本分類是一種重要的自然語言處理任務(wù),它可以幫助我們將大量的文本數(shù)據(jù)進(jìn)行有效的分類和歸納。實(shí)際上,在日常生活中,我們也經(jīng)常會用到文本分類技術(shù)。例如,我們可以使用文本分類來對新聞報道進(jìn)行分類,對電子郵件進(jìn)行分類,對社交媒體上的評論進(jìn)行情感分析等等。但是,文本分類也面臨著許多挑戰(zhàn)。其中最重要的挑戰(zhàn)之一是數(shù)據(jù)稀缺。由于文本數(shù)據(jù)往往非常龐大,因此獲取足夠的訓(xùn)練數(shù)據(jù)可能非常困難。此外,不同的文本分類任務(wù)也可能面臨著領(lǐng)域多變和任務(wù)多樣等挑戰(zhàn)。為了應(yīng)對這些挑戰(zhàn),PaddleNLP推出了一項(xiàng)零樣本文本分類應(yīng)用UTC。該應(yīng)用通過統(tǒng)一語義匹配方式USM(Unified Semantic Matching)來將標(biāo)簽和文本的語義匹配能力進(jìn)行統(tǒng)一建模。這種方法可以幫助我們更好地理解文本數(shù)據(jù),并從中提取出有用的特征信息。
UTC具有低資源遷移能力,可以支持通用分類、評論情感分析、語義相似度計(jì)算、蘊(yùn)含推理、多項(xiàng)式閱讀理解等多種“泛分類”任務(wù)。這使得開發(fā)者可以更加輕松高效地實(shí)現(xiàn)多任務(wù)文本分類數(shù)據(jù)標(biāo)注、訓(xùn)練、調(diào)優(yōu)和上線,從而降低文本分類技術(shù)門檻。
總之,文本分類是一項(xiàng)重要的自然語言處理任務(wù),它可以幫助我們更好地理解和歸納文本數(shù)據(jù)。盡管它面臨著許多挑戰(zhàn),但是通過使用PaddleNLP的零樣本文本分類應(yīng)用UTC,開發(fā)者們可以簡單高效實(shí)現(xiàn)多任務(wù)文本分類數(shù)據(jù)標(biāo)注、訓(xùn)練、調(diào)優(yōu)、上線,降低文本分類落地技術(shù)門檻。
1.1 分類落地面臨難度
分類任務(wù)看似簡單,然而在產(chǎn)業(yè)級文本分類落地實(shí)踐中,面臨著諸多挑戰(zhàn):
任務(wù)多樣:單標(biāo)簽、多標(biāo)簽、層次標(biāo)簽、大規(guī)模標(biāo)簽等不同的文本分類任務(wù),需要開發(fā)不同的分類模型,模型架構(gòu)往往特化于具體任務(wù),難以使用統(tǒng)一形式建模;
數(shù)據(jù)稀缺:部分領(lǐng)域數(shù)據(jù)稀缺,難以獲取,且領(lǐng)域?qū)I(yè)性使得數(shù)據(jù)標(biāo)注門檻高;
標(biāo)簽遷移:不同領(lǐng)域的標(biāo)簽多樣,并且遷移難度大,尤其不同領(lǐng)域間的標(biāo)簽知識很難遷移。
1.2 UTC亮點(diǎn)
1.2.1 多任務(wù)統(tǒng)一建模
在傳統(tǒng)技術(shù)方案中,針對不同的分類任務(wù)需要構(gòu)建多個分類模型,模型需單獨(dú)訓(xùn)練且數(shù)據(jù)和知識不共享。而在UTC方案下,單個模型能解決所有分類需求,包括但不限于單標(biāo)簽分類、多標(biāo)簽分類、層次標(biāo)簽分類、大規(guī)模事件標(biāo)簽檢測、蘊(yùn)含推理、語義相似度計(jì)算等,降低了開發(fā)成本和機(jī)器成本。

1.2.2 零樣本分類和小樣本遷移能力強(qiáng)
UTC通過大規(guī)模多任務(wù)預(yù)訓(xùn)練后,可以適配不同的行業(yè)領(lǐng)域,不同的分類標(biāo)簽,僅標(biāo)注了幾條樣本,分類效果就取得大幅提升,大大降低標(biāo)注門檻和成本。

在醫(yī)療、金融、法律等領(lǐng)域中,無需訓(xùn)練數(shù)據(jù)的零樣本情況下UTC效果平均可達(dá)到70%+(如下表所示),標(biāo)注少樣本也可帶來顯著的效果提升:每個標(biāo)簽僅僅標(biāo)注1條樣本后,平均提升了10個點(diǎn)!也就是說,即使在某些場景下表現(xiàn)欠佳,人工標(biāo)幾個樣本,丟給模型后就會有大幅的效果提升。
1.3 UTC技術(shù)思路
UTC基于百度最新提出的統(tǒng)一語義匹配框架USM(Unified Semantic Matching)[1],將分類任務(wù)統(tǒng)一建模為標(biāo)簽與文本之間的匹配任務(wù),對不同標(biāo)簽的分類任務(wù)進(jìn)行統(tǒng)一建模。具體地說:
為了實(shí)現(xiàn)任務(wù)架構(gòu)統(tǒng)一,UTC設(shè)計(jì)了標(biāo)簽與文本之間的詞對連接操作(Label–>CLS-Token Linking),這使得模型能夠適應(yīng)不同領(lǐng)域和任務(wù)的標(biāo)簽信息,并按需求進(jìn)行分類,從而實(shí)現(xiàn)了開放域場景下的通用文本分類。 例如,對于事件檢測任務(wù),可將一系列事件標(biāo)簽拼接為[L]上映[L]奪冠[L]下架 ,然后與原文本一起作為整體輸入到UTC中,UTC將不同標(biāo)簽標(biāo)識符[L]與[CLS]進(jìn)行匹配,可對不同標(biāo)簽類型的分類任務(wù)統(tǒng)一建模,直接上圖:

為了實(shí)現(xiàn)通用能力共享,讓不同領(lǐng)域間的標(biāo)簽知識跨域遷移,UTC構(gòu)建了統(tǒng)一的異質(zhì)監(jiān)督學(xué)習(xí)方法進(jìn)行多任務(wù)預(yù)訓(xùn)練,使不同領(lǐng)域任務(wù)具備良好的零/少樣本遷移性能。統(tǒng)一的異質(zhì)監(jiān)督學(xué)習(xí)方法主要包括三種不同的監(jiān)督信號:
直接監(jiān)督:分類任務(wù)直接相關(guān)的數(shù)據(jù)集,如情感分類、新聞分類、意圖識別等。
間接監(jiān)督:分類任務(wù)間接相關(guān)的數(shù)據(jù)集,如選項(xiàng)式閱讀理解、問題-文章匹配等。
遠(yuǎn)程監(jiān)督:標(biāo)簽知識庫或?qū)蛹墭?biāo)題與文本對齊后弱標(biāo)注數(shù)據(jù)。
更多內(nèi)容參考論文見文末鏈接 or fork一下項(xiàng)目論文已上傳
2.文本分類任務(wù)Label Studio教程
2.1 Label Studio安裝
以下標(biāo)注示例用到的環(huán)境配置:
Python 3.8+
label-studio == 1.7.2
在終端(terminal)使用pip安裝label-studio:
pip install label-studio==1.7.2
安裝完成后,運(yùn)行以下命令行:
label-studio start
在瀏覽器打開http://localhost:8080/,輸入用戶名和密碼登錄,開始使用label-studio進(jìn)行標(biāo)注。
2.2 文本分類任務(wù)標(biāo)注
2.2.1 項(xiàng)目創(chuàng)建
點(diǎn)擊創(chuàng)建(Create)開始創(chuàng)建一個新的項(xiàng)目,填寫項(xiàng)目名稱、描述,然后在Labeling Setup
中選擇Text Classification
。
填寫項(xiàng)目名稱、描述
數(shù)據(jù)上傳,從本地上傳txt格式文件,選擇
List of tasks
,然后選擇導(dǎo)入本項(xiàng)目

設(shè)置任務(wù),添加標(biāo)簽

數(shù)據(jù)上傳
項(xiàng)目創(chuàng)建后,可在Project/文本分類任務(wù)中點(diǎn)擊Import
繼續(xù)導(dǎo)入數(shù)據(jù),同樣從本地上傳txt格式文件,選擇List of tasks
?。
2.2.2 標(biāo)簽構(gòu)建
項(xiàng)目創(chuàng)建后,可在Setting/Labeling Interface中繼續(xù)配置標(biāo)簽,
默認(rèn)模式為單標(biāo)簽多分類數(shù)據(jù)標(biāo)注。對于多標(biāo)簽多分類數(shù)據(jù)標(biāo)注,需要將choice
的值由single
改為multiple
。
2.2.3 任務(wù)標(biāo)注

2.2.4 數(shù)據(jù)導(dǎo)出
勾選已標(biāo)注文本ID,選擇導(dǎo)出的文件類型為JSON
,導(dǎo)出數(shù)據(jù):
參考鏈接:
Label Studio
3.多標(biāo)簽/層次分類數(shù)據(jù)轉(zhuǎn)換
這里我們使用CAIL2019“中國法研杯”司法人工智能挑戰(zhàn)賽—婚姻家庭要素提取任務(wù)數(shù)據(jù)集的子集作為示例數(shù)據(jù)集。該數(shù)據(jù)集中原始訓(xùn)練集包括 14377 條標(biāo)注樣本,我們按每條標(biāo)簽隨機(jī)采樣 4 條樣本,得到 80 條樣本數(shù)據(jù)作為訓(xùn)練集,剩余訓(xùn)練集數(shù)據(jù)作為測試集。
3.1 多標(biāo)簽源數(shù)據(jù)格式
data/
├── train.txt ?# 訓(xùn)練數(shù)據(jù)集├── dev.txt ? ?# 驗(yàn)證數(shù)據(jù)集├── test.txt ? # 測試數(shù)據(jù)集(可選)├── data.txt ? # 待預(yù)測數(shù)據(jù)(可選)└── label.txt ?# 分類標(biāo)簽集
訓(xùn)練/驗(yàn)證/測試數(shù)據(jù)
對于訓(xùn)練/驗(yàn)證/測試數(shù)據(jù)集文件,每行數(shù)據(jù)表示一條樣本,包括文本和標(biāo)簽兩部分,由tab符\t分隔,多個標(biāo)簽以英文逗號,分隔。格式如下
<文本>'\t'<標(biāo)簽>','<標(biāo)簽>','<標(biāo)簽><文本>'\t'<標(biāo)簽>','<標(biāo)簽>
數(shù)據(jù)集展示
本院認(rèn)為,涉案房屋系2012年12月4日原、被告婚姻關(guān)系存續(xù)期間購買,且涉案樓房的產(chǎn)權(quán)登記在原、被告名下,依據(jù)法律規(guī)定,夫妻在婚姻關(guān)系存續(xù)期間所得的財(cái)產(chǎn),歸夫妻共同所有; ? ?不動產(chǎn)分割,有夫妻共同財(cái)產(chǎn)
原、被告之間的共同財(cái)產(chǎn)應(yīng)依法分割。 ? ?有夫妻共同財(cái)產(chǎn)
協(xié)議不成時,由人民法院判決”的規(guī)定,由于被告后期治療還需大量費(fèi)用,原告應(yīng)給與原告必要的經(jīng)濟(jì)幫助。 ? ?適當(dāng)幫助
故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養(yǎng)費(fèi)。 ? ?婚后有子女,支付撫養(yǎng)費(fèi),限制行為能力子女撫養(yǎng)
2014年12月22日,原告訴至本院,要求與被告離婚,后本院判決不準(zhǔn)予原、被告離婚。 ? ?二次起訴離婚
男到女家生活,2006年12月婚生一女,取名張某甲。 ? ?婚后有子女
預(yù)測數(shù)據(jù)
對于待預(yù)測數(shù)據(jù)文件,每行包含一條待預(yù)測樣本,無標(biāo)簽。格式如下
<文本><文本>
數(shù)據(jù)集展示
五松新村房屋是被告婚前購買的;
被告于2016年3月將車牌號為皖B×××××出售了2.7萬元,被告通過原告償還了齊荷花人民幣2.6萬元,原、被告尚欠齊荷花2萬元。
2、判令被告返還借婚姻索取的現(xiàn)金33萬元,婚前個人存款10萬元;
一、判決原告于某某與被告楊某某離婚;
標(biāo)簽數(shù)據(jù)
對于分類標(biāo)簽集文件,存儲了數(shù)據(jù)集中所有的標(biāo)簽集合,每行為一個標(biāo)簽名。如果需要自定義標(biāo)簽映射用于分類器初始化,則每行需要包括標(biāo)簽名和相應(yīng)的映射詞,由==分隔。格式如下
<標(biāo)簽>'=='<映射詞><標(biāo)簽>'=='<映射詞>
例如,對于婚姻家庭要素提取數(shù)據(jù)集,原標(biāo)簽字?jǐn)?shù)較多,因此同一個標(biāo)簽依賴的輸出也多。為了降低訓(xùn)練難度,我們可以將其映射為較短的短語
有夫妻共同債務(wù)==共同債務(wù)
存在非婚生子==非婚生子
...
Note: 這里的標(biāo)簽映射詞定義遵循的規(guī)則是,不同映射詞盡可能長度一致,映射詞和提示需要盡可能構(gòu)成通順的語句。越接近自然語句,小樣本下模型訓(xùn)練效果越好。如果原標(biāo)簽名已經(jīng)可以構(gòu)成通順語句,也可以不構(gòu)造映射詞,每行一個標(biāo)簽即可,即
3.2層次分類源數(shù)據(jù)格式
訓(xùn)練/驗(yàn)證/測試數(shù)據(jù) 對于訓(xùn)練/驗(yàn)證/測試數(shù)據(jù)集文件,每行數(shù)據(jù)表示一條樣本,包括文本和標(biāo)簽兩部分,由tab符\t分隔,多個標(biāo)簽以英文逗號,分隔,同一標(biāo)簽內(nèi)不同層級以##字符連接。格式如下
<文本>'\t'<標(biāo)簽>','<標(biāo)簽>','<標(biāo)簽><文本>'\t'<標(biāo)簽>','<標(biāo)簽>...
紫光圣果副總經(jīng)理李明雷辭職 ?組織關(guān)系,組織關(guān)系##辭/離職
無理取鬧辱罵扶貧干部織金一居民被行拘 ? ?司法行為,司法行為##拘捕
...
標(biāo)簽數(shù)據(jù)
對于分類標(biāo)簽集文件,存儲了數(shù)據(jù)集中所有的標(biāo)簽路徑集合,每行是一個標(biāo)簽路徑,高層的標(biāo)簽指向底層標(biāo)簽,不同層級的標(biāo)簽用'##'連接,本項(xiàng)目選擇為標(biāo)簽層次結(jié)構(gòu)中的每一個節(jié)點(diǎn)生成對應(yīng)的標(biāo)簽路徑,詳見層次分類任務(wù)介紹,標(biāo)簽路徑格式如下
<一級標(biāo)簽><一級標(biāo)簽>'##'<二級標(biāo)簽><一級標(biāo)簽>'##'<二級標(biāo)簽>'##'<三級標(biāo)簽>...
如果需要自定義標(biāo)簽映射用于分類器初始化,則每行需要包括標(biāo)簽名和相應(yīng)的映射詞,由==分隔。格式如下<一級標(biāo)簽>'=='<映射詞><一級標(biāo)簽>'##'<二級標(biāo)簽>'=='<映射詞><一級標(biāo)簽>'##'<二級標(biāo)簽>'##'<三級標(biāo)簽>'=='<映射詞>...
例如,原標(biāo)簽路徑交往##會見中包括特殊符號##,大概率不會在說話或者寫作中使用,因此我們將其映射為會見或者見面。
交往==交往
交往##會見==會見
...
3.3 轉(zhuǎn)換后格式
三種分類都可以在 UTC 框架下實(shí)現(xiàn),其中 multi-class 2.5版本需要修改評估代碼。multi-label: UTC 默認(rèn)是 multi-label 形式。
#多分類數(shù)據(jù)示例{"text_a": "、月經(jīng)期間刮痧拔罐會引起身體什么", "text_b": "", "question": "", "choices": ["病情診斷", "治療方案", "病因分析", "指標(biāo)解讀", "就醫(yī)建議", "疾病表述", "后果表述", "注意事項(xiàng)", "功效作用", "醫(yī)療費(fèi)用", "其他"], "labels": [5]}
#多標(biāo)簽數(shù)據(jù)示例{"text_a": "多標(biāo)簽分類示例","text_b": "", "question": "","choices": ["體育", "時政", "娛樂", "電影"], "labels": [2, 3]}
hierachical: applications/text_classification/*/few-shot 目錄下 hierachical 的代碼實(shí)現(xiàn)和 multi-label 是相同的,區(qū)別是數(shù)據(jù)層面將多級標(biāo)簽用 ## 分隔符拼接了起來,形式上仍是 multi-label。在 UTC 中也可以使用這種實(shí)現(xiàn),將多級標(biāo)簽直接拼起來,如果只需要分類到細(xì)分層級,直接取細(xì)分層級效果可能更好。這里就不在重復(fù)展示了
#層次分類數(shù)據(jù)示例{"text_a": "多層次分類示例", "text_b": "", "question": "", "choices": ["環(huán)境 資質(zhì)優(yōu)", ?"環(huán)境 資質(zhì)差", "口味 口感好", "口味 口感差"], "labels": [0, 1]}
Note:2.5版本修改代碼部分:原有代碼中computemetrics 函數(shù)的 sigmoid 實(shí)現(xiàn) runtrain.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}
最新版本已經(jīng)增加:single_label超參數(shù)
默認(rèn)False,即可
二分類時,開啟singlelabel時需要將運(yùn)行腳本中的 metricforbestmodel 參數(shù)改為accuracy
4.模型訓(xùn)練預(yù)測
多任務(wù)訓(xùn)練場景可分別進(jìn)行數(shù)據(jù)轉(zhuǎn)換再進(jìn)行混合:通用分類、評論情感分析、語義相似度計(jì)算、蘊(yùn)含推理、多項(xiàng)式閱讀理解等眾多“泛分類”任務(wù)
##代碼結(jié)構(gòu)├── deploy/simple_serving/ # 模型部署腳本├── utils.py ? ? ? ? ? ? ? # 數(shù)據(jù)處理工具├── run_train.py ? ? ? ? ? # 模型微調(diào)腳本├── run_eval.py ? ? ? ? ? ?# 模型評估腳本├── label_studio.py ? ? ? ?# 數(shù)據(jù)格式轉(zhuǎn)換腳本├── label_studio_text.md ? # 數(shù)據(jù)標(biāo)注說明文檔└── README.md
4.1 模型微調(diào)
推薦使用 PromptTrainer API 對模型進(jìn)行微調(diào),該 API 封裝了提示定義功能,且繼承自?Trainer API?。只需輸入模型、數(shù)據(jù)集等就可以使用 Trainer API 高效快速地進(jìn)行預(yù)訓(xùn)練、微調(diào)等任務(wù),可以一鍵啟動多卡訓(xùn)練、混合精度訓(xùn)練、梯度累積、斷點(diǎn)重啟、日志顯示等功能,Trainer API 還針對訓(xùn)練過程的通用訓(xùn)練配置做了封裝,比如:優(yōu)化器、學(xué)習(xí)率調(diào)度等。
使用下面的命令,使用?utc-base
?作為預(yù)訓(xùn)練模型進(jìn)行模型微調(diào),將微調(diào)后的模型保存至output_dir
:
4.1.1 單卡訓(xùn)練
#安裝最新版本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
訓(xùn)練樣本80下結(jié)果:
[1611[ ] [ ? ?INFO] - ? Total prediction steps = 806[ ] [ ? ?INFO] - ? Pre device batch size = 2[ ] [ ? ?INFO] - ? Total Batch size = 2[ ] [ ? ?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
] [ ? ?INFO] - ***** Running Evaluation *****
[ ] [ ? ?INFO] - ? Num examples =
二分類時需要注意的問題
ModuleNotFoundError: No module named 'fast_tokenizer'
安裝一下fast tokenizer
pip install --upgrade fast_tokenizer
開啟singlelabel時需要將運(yùn)行腳本中的 metricforbestmodel 參數(shù)改為accuracy
metric_value = metrics[metric_to_check]KeyError: 'eval_macro_f1'
NOTE:
如需恢復(fù)模型訓(xùn)練,則可以設(shè)置 initfromckpt , 如 initfromckpt=checkpoint/model_state.pdparams 。
4.1.2 多卡訓(xùn)練
如果在GPU環(huán)境中使用,可以指定gpus參數(shù)進(jìn)行多卡訓(xùn)練:
!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
訓(xùn)練樣本1.4w+下結(jié)果:
[1611[ ] [ ? ?INFO] - ? Total prediction steps = 13[ ] [ ? ?INFO] - ? Pre device batch size = 32[ ] [ ? ?INFO] - ? Total Batch size = 128[ ] [ ? ?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
] [ ? ?INFO] - ***** Running Evaluation *****
[ ] [ ? ?INFO] - ? Num examples =
該示例代碼中由于設(shè)置了參數(shù)?--do_eval
,因此在訓(xùn)練完會自動進(jìn)行評估。
可配置參數(shù)說明:
single_label
: 每條樣本是否只預(yù)測一個標(biāo)簽。默認(rèn)為False
,表示多標(biāo)簽分類。device
: 訓(xùn)練設(shè)備,可選擇 'cpu'、'gpu' 其中的一種;默認(rèn)為 GPU 訓(xùn)練。logging_steps
: 訓(xùn)練過程中日志打印的間隔 steps 數(shù),默認(rèn)10。save_steps
: 訓(xùn)練過程中保存模型 checkpoint 的間隔 steps 數(shù),默認(rèn)100。eval_steps
: 訓(xùn)練過程中保存模型 checkpoint 的間隔 steps 數(shù),默認(rèn)100。seed
:全局隨機(jī)種子,默認(rèn)為 42。model_name_or_path
:進(jìn)行 few shot 訓(xùn)練使用的預(yù)訓(xùn)練模型。默認(rèn)為 "utc-base", 可選"utc-xbase", "utc-base", "utc-medium", "utc-mini", "utc-micro", "utc-nano", "utc-pico"。output_dir
:必須,模型訓(xùn)練或壓縮后保存的模型目錄;默認(rèn)為?None
?。dataset_path
:數(shù)據(jù)集文件所在目錄;默認(rèn)為?./data/
?。train_file
:訓(xùn)練集后綴;默認(rèn)為?train.txt
?。dev_file
:開發(fā)集后綴;默認(rèn)為?dev.txt
?。max_seq_len
:文本最大切分長度,包括標(biāo)簽的輸入超過最大長度時會對輸入文本進(jìn)行自動切分,標(biāo)簽部分不可切分,默認(rèn)為512。per_device_train_batch_size
:用于訓(xùn)練的每個 GPU 核心/CPU 的batch大小,默認(rèn)為8。per_device_eval_batch_size
:用于評估的每個 GPU 核心/CPU 的batch大小,默認(rèn)為8。num_train_epochs
: 訓(xùn)練輪次,使用早停法時可以選擇 100;默認(rèn)為10。learning_rate
:訓(xùn)練最大學(xué)習(xí)率,UTC 推薦設(shè)置為 1e-5;默認(rèn)值為3e-5。do_train
:是否進(jìn)行微調(diào)訓(xùn)練,設(shè)置該參數(shù)表示進(jìn)行微調(diào)訓(xùn)練,默認(rèn)不設(shè)置。do_eval
:是否進(jìn)行評估,設(shè)置該參數(shù)表示進(jìn)行評估,默認(rèn)不設(shè)置。do_export
:是否進(jìn)行導(dǎo)出,設(shè)置該參數(shù)表示進(jìn)行靜態(tài)圖導(dǎo)出,默認(rèn)不設(shè)置。export_model_dir
:靜態(tài)圖導(dǎo)出地址,默認(rèn)為None。overwrite_output_dir
: 如果?True
,覆蓋輸出目錄的內(nèi)容。如果?output_dir
?指向檢查點(diǎn)目錄,則使用它繼續(xù)訓(xùn)練。disable_tqdm
: 是否使用tqdm進(jìn)度條。metric_for_best_model
:最優(yōu)模型指標(biāo), UTC 推薦設(shè)置為?macro_f1
,默認(rèn)為None。load_best_model_at_end
:訓(xùn)練結(jié)束后是否加載最優(yōu)模型,通常與metric_for_best_model
配合使用,默認(rèn)為False。save_total_limit
:如果設(shè)置次參數(shù),將限制checkpoint的總數(shù)。刪除舊的checkpoints?輸出目錄
,默認(rèn)為None。--save_plm
:保存模型進(jìn)行推理部署
NOTE:
如需恢復(fù)模型訓(xùn)練,則可以設(shè)置 initfromckpt , 如 initfromckpt=checkpoint/model_state.pdparams 。
4.2 模型評估
通過運(yùn)行以下命令進(jìn)行模型評估預(yù)測:
#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
測試結(jié)果
test.txt 結(jié)果
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結(jié)果
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
測試結(jié)果
test.txt 結(jié)果
[1.0959[ ] [ ? ?INFO] - ? test_macro_f1 ? ? ? ? ? = ? ? 0.9576[ ] [ ? ?INFO] - ? test_micro_f1 ? ? ? ? ? = ? ? 0.9831[ ] [ ? ?INFO] - ? test_runtime ? ? ? ? ? ?= 0:00:01.23[ ] [ ? ?INFO] - ? test_samples_per_second = ? ? 64.911[ ] [ ? ?INFO] - ? test_steps_per_second ? = ? ? ?4.057
] [ ? ?INFO] - ? test_loss ? ? ? ? ? ? ? = ? ?
dev.txt結(jié)果
[1.0903[ ] [ ? ?INFO] - ? test_macro_f1 ? ? ? ? ? = ? ? 0.9492[ ] [ ? ?INFO] - ? test_micro_f1 ? ? ? ? ? = ? ? 0.9833[ ] [ ? ?INFO] - ? test_runtime ? ? ? ? ? ?= 0:00:10.98[ ] [ ? ?INFO] - ? test_samples_per_second = ? ?146.627[ ] [ ? ?INFO] - ? test_steps_per_second ? = ? ? ?9.193
] [ ? ?INFO] - ? test_loss ? ? ? ? ? ? ? = ? ?
可配置參數(shù)說明:
model_path
: 進(jìn)行評估的模型文件夾路徑,路徑下需包含模型權(quán)重文件model_state.pdparams
及配置文件model_config.json
。test_path
: 進(jìn)行評估的測試集文件。per_device_eval_batch_size
: 批處理大小,請結(jié)合機(jī)器情況進(jìn)行調(diào)整,默認(rèn)為16。max_seq_len
: 文本最大切分長度,輸入超過最大長度時會對輸入文本進(jìn)行自動切分,默認(rèn)為512。single_label
: 每條樣本是否只預(yù)測一個標(biāo)簽。默認(rèn)為False
,表示多標(biāo)簽分類。
4.3模型預(yù)測
paddlenlp.Taskflow
裝載定制模型,通過task_path
指定模型權(quán)重文件的路徑,路徑下需要包含訓(xùn)練好的模型權(quán)重文件model_state.pdparams
。
from pprint import pprintimport jsonfrom paddlenlp import Taskflowdef openreadtxt(file_name):
? ?data = []
? ?file = open(file_name,'r',encoding='UTF-8') ?#打開文件
? ?file_data = file.readlines() #讀取所有行
? ?for row in file_data:
? ? ? ?data.append(row) #將每行數(shù)據(jù)插入data中 ? ?
? ?return data
data_input=openreadtxt('/home/aistudio/input/data2.txt')# print(data_input)schema = ["婚后生育", "撫養(yǎng)孩子", "共同財(cái)產(chǎn)", "付撫養(yǎng)費(fèi)", "分不動產(chǎn)", "婚后分居", "二次起訴", "按月付費(fèi)", "同意離婚", "共同債務(wù)", "婚前財(cái)產(chǎn)", "法定離婚", "家庭義務(wù)", "非婚生子", "適當(dāng)幫助", "無視協(xié)議", "損害賠償", "分居兩年", "子女分開", "個人財(cái)產(chǎn)"]
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 : ? 寫入文件,若文件不存在則會先創(chuàng)建再寫入,但不會覆蓋原文件,而是追加在文件末尾
? ?for result in results:
? ? ? ?print(result)
? ? ? ?line = json.dumps(result, ensure_ascii=False) ?#對中文默認(rèn)使用的ascii編碼.想輸出真正的中文需要指定ensure_ascii=False
? ? ? ?f.write(line + "\n")
print("數(shù)據(jù)結(jié)果已導(dǎo)出")
[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': '適當(dāng)幫助', 'score': 0.9990043954170514}], 'text_a': '協(xié)議不成時,由人民法院判決”的規(guī)定,由于被告后期治療還需大量費(fèi)用,原告應(yīng)給與原告必要的經(jīng)濟(jì)幫助。\t\n'}
{'predictions': [{'label': '婚后生育', 'score': 0.9994037939529928}, {'label': '撫養(yǎng)孩子', 'score': 0.9991192036976089}, {'label': '付撫養(yǎng)費(fèi)', 'score': 0.9995337863092342}], 'text_a': '故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養(yǎng)費(fèi)。\t\n'}
{'predictions': [{'label': '二次起訴', 'score': 0.9996573067393362}], 'text_a': '2014年12月22日,原告訴至本院,要求與被告離婚,后本院判決不準(zhǔn)予原、被告離婚。\t\n'}
{'predictions': [{'label': '婚后生育', 'score': 0.9981496013638776}], 'text_a': '男到女家生活,2006年12月婚生一女,取名張某甲。\t'}
數(shù)據(jù)結(jié)果已導(dǎo)出
抽樣測試:
協(xié)議不成時,由人民法院判決”的規(guī)定,由于被告后期治療還需大量費(fèi)用,原告應(yīng)給與原告必要的經(jīng)濟(jì)幫助。 適當(dāng)幫助
故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養(yǎng)費(fèi)。 婚后生育,付撫養(yǎng)費(fèi),撫養(yǎng)孩子
2014年12月22日,原告訴至本院,要求與被告離婚,后本院判決不準(zhǔn)予原、被告離婚。 二次起訴
男到女家生活,2006年12月婚生一女,取名張某甲。 婚后生育
{'predictions': [{'label': '適當(dāng)幫助', 'score': 0.9990043954170514}], 'text_a': '協(xié)議不成時,由人民法院判決”的規(guī)定,由于被告后期治療還需大量費(fèi)用,原告應(yīng)給與原告必要的經(jīng)濟(jì)幫助。\t\n'}
{'predictions': [{'label': '婚后生育', 'score': 0.9994037939529928}, {'label': '撫養(yǎng)孩子', 'score': 0.9991192036976089}, {'label': '付撫養(yǎng)費(fèi)', 'score': 0.9995337863092342}], 'text_a': '故原告向法院提起訴訟,要求與被告離婚,婚生女孩隨原告生活,被告給付撫養(yǎng)費(fèi)。\t\n'}
{'predictions': [{'label': '二次起訴', 'score': 0.9996573067393362}], 'text_a': '2014年12月22日,原告訴至本院,要求與被告離婚,后本院判決不準(zhǔn)予原、被告離婚。\t\n'}
{'predictions': [{'label': '婚后生育', 'score': 0.9981496013638776}], 'text_a': '男到女家生活,2006年12月婚生一女,取名張某甲。\t'}
抽樣準(zhǔn)確率100%
5.基于gradio可視化展示

6.總結(jié)
6.1 UTC提示學(xué)習(xí)和微調(diào)預(yù)訓(xùn)練學(xué)習(xí)模型對比
Macro F1和Micro F1都是評估分類模型性能的指標(biāo),但是它們計(jì)算方式不同。
Macro F1是每個類別的F1值的平均值,不考慮類別的樣本數(shù)。它適用于數(shù)據(jù)集中各個類別的樣本數(shù)量相近的情況下,可以更好地反映每個類別的性能。
Micro F1是所有類別的F1值的加權(quán)平均,其中權(quán)重為每個類別的樣本數(shù)。它將所有類別的預(yù)測結(jié)果匯總為一個混淆矩陣,并計(jì)算出整個數(shù)據(jù)集的精確率、召回率和F1值。Micro F1適用于多分類問題,尤其是在數(shù)據(jù)集不平衡的情況下,可以更好地反映整體的性能。
總之,Micro F1更關(guān)注整個數(shù)據(jù)集的性能,而Macro F1更關(guān)注每個類別的性能。
| model_name | 模型結(jié)構(gòu) |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|
## 項(xiàng)目鏈接&碼源鏈接
“中國法研杯”司法人工智能挑戰(zhàn)賽:基于UTC的多標(biāo)簽/層次分類小樣本文本應(yīng)用,Macro F1提升13%+:(https://blog.csdn.net/sinat_39620217/article/details/130760918)