本项目链接:基于Ernie3。0CAIL2019法研杯要素识别多标签分类任务 (https:aistudio。baidu。comaistudioprojectdetail4280922?contributionType1) 本项目将介绍如何基于PaddleNLP对ERNIE3。0预训练模型微调完成法律文本多标签分类预测。本项目主要包括什么是多标签文本分类预测、ERNIE3。0模型、如何使用ERNIE3。0中文预训练模型进行法律文本多标签分类预测等三个部分。1。什么是多标签文本分类预测 文本多标签分类是自然语言处理(NLP)中常见的文本分类任务,文本多标签分类在各种现实场景中具有广泛的适用性,例如商品分类、网页标签、新闻标注、蛋白质功能分类、电影分类、语义场景分类等。多标签数据集中样本用来自nclasses个可能类别的m个标签类别标记,其中m的取值在0到nclasses之间,这些类别具有不相互排斥的属性。通常,我们将每个样本的标签用Onehot的形式表示,正类用1表示,负类用0表示。例如,数据集中样本可能标签是A、B和C的多标签分类问题,标签为〔1,0,1〕代表存在标签A和C而标签B不存在的样本。 近年来,随着司法改革的全面推进,以公开为原则,不公开为例外的政策逐步确立,大量包含了案件事实及其适用法律条文信息的裁判文书逐渐在互联网上公开,海量的数据使自然语言处理技术的应用成为可能。法律条文的组织呈树形层次结构,现实中的案情错综复杂,同一案件可能适用多项法律条文,涉及数罪并罚,需要多标签模型充分学习标签之间的关联性,对文本进行分类预测。2。ERNIE3。0模型 ERNIE3。0首次在百亿级预训练模型中引入大规模知识图谱,提出了海量无监督文本与大规模知识图谱的平行预训练方法(UniversalKnowledgeTextPrediction),通过将知识图谱挖掘算法得到五千万知识图谱三元组与4TB大规模语料同时输入到预训练模型中进行联合掩码训练,促进了结构化知识和无结构文本之间的信息共享,大幅提升了模型对于知识的记忆和推理能力。 ERNIE3。0框架分为两层。第一层是通用语义表示网络,该网络学习数据中的基础和通用的知识。第二层是任务语义表示网络,该网络基于通用语义表示,学习任务相关的知识。在学习过程中,任务语义表示网络只学习对应类别的预训练任务,而通用语义表示网络会学习所有的预训练任务。 ERNIE3。0模型框架3。ERNIE3。0中文预训练模型进行法律文本多标签分类预测3。1环境准备 AIStudio平台默认安装了Paddle和PaddleNLP,并定期更新版本。如需手动更新Paddle,可参考飞桨安装说明,安装相应环境下最新版飞桨框架。使用如下命令确保安装最新版PaddleNLP:3。2加载法律文本多标签数据 本数据集(2019年法研杯要素识别任务)来自于中国裁判文书网公开的法律文书,每条训练数据由一份法律文书的案情描述片段构成,其中每个句子都被标记了对应的类别标签,数据集一共包含20个标签,标签代表含义如下:DV10婚后有子女DV21限制行为能力子女抚养DV32有夫妻共同财产DV43支付抚养费DV54不动产分割DV65婚后分居DV76二次起诉离婚DV87按月给付抚养费DV98准予离婚DV109有夫妻共同债务DV1110婚前个人财产DV1211法定离婚DV1312不履行家庭义务DV1413存在非婚生子DV1514适当帮助DV1615不履行离婚协议DV1716损害赔偿DV1817感情不和分居满二年DV1918子女随非抚养权人生活DV2019婚后个人财产 数据集示例:textlabels所以起诉至法院请求变更两个孩子均由原告抚养,被告承担一个孩子抚养费每月600元。0,7,3,12014年8月原、被告因感情不和分居,2014年10月16日被告文某某向务川自治县人民法院提起离婚诉讼,被法院依法驳回了离婚诉讼请求。6,5女儿由原告抚养,被告每月支付小孩抚养费500元;0,7,3,1 使用本地文件创建数据集,自定义readcustomdata()函数读取数据文件,传入loaddataset()创建数据集,返回数据类型为MapDataset。更多数据集自定方法详见如何自定义数据集。自定义数据集importrefrompaddlenlp。datasetsimportloaddatasetdefcleantext(text):texttext。replace(r,)。replace(,)textre。sub(rn,。,text)returntext定义读取数据集函数defreadcustomdata(istestFalse,isonehotTrue):filenum6ifistestelse48文件个数filepathrawdatatestifistestelserawdatatrainforiinrange(filenum):fopen({}labeled{}。txt。format(filepath,i))whileTrue:linef。readline()ifnotline:breakdataline。strip()。split()标签用Onehot表示ifisonehot:labels〔float(1)ifstr(i)indata〔1〕。split(,)elsefloat(0)foriinrange(20)〕else:labels〔int(d)fordindata〔1〕。split(,)〕yield{text:cleantext(data〔0〕),labels:labels}f。close()labelvocab{0:婚后有子女,1:限制行为能力子女抚养,2:有夫妻共同财产,3:支付抚养费,4:不动产分割,5:婚后分居,6:二次起诉离婚,7:按月给付抚养费,8:准予离婚,9:有夫妻共同债务,10:婚前个人财产,11:法定离婚,12:不履行家庭义务,13:存在非婚生子,14:适当帮助,15:不履行离婚协议,16:损害赔偿,17:感情不和分居满二年,18:子女随非抚养权人生活,19:婚后个人财产}loaddataset()创建数据集traindsloaddataset(readcustomdata,istestFalse,lazyFalse)testdsloaddataset(readcustomdata,istestTrue,lazyFalse)lazyFalse,数据集返回为MapDataset类型print(数据类型:,type(trainds))labels为Onehot标签print(训练集样例:,trainds〔0〕)print(测试集样例:,testds〔0〕)数据类型:classpaddlenlp。datasets。dataset。MapDataset训练集样例:{text:2013年11月28日原、被告离婚时自愿达成协议,婚生子张某乙由被告李某某抚养,本院以(2013)宝渭法民初字第01848号民事调解书对该协议内容予以了确认,该协议具有法律效力,对原、被告双方均有约束力。,labels:〔1。0,1。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0〕}测试集样例:{text:综上,原告现要求变更女儿李乙抚养关系的请求,本院应予支持。,labels:〔1。0,1。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0,0。0〕}3。3加载中文ERNIE3。0预训练模型和分词器 PaddleNLP中Auto模块(包括AutoModel,AutoTokenizer及各种下游任务类)提供了方便易用的接口,无需指定模型类别,即可调用不同网络结构的预训练模型。PaddleNLP的预训练模型可以很容易地通过frompretrained()方法加载,Transformer预训练模型汇总包含了40多个主流预训练模型,500多个模型权重。 AutoModelForSequenceClassification可用于多标签分类,通过预训练模型获取输入文本的表示,之后将文本表示进行分类。PaddleNLP已经实现了ERNIE3。0预训练模型,可以通过一行代码实现ERNIE3。0预训练模型和分词器的加载。加载中文ERNIE3。0预训练模型和分词器frompaddlenlp。transformersimportAutoModelForSequenceClassification,AutoTokenizermodelnameernie3。0basezhnumclasses20modelAutoModelForSequenceClassification。frompretrained(modelname,numclassesnumclasses)tokenizerAutoTokenizer。frompretrained(modelname)3。4基于预训练模型的数据处理 Dataset中通常为原始数据,需要经过一定的数据处理并进行采样组batch。通过Dataset的map函数,使用分词器将数据集从原始文本处理成模型的输入。定义paddle。io。BatchSampler和collatefn构建paddle。io。DataLoader。 实际训练中,根据显存大小调整批大小batchsize和文本最大长度maxseqlength。importfunctoolsimportnumpyasnpfrompaddle。ioimportDataLoader,BatchSamplerfrompaddlenlp。dataimportDataCollatorWithPadding数据预处理函数,利用分词器将文本转化为整数序列defpreprocessfunction(examples,tokenizer,maxseqlength):resulttokenizer(textexamples〔text〕,maxseqlenmaxseqlength)result〔labels〕examples〔labels〕returnresulttransfuncfunctools。partial(preprocessfunction,tokenizertokenizer,maxseqlength128)traindstrainds。map(transfunc)testdstestds。map(transfunc)collatefn函数构造,将不同长度序列充到批中数据的最大长度,再将数据堆叠collatefnDataCollatorWithPadding(tokenizer)定义BatchSampler,选择批大小和是否随机乱序,进行DataLoadertrainbatchsamplerBatchSampler(trainds,batchsize64,shuffleTrue)testbatchsamplerBatchSampler(testds,batchsize64,shuffleFalse)traindataloaderDataLoader(datasettrainds,batchsamplertrainbatchsampler,collatefncollatefn)testdataloaderDataLoader(datasettestds,batchsamplertestbatchsampler,collatefncollatefn)3。5数据训练和评估 定义训练所需的优化器、损失函数、评价指标等,就可以开始进行预模型微调任务。importtimeimportpaddle。nn。functionalasFfrommetricimportMultiLabelReport文件在根目录下Adam优化器、交叉熵损失函数、自定义MultiLabelReport评价指标optimizerpaddle。optimizer。AdamW(learningrate1e4,parametersmodel。parameters())criterionpaddle。nn。BCEWithLogitsLoss()metricMultiLabelReport()fromevalimportevaluateepochs5训练轮次ckptdirernieckpt训练过程中保存模型参数的文件夹globalstep0迭代次数tictraintime。time()bestf1score0forepochinrange(1,epochs1):forstep,batchinenumerate(traindataloader,start1):inputids,tokentypeids,labelsbatch〔inputids〕,batch〔tokentypeids〕,batch〔labels〕计算模型输出、损失函数值、分类概率值、准确率、f1分数logitsmodel(inputids,tokentypeids)losscriterion(logits,labels)probsF。sigmoid(logits)metric。update(probs,labels)auc,f1score,,metric。accumulate()auc,f1score,precison,recall每迭代10次,打印损失函数值、准确率、f1分数、计算速度globalstep1ifglobalstep100:print(globalstepd,epoch:d,batch:d,loss:。5f,auc:。5f,f1score:。5f,speed:。2fsteps(globalstep,epoch,step,loss,auc,f1score,10(time。time()tictrain)))tictraintime。time()反向梯度回传,更新参数loss。backward()optimizer。step()optimizer。cleargrad()每迭代40次,评估当前训练的模型、保存当前最佳模型参数和分词器的词表等ifglobalstep400:savedirckptdirifnotos。path。exists(savedir):os。makedirs(savedir)evalf1scoreevaluate(model,criterion,metric,testdataloader,labelvocab,ifreturnresultsFalse)ifevalf1scorebestf1score:bestf1scoreevalf1scoremodel。savepretrained(savedir)tokenizer。savepretrained(savedir) 模型训练过程中会输出如下日志:globalstep770,epoch:4,batch:95,loss:0。04217,auc:0。99446,f1score:0。92639,speed:0。61stepsglobalstep780,epoch:4,batch:105,loss:0。03375,auc:0。99591,f1score:0。92674,speed:0。98stepsglobalstep790,epoch:4,batch:115,loss:0。04217,auc:0。99530,f1score:0。92483,speed:0。80stepsglobalstep800,epoch:4,batch:125,loss:0。05338,auc:0。99534,f1score:0。92467,speed:0。67stepsevalloss:0。05298,auc:0。99185,f1score:0。90312,precison:0。90031,recall:0。90596〔2022072716:31:27,917〕〔INFO〕tokenizerconfigfilesavedinernieckpttokenizerconfig。json〔2022072716:31:27,920〕〔INFO〕Specialtokensfilesavedinernieckptspecialtokensmap。jsonglobalstep810,epoch:4,batch:135,loss:0。04668,auc:0。99509,f1score:0。91319,speed:0。59stepsglobalstep820,epoch:4,batch:145,loss:0。04317,auc:0。99478,f1score:0。91696,speed:0。98stepsglobalstep830,epoch:4,batch:155,loss:0。04573,auc:0。99488,f1score:0。91815,speed:0。80stepsglobalstep840,epoch:4,batch:165,loss:0。05505,auc:0。99465,f1score:0。91753,speed:0。65stepsevalloss:0。05352,auc:0。99234,f1score:0。89713,precison:0。88058,recall:0。91432globalstep850,epoch:4,batch:175,loss:0。03971,auc:0。99626,f1score:0。92391,speed:0。76stepsglobalstep860,epoch:4,batch:185,loss:0。04622,auc:0。99593,f1score:0。91806,speed:0。97stepsglobalstep870,epoch:4,batch:195,loss:0。04128,auc:0。99587,f1score:0。91959,speed:0。77stepsglobalstep880,epoch:4,batch:205,loss:0。06053,auc:0。99566,f1score:0。92041,speed:0。63stepsevalloss:0。05234,auc:0。99220,f1score:0。90272,precison:0。89108,recall:0。91466。。。3。6多标签分类预测结果预测 加载微调好的模型参数进行情感分析预测,并保存预测结果fromevalimportevaluate模型在测试集中表现model。setdict(paddle。load(ernieckptmodelstate。pdparams))也可以选择加载预先训练好的模型参数结果查看模型训练结果model。setdict(paddle。load(ernieckpttrainedmodelstate。pdparams))print(ERNIE3。0在法律文本多标签分类test集表现,end)resultsevaluate(model,criterion,metric,testdataloader,labelvocab)ERNIE3。0在法律文本多标签分类test集表现evalloss:0。05298,auc:0。99185,f1score:0。90312,precison:0。90031,recall:0。90596testdsloaddataset(readcustomdata,istestTrue,isonehotFalse,lazyFalse)resdir。resultsifnotos。path。exists(resdir):os。makedirs(resdir)withopen(os。path。join(resdir,multilabel。tsv),w,encodingutf8)asf:f。write(textprediction)fori,predinenumerate(results):f。write(testds〔i〕〔text〕pred) 法律多标签文本预测结果示例: 4。总结 相关项目: Paddlenlp之UIE模型实战实体抽取任务【打车数据、快递单】 Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案) 应用实践:分类模型大集成者〔PaddleHub、Finetune、prompt〕 Paddlenlp之UIE关系抽取模型【高管关系抽取为例】 PaddleNLP基于ERNIR3。0文本分类以中医疗搜索检索词意图分类(KUAKEQIC)为例【多分类(单标签)】 基于ERNIR3。0文本分类:CAIL2018SMALL罪名预测为例(多标签) 本项目主要讲解了法律任务,和对性能指标的简单探讨,可以看到实际更多问题是关于多标签分类的。 ChinaAILawChallenge(CAIL)中国法研杯司法人工智能挑战赛本项目数据集:https:github。comchinaailawchallengeCAIL2019treemasterE8A681E7B4A0E8AF86E588AB 数据集自取: 欢迎大家关注我的主页:https:aistudio。baidu。comaistudiousercenter 以及博客:https:blog。csdn。netsinat39620217?typeblog