PaddleNLP预训练模型实现文本分类

为什么选择paddle?
1.paddlenlp有很多的例子和开放了很多的预训练模型,比较容易上手。
2.百度的aistudio上面的课程也比较多,都是百度NLP资深工程师授课。
3.aistudio上有免费的GPU训练数据,且只能使用paddle,阿里云GPU最低配置26元/1小时。

深度学习训练步骤:

  • 处理数据,将文本和标签转化为tokenizer_id,处理为dataset批处理方式将加快模型的训练
  • 选择损失函数和优化器
  • 构造网络模型
  • 训练数据
  • 预测数据

训练数据格式如下:

#train_data.csv
id,title,content,name
1160842,《Nature》:缬氨酸在T细胞急性淋巴细胞白血病癌症生长中起着关键作用,2021年12月31日获悉,在一项新的研究中,来自美国纽约大学朗格尼健康中心的研究人员发现作为许多动物蛋白的分子构成单元(building block),一种称为缬氨酸的氨基酸在T细胞急性淋巴细胞白血病的癌症生长中起着关键作用。他们指出参与使用细胞中缬氨酸的基因在癌症T细胞中比正常T细胞更活跃。相关研究结果于2021年12月22日在线发表在《Nature》期刊上。,科研进展
1160850,《Cancers》:天然产物β-七叶素有潜力阻止卵巢癌转移,2021年12月31日获悉,在一项新的研究中,来自美国芝加哥大学的研究人员揭示了一种天然产物对卵巢癌转移的影响。相关研究结果发表在《Cancers》期刊上。研究发现,当在小鼠的肿瘤开始生长之前或之后给予β-七叶素,可以减少卵巢癌细胞的转移扩散。,科研进展
1160898,传信生物完成天使+轮融资,加速推进管线开发和LNP生产平台建设,2022年1月1日,传信生物医药(苏州)有限公司宣布完成天使+轮融资,本轮投资由建银医疗成长基金和老股东元生创投(美元II期)共同领投,洪泰基金和老股东华盖资本参与投资。募集资金主要用于加速推进管线开发和LNP生产平台建设。,投融资
1160899,北京天星完成数亿元B轮融资,由OrbiMed(奥博资本)领投,2022年1月1日,中国企业北京天星博迈迪医疗器械有限公司近日宣布完成数亿元B轮融资,本轮融资由OrbiMed(奥博资本)领投,3W Partners跟投,现有股东君联资本继续追加投资。北京天星引入知名机构投资并获得原股东跟投,彰显了公司的卓越实力与行业头部地位。点石资本担任独家财务顾问。本轮融资将用于产品研发及市场拓展。,投融资
1160900,耐德生物完成千万元pre-A轮融资,专注于核酸快检领域的一体化检测平台,近日,青岛耐德生物技术有限公司宣布完成千万元pre-A轮融资,本轮融资的资金将主要用于手持式核酸一体化快检系统的研发落地及项目推广。本轮融资来自青岛高创投资和里程碑创投。2019年成立全资子公司青岛简码基因科技有限公司,专注于医疗产品开发和产业化,简码基因在新冠疫情期间是国内第一批完成新型冠状病毒核酸检测试剂盒的研发企业,也是国内第一批获得欧盟CE认证的企业。,投融资
1160901,拨云制药获1.3亿美元C轮融资,由鼎晖百孚领投,"2022年1月1日,拨云制药(Cloudbreak Pharma, Inc.)宣布完成1.3亿美元的C轮融资。本轮融资由鼎晖百孚领投,高特佳投资、德屹资本、建银国际、倚峰资本、关子资本、盈科资本、信银远大医疗投资、兴证资本、创东方投资、粤骏投资等多家知名机构参与。本轮融资的财务顾问由“冷杉康舟”负责,华泰联合证券担任联席财务顾问。C轮融资所获款项将用于公司多项产品管线临床试验、注册及商业化准备、GMP中试车间建设、提升公司国际化标准的生产能力和团队的扩展建设。",投融资
1160902,科塞尔医疗完成超亿元融资,由聚明创投和约印医疗基金领投,近日,科塞尔医疗科技(苏州)有限公司顺利完成超亿元融资。本轮融资由聚明创投和约印医疗基金领投,领创未来跟投。本轮融资将助力科塞尔医疗丰富外周产品管线,构建外周介入领域一站式治疗产品体系,扩大生产基地,吸纳更多、更优秀高端人才集聚。科塞尔医疗是一家具有血管介入器械全方位生产和研发能力的平台企业,致力于为临床提供系统解决方案。,投融资
1160903,至真健康完成近亿元B轮融资,由华夏恒天资本与福合永信创投联合投资,近日,北京至真互联网技术有限公司宣布完成新一轮近亿元B轮融资,由华夏恒天资本与福合永信创投联合投资。本轮融资将重点用于加大医疗服务市场开拓,以及智能硬件产品研发,持续优化升级AI算法核心能力,并将扩大AI软硬一体化解决方案在三甲医院及基层医疗服务机构的临床应用,加速在教育、保险、养老和慢病管理等场景的落地和覆盖,全面提升全医疗体系眼健康筛查水平,通过“人工智能+医疗”实现医疗资源公平化,普惠更广大群众。,投融资
1160943,睿刀医疗肝癌治疗设备临床试验成功完成第一例患者入组,2021年12月31日,上海睿刀医疗科技有限公司自主创新研发的复合陡脉冲治疗设备(REMD-G2)在首都医科大学附属北京佑安医院完成了第一例肝脏恶性肿瘤受试者入组并成功完成试验组手术,术中肿瘤消融效果良好,手术效果完全符合预期,显示了睿刀医疗不可逆电穿孔技术在肝脏肿瘤局灶消融治疗适应症领域,有着突出的临床效果和巨大优势。,公司动态
1161010,《细胞》子刊:益生肠菌罗伊氏乳杆菌能够抑制结直肠癌进展,口服或有效,近日,来自美国密歇根大学的Yatrik M. Shah和他的同事们发现,罗伊氏乳杆菌以及罗伊氏菌素能够通过消耗谷胱甘肽,来诱导结直肠癌(CRC)细胞发生氧化应激,并抑制其核糖体活性,从而抑制CRC进展。相关研究结果发表在《Cancer Cell》上。,科研进展
1161013,《Science》子刊:年轻时吃糖太多会损伤大脑,并诱发精神疾病,近日,日本东京大学医科学研究所的研究人员在《Science》子刊《Science Advances》上发表了研究论文。该研究证明了青春期时的高糖饮食诱导了精神疾病相关的行为表型,包括多动症、记忆力衰退和感觉迟钝。,科研进展
1161014,《Cancer Cell》:科研人员绘制出肝内胆管癌的多组学分子特征全景,2022年1月8日获悉,中国科学院上海药物研究所研究员周虎、中科院院士、复旦大学附属中山医院教授樊嘉、复旦大学附属中山医院教授高强,与中科院分子细胞科学卓越创新中心研究员高大明合作,在《Cancer Cell》上在线发表了研究成果。该研究对262例iCCA患者的肿瘤组织进行蛋白基因组学分析,通过整合基因组、转录组、蛋白质组、磷酸化蛋白质组等多维度数据,为肝内胆管癌的发生发展机制、分子分型、预后监测和个性化治疗策略提供了新思路。,科研进展
1161032,派尔特医疗再度冲刺港交所上市,近日,北京派尔特医疗科技股份有限公司向港交所公开递交招股书,冲刺港交所主板上市。据贝多财经了解,这已经是派尔特医疗第二次公开递表。根据招股书,派尔特医疗是智能微创外科手术解决方案提供商,主营业务包括设计、开发、制造及销售外科手术器械(专注于外科吻合器),并提供定制手术培训服务。根据介绍,派尔特医疗销售的外科手术器械主要为外科吻合器。,公司动态
1161048,《Cancer Research》:抗逆转录病毒药物有望治疗脑膜瘤和听神经瘤,2022年1月1日获悉,在一项新的研究中,来自英国普利茅斯大学的研究人员发现为治疗艾滋病/HIV感染(HIV/AIDS)而开发的抗逆转录病毒药物(ART)可能为被诊断为最常见的原发性脑瘤的患者带来希望。这一突破具有重要意义,因为如果进一步的研究有了定论,ART药物可能被开给被诊断为脑膜瘤和听神经瘤(也被称为前庭神经鞘瘤)的患者。相关研究结果在线发表在《Cancer Research》期刊上。,科研进展
1161061,南昌医疗保障局:南昌惠民保将升级上线,近日,2022年“南昌惠民保”项目正式启动。据了解,“南昌惠民保”不限年龄、不限既往症、投保门槛低、保障全面,只要是南昌市基本医疗保险参保人员(包括城镇职工和城乡居民参保人)都可投保。“南昌惠民保” 是目前南昌市唯一一款由政府指导、可使用医保个账支付,为南昌市基本医疗保险参保人专属定制,与基本医疗保障有效衔接的补充医疗保险产品。保费价格定为128元/年,保障范围涵盖自付、自费医疗费用以及十余种指定特药费用,总保额最高可达300万元。,行业动态
1161081,《临床肿瘤学杂志》:研究成果明显改善晚期肝癌患者预后生存,近日,全球癌症治疗领域权威期刊《临床肿瘤学杂志》,在线发表了中山大学肿瘤防治中心微创介入治疗科赵明教授团队的一项晚期肝癌介入治疗领域的III期临床研究(FOHAIC-1)。该研究首次在全球范围内证实基于介入技术的肝动脉灌注奥沙利铂+氟尿嘧啶方案(HAIC-FO)治疗晚期肝癌的疗效要显着优于索拉非尼靶向治疗;同时首次在基因水平上探索开发出HAIC-FO疗效预测模型,填补了中国晚期肝癌介入治疗领域和分子模型疗效预测领域的空白,为以肝动脉灌注化疗为基础的联合治疗策略提供了循证医学证据。,科研进展
1161089,《EMBO Molecular Medicine》:科研团队拓展CX5461新用途,2022年1月2日获悉,中山大学药学院(深圳)邓文斌教授、陈红波副教授和程芳副教授共同在《EMBO Molecular Medicine》上发表了研究文章。该研究发现一个核仁定位的蛋白复合体NF45/ NF90可以通过调控核糖体DNA(Ribosomal DNA, rDNA)转录影响T细胞的增殖和活化。研究者将一种rDNA特异性转录抑制剂CX5461应用在小鼠皮肤和心脏移植模型中,发现CX5461相对于临床常用药物FK506能够更有效延长移植物的存活时间,并且具有更低的毒副作用。CX5461是用于治疗携带BRCA2或PALB2突变的实体瘤患者的一个first-in-class药物。,科研进展
1161114,生物科技公司Amberstone Biosciences完成1200万美元A轮融资,用以推进其肿瘤微环境条件性激活产品管线,2022年1月3日,基于单细胞的免疫治疗发现平台和条件活性免疫治疗方面拥有独特技术的生物科技公司Amberstone Biosciences,宣布完成1200万美元的A轮融资。此次融资由知名投资机构-维亚生物创新中心(维亚生物)的风险投资部门,凯风创投以及创新工场共同领投,长融资本和其他多家新老投资人的跟投和支持。Amberstone Biosciences计划利用此次融资,将其管线中多款肿瘤微环境条件性激活的候选药物(包括双特异性抗体和细胞因子药物)推进至IND阶段。在本轮融资后,来自维亚生物创新中心的蔡小嘉博士和来自凯风创投的黄昕博士将加入公司的董事会。,投融资
1161115,四环医药:轩竹生物完成超6亿元B轮融资,由阳光人寿领投,2022月1月3日获悉,四环医药发布公告,旗下控股子公司轩竹生物在2021年12月31日完成超6亿元B轮融资,本轮融资由阳光人寿领投,倚锋资本、中冀投资、太金资本、国投泰康、海创母基金、中银资本、晋江轩弘、陕西金控、湾信资本、德诺资本、华医资本等知名投资机构跟投。凯乘资本(WinX Capital)担任本轮融资的独家财务顾问。作为四环医药集团旗下首家分拆的创新药子公司,轩竹生物将继续加大创新药研发管线的投入建设和全球布局,持续增强自主创新能力。,投融资
1161141,完美医疗大湾区新店首60日销售合同达2880.1万港元,2022年1月3日,完美医疗宣布大湾区内中环、尖沙咀及沙田最新的“医疗美容+医疗健康”服务中心(“该等服务中心”)由其开业日起首60个营业日的未经审核最新营运数据。该等服务中心于该期间的销售合同表现为2880.1万港元。集团对其于未来季度的业务表现感到乐观。,公司动态
1161142,基石药业抗体偶联药物CS5001临床试验申请获FDA批准,2022年1月3日,基石药业宣布,其抗体偶联药物(ADC)CS5001的临床试验申请(IND)已获美国食品药品监督管理局(FDA)批准。据了解,CS5001不仅是全球研发进展最快的靶向ROR1的ADC之一,更具有全球同类药物最佳潜力。此次IND获批后,基石药业即将在美国启动人体临床试验,旨在评估 CS5001在晚期B细胞淋巴瘤和实体瘤中的安全性、耐受性、药代动力学和初步抗肿瘤活性。,FDA动态
1161153,韩美制药向蔼睦医疗转让眼药Luminate在中国独家权利,2022年1月3日,蔼睦医疗宣布与韩美制药达成许可协议,蔼睦医疗获得针对治疗中期干性年龄相关性黄斑变性(Dry AMD) 及其他玻璃体视网膜疾病,同类首创玻璃体内注射产品 Risuteganib(又名 “Luminate®”) 在大中华区(包括中国大陆、香港、台湾和澳门)的独家生产、开发和商业化权利。根据协议条款,韩美制药将获得总计1.45亿美元,其中包括600万美元预付许可费,以及相关开发、注册和销售的里程碑付款。韩美还将能够从Risuteganib(Luminate®)的净销售额中按比例获得销售分成。,公司动态
1161162,《Nature Chemical Biology》:开发出可作为微型制药厂CAR-T细胞,不受T细胞衰竭影响,2022年1月3日获悉,在一项新的研究中,来自美国纪念斯隆-凯特琳癌症中心(SKI)的研究人员设计出一种全新的作为一种“微型制药厂”起作用的CAR-T细胞:它可以直接向肿瘤提供有毒的药物载荷,杀死含有癌症标志物的肿瘤细胞,以及附近不含这种标志物的癌细胞。更重要的是,CAR-T细胞即使处于衰竭状态时也能产生药物,而且所产生的药物不受癌症抑制。相关研究结果于2021年12月30日在线发表在《Nature Chemical Biology》期刊上。,科研进展

验证数据

dev_data.csv
id,title,content,name
1346133,光生物调节公司JustLight启动Sunflower Rx临床研究,治疗老年痴呆,"2022年7月5日,光生物调节公司JustLight正式启动Sunflower Rx临床研究。Sunflower Rx是一种智能光生物调节(PBM)治疗器械,用于治疗老年痴呆,其利用红光或近红外光(600–1,100nm)来治愈、修复和激活人体内的细胞。它可根据患者临床数据自动调整光照的强度和波长,也可以通过应用程序自动化控制,患者能够一个人在家中接受治疗。",科研进展
1346135,核心医疗Corheart 6人工心脏完成临床入组,2022年7月4日,核心医疗自主研发的Corheart 6植入式左心室辅助系统临床注册试验宣告全数患者入组完成。Corheart 6是一种持久性机械循环辅助装置,用于为进展期难治性左心衰患者血液循环提供机械支持,含心脏移植前或恢复心脏功能的过渡治疗。2022年1月20日,由中国医学科学院阜外医院牵头,全国12家临床研究中心共同参与的Corheart 6植入式左心室辅助系统前瞻性、多中心、单组临床评估试验正式获NMPA批准启动。,公司动态
1346135,核心医疗Corheart 6人工心脏完成临床入组,2022年7月4日,核心医疗自主研发的Corheart 6植入式左心室辅助系统临床注册试验宣告全数患者入组完成。Corheart 6是一种持久性机械循环辅助装置,用于为进展期难治性左心衰患者血液循环提供机械支持,含心脏移植前或恢复心脏功能的过渡治疗。2022年1月20日,由中国医学科学院阜外医院牵头,全国12家临床研究中心共同参与的Corheart 6植入式左心室辅助系统前瞻性、多中心、单组临床评估试验正式获NMPA批准启动。,科研进展
1346136,九典制药高端制剂研发产业园即将全面完工,或新增产值60亿,2022年7月11日获悉,九典制药高端制剂研发产业园预计10月底全面完工,达产后新增产值60亿元。据悉,九典制药高端制剂研发产业园位于浏阳经开区健康大道西侧,今年2月7日开始建设。经过数百名建设者加班加点建设,目前桩基建设已经全部完成,进入了主体施工阶段,预计10月底全面完工,11月份进行试生产,项目全面投产后新增年产值达60亿元,年利税8亿元以上。,公司动态
1346138,密歇根大学研究人员首次实现利用脑机接口控制多指运动,2022年7月4日,密歇根大学的研究人员实现了利用安装在可植入设备上的计算机解释灵长类动物精确、高速、多指运动的大脑信号。这一关键步骤的实现使那些失去肢体功能的人能够更自然、实时地控制假肢,甚至是他们自己的手。,科研进展

标签label.csv

#label.csv
label_id,label_name
"1","投融资"
"2","收购"
"3","商业合作"
"4","政策"
"5","人事变更"
"6","新品发布"
"7","产品获批"
"8","业绩发布"
"9","FDA动态"
"10","行业动态"
"11","公司动态"
"12","报告"
"13","盘点"
"14","科研进展"
"15","人物观点"
"16","会议"
"17","聚焦两会"
"18","招标公告"
"19","新型冠状病毒"
"20","中标公告"
"21","上市公司公告"

训练train.py

#train.py
from functools import partial
import argparse
import os
import random
import time
import distutils.util

import numpy as np
import paddle
import paddle.nn.functional as F
from paddlenlp.data import Stack, Tuple, Pad
from paddlenlp.transformers import AutoModelForSequenceClassification, AutoTokenizer
from paddlenlp.transformers import LinearDecayWithWarmup

from data_loader import NewsTopicDataset

# yapf: disable
parser = argparse.ArgumentParser()
parser.add_argument("--save_dir", default='./checkpoint', type=str,
                    help="The output directory where the model checkpoints will be written.")
parser.add_argument("--dataset", choices=["chnsenticorp", "xnli_cn"], default="chnsenticorp", type=str,
                    help="Dataset for classfication tasks.")
parser.add_argument("--max_seq_length", default=128, type=int,
                    help="The maximum total input sequence length after tokenization. "
                         "Sequences longer than this will be truncated, sequences shorter will be padded.")
parser.add_argument("--batch_size", default=32, type=int, help="Batch size per GPU/CPU for training.")
parser.add_argument("--learning_rate", default=5e-5, type=float, help="The initial learning rate for Adam.")
parser.add_argument("--weight_decay", default=0.0, type=float, help="Weight decay if we apply some.")
parser.add_argument("--epochs", default=3, type=int, help="Total number of training epochs to perform.")
parser.add_argument("--warmup_proportion", default=0.0, type=float,
                    help="Linear warmup proption over the training process.")
parser.add_argument("--valid_steps", default=100, type=int, help="The interval steps to evaluate model performance.")
parser.add_argument("--save_steps", default=100, type=int, help="The interval steps to save checkppoints.")
parser.add_argument("--logging_steps", default=10, type=int, help="The interval steps to logging.")
parser.add_argument("--init_from_ckpt", type=str, default=None, help="The path of checkpoint to be loaded.")
parser.add_argument("--seed", type=int, default=1000, help="random seed for initialization")
parser.add_argument('--device', choices=['cpu', 'gpu', 'xpu', 'npu'], default="cpu",
                    help="Select which device to train model, defaults to gpu.")
parser.add_argument("--use_amp", type=distutils.util.strtobool, default=False, help="Enable mixed precision training.")
parser.add_argument("--scale_loss", type=float, default=2 ** 15, help="The value of scale_loss for fp16.")
args = parser.parse_args()

# yapf: enable
def set_seed(seed):
    """sets random seed"""
    random.seed(seed)
    np.random.seed(seed)
    paddle.seed(seed)

@paddle.no_grad()
def evaluate(model, criterion, metric, data_loader):
    """
    Given a dataset, it evals model and computes the metric.

    Args:
        model(obj:`paddle.nn.Layer`): A model to classify texts.
        data_loader(obj:`paddle.io.DataLoader`): The dataset loader which generates batches.
        criterion(obj:`paddle.nn.Layer`): It can compute the loss.
        metric(obj:`paddle.metric.Metric`): The evaluation metric.
    """
    model.eval()
    metric.reset()
    losses = []
    for batch in data_loader:
        input_ids, token_type_ids, labels = batch
        logits = model(input_ids, token_type_ids)
        loss = criterion(logits, labels)
        losses.append(loss.numpy())
        correct = metric.compute(logits, labels)
        metric.update(correct)
    accu = metric.accumulate()
    print("eval loss: %.5f, accuracy: %.5f" % (np.mean(losses), accu))
    model.train()
    metric.reset()


def do_train():
    paddle.set_device(args.device)
    rank = paddle.distributed.get_rank()
    if paddle.distributed.get_world_size() > 1:
        paddle.distributed.init_parallel_env()

    set_seed(args.seed)

    model = AutoModelForSequenceClassification.from_pretrained(
        'ernie-3.0-medium-zh', num_classes=21)
    # 有21个标签,所以这里的num_classes为21
    tokenizer = AutoTokenizer.from_pretrained("ernie-3.0-medium-zh")

    batchify_fn = lambda samples, fn=Tuple(
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input
        Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # segment
        Stack(dtype="int64")  # label
    ): [data for data in fn(samples)]
    #将文本转化为id
    train_ds = NewsTopicDataset.from_file("./data/train_data.csv", tokenizer)
    train_sampler = paddle.io.RandomSampler(data_source=train_ds)
    train_batch_sampler = paddle.io.BatchSampler(sampler=train_sampler, batch_size=8)
    train_data_loader = paddle.io.DataLoader(dataset=train_ds,
                                             batch_sampler=train_batch_sampler,
                                             collate_fn=batchify_fn,
                                             return_list=True)

    dev_ds = NewsTopicDataset.from_file("./data/dev_data.csv", tokenizer)
    dev_sampler = paddle.io.RandomSampler(data_source=dev_ds)
    dev_batch_sampler = paddle.io.BatchSampler(sampler=dev_sampler, batch_size=8)
    dev_data_loader = paddle.io.DataLoader(dataset=train_ds,
                                           batch_sampler=dev_batch_sampler,
                                           collate_fn=batchify_fn,
                                           return_list=True)

    if args.init_from_ckpt and os.path.isfile(args.init_from_ckpt):
        state_dict = paddle.load(args.init_from_ckpt)
        model.set_dict(state_dict)
    model = paddle.DataParallel(model)

    num_training_steps = len(train_data_loader) * args.epochs

    lr_scheduler = LinearDecayWithWarmup(args.learning_rate, num_training_steps,
                                         args.warmup_proportion)

    # Generate parameter names needed to perform weight decay.
    # All bias and LayerNorm parameters are excluded.
    decay_params = [
        p.name for n, p in model.named_parameters()
        if not any(nd in n for nd in ["bias", "norm"])
    ]
    #设置优化器
    optimizer = paddle.optimizer.AdamW(
        learning_rate=lr_scheduler,
        parameters=model.parameters(),
        weight_decay=args.weight_decay,
        apply_decay_param_fun=lambda x: x in decay_params)
    #设置损失函数
    criterion = paddle.nn.loss.CrossEntropyLoss()

    metric = paddle.metric.Accuracy()
    if args.use_amp:
        scaler = paddle.amp.GradScaler(init_loss_scaling=args.scale_loss)
    global_step = 0
    tic_train = time.time()
    for epoch in range(1, args.epochs + 1):
        for step, batch in enumerate(train_data_loader, start=1):
            input_ids, token_type_ids, labels = batch
            with paddle.amp.auto_cast(
                    args.use_amp,
                    custom_white_list=["layer_norm", "softmax", "gelu"],
            ):
                logits = model(input_ids, token_type_ids)
                loss = criterion(logits, labels)
            probs = F.softmax(logits, axis=1)
            correct = metric.compute(probs, labels)
            metric.update(correct)
            acc = metric.accumulate()

            if args.use_amp:
                scaler.scale(loss).backward()
                scaler.minimize(optimizer, loss)
            else:
                loss.backward()
                optimizer.step()
            lr_scheduler.step()
            optimizer.clear_grad()

            global_step += 1
            if global_step % args.logging_steps == 0 and rank == 0:
                time_diff = time.time() - tic_train
                print(
                    "global step %d, epoch: %d, batch: %d, loss: %.5f, accuracy: %.5f, speed: %.2f step/s"
                    % (global_step, epoch, step, loss, acc,
                       args.logging_steps / time_diff))
                tic_train = time.time()

            if global_step % args.valid_steps == 0 and rank == 0:
                evaluate(model, criterion, metric, dev_data_loader)
                tic_train = time.time()

            if global_step % args.save_steps == 0 and rank == 0:
                save_dir = os.path.join(args.save_dir, "model_%d" % global_step)
                if not os.path.exists(save_dir):
                    os.makedirs(save_dir)
                model._layers.save_pretrained(save_dir)
                tokenizer.save_pretrained(save_dir)
                tic_train = time.time()


if __name__ == "__main__":
    do_train()

数据处理

#data_loader.py
import collections
import json
import os
import sys
from typing import Optional, List, Union, Dict
from dataclasses import dataclass

import numpy as np
import pandas as pd
import paddle
from paddlenlp.data import Stack, Tuple, Pad
from tqdm import tqdm

from paddlenlp.transformers import AutoTokenizer, PretrainedTokenizer
from paddlenlp.utils.log import logger


def convert_example_to_feature(
        example,
        tokenizer: PretrainedTokenizer,
        max_length: Optional[int] = 512,
        is_test=False):
    content = example['content']
    encoded_inputs = tokenizer(text=content, max_seq_len=max_length)
    input_ids = encoded_inputs["input_ids"]
    token_type_ids = encoded_inputs["token_type_ids"]
    if not is_test:
        label = np.array([example["label_id"]], dtype="int64")
        tokenized_output = [
            input_ids, token_type_ids, label
        ]
    else:
        tokenized_output = [
            input_ids, token_type_ids
        ]
    return tuple(tokenized_output)


class NewsTopicDataset(paddle.io.Dataset):

    def __init__(self,
                 data,
                 tokenizer2,
                 max_length=512):
        super(NewsTopicDataset, self).__init__()

        self.data = data
        self.tokenizer = tokenizer2
        self.max_seq_length = max_length

    def __len__(self):
        return len(self.data)

    def __getitem__(self, item):

        example = self.data[item]
        input_feature = convert_example_to_feature(example, self.tokenizer,
                                                   self.max_seq_length)
        return [
            np.array(input_feature[0], dtype="int64"),
            np.array(input_feature[1], dtype="int64"),
            np.array(input_feature[2], dtype="int64")
        ]

    @classmethod
    def from_file(cls,
                  file_path: Union[str, os.PathLike],
                  tokenizer: PretrainedTokenizer,
                  max_length: Optional[int] = 512):
        assert os.path.exists(file_path) and os.path.isfile(
            file_path), f"{file_path} dose not exists or is not a file."
        label_map_path = os.path.join(os.path.dirname(file_path),
                                      "label.csv")
        assert os.path.exists(label_map_path) and os.path.isfile(
            label_map_path
        ), f"{label_map_path} dose not exists or is not a file."

        header = pd.read_csv(label_map_path, nrows=0)
        head_row_list = list(header)
        csv_lists = pd.read_csv(label_map_path, usecols=head_row_list)
        lists = csv_lists.values
        label_map = {}
        for it in lists:
            label_map[it[1]] = it[0]

        header = pd.read_csv(file_path, nrows=0)
        head_row_list = list(header)
        csv_lists = pd.read_csv(file_path, usecols=head_row_list)
        lists = csv_lists.values
        data = []
        for it in lists:
            tmp = {'content': it[2],
                   'label_id': label_map.get(it[3], 0)
                   }
            data.append(tmp)

        return cls(data, tokenizer, max_length)


if __name__ == "__main__":
    tokenizer = AutoTokenizer.from_pretrained("ernie-3.0-medium-zh")
    d = NewsTopicDataset.from_file("./data/train_data.csv", tokenizer)
    sampler = paddle.io.RandomSampler(data_source=d)
    batch_sampler = paddle.io.BatchSampler(sampler=sampler, batch_size=2)

    batchify_fn = lambda samples, fn=Tuple(
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input
        Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # segment
        Stack(dtype="int64")  # label
    ): [data for data in fn(samples)]

    train_loader = paddle.io.DataLoader(dataset=d,
                                        batch_sampler=batch_sampler,
                                        collate_fn=batchify_fn,
                                        return_list=True)
    data_list = train_loader
    for i, dd in enumerate(data_list):
        print("*" * 50)
        print(dd)
        if i > 5:
            sys.exit(0)

预测模型

#predict.py
import argparse
import os
import sys

import paddle
import paddle.nn.functional as F
from paddlenlp.data import Tuple, Pad
from paddlenlp.transformers import AutoModelForSequenceClassification, AutoTokenizer

import numpy as np
import pandas as pd

from data_loader import convert_example_to_feature

# yapf: disable
parser = argparse.ArgumentParser()
parser.add_argument("--params_path", type=str, required=False, default="checkpoint/model_6000/model_state.pdparams",
                    help="The path to model parameters to be loaded.")
parser.add_argument("--label_map_path", type=str, required=False, default="./data/label.csv",
                    help="The path to model parameters to be loaded.")
parser.add_argument("--test_data_path", type=str, required=False, default="./data/test_data.csv",
                    help="The path to model parameters to be loaded.")

parser.add_argument("--max_seq_length", type=int, default=512,
                    help="The maximum total input sequence length after tokenization. "
                         "Sequences longer than this will be truncated, sequences shorter will be padded.")
parser.add_argument("--batch_size", type=int, default=32, help="Batch size per GPU/CPU for training.")
parser.add_argument('--device', choices=['cpu', 'gpu', 'xpu', 'npu'], default="cpu",
                    help="Select which device to train model, defaults to gpu.")
args = parser.parse_args()


# yapf: enable


def predict(model, data, tokenizer, label_map, batch_size=1):
    """
    Predicts the data labels.

    Args:
        model (obj:`paddle.nn.Layer`): A model to classify texts.
        data (obj:`List(Example)`): The processed data whose each element is a Example (numedtuple) object.
            A Example object contains `text`(word_ids) and `seq_len`(sequence length).
        tokenizer(obj:`PretrainedTokenizer`): This tokenizer inherits from :class:`~paddlenlp.transformers.PretrainedTokenizer` 
            which contains most of the methods. Users should refer to the superclass for more information regarding methods.
        label_map(obj:`dict`): The label id (key) to label str (value) map.
        batch_size(obj:`int`, defaults to 1): The number of batch.

    Returns:
        results(obj:`dict`): All the predictions labels.
    """
    examples = []
    for text in data:
        example = {"content": text}
        input_ids, token_type_ids = convert_example_to_feature(
            example,
            tokenizer,
            max_length=args.max_seq_length,
            is_test=True)
        examples.append((input_ids, token_type_ids))

    # Seperates data into some batches.
    batches = [
        examples[idx:idx + batch_size]
        for idx in range(0, len(examples), batch_size)
    ]
    batchify_fn = lambda samples, fn=Tuple(
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # input
        Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # segment
    ): fn(samples)

    results = []
    model.eval()
    for batch in batches:
        input_ids, token_type_ids = batchify_fn(batch)
        input_ids = paddle.to_tensor(input_ids)
        token_type_ids = paddle.to_tensor(token_type_ids)
        logits = model(input_ids, token_type_ids)
        probs = F.softmax(logits, axis=1)
        idx = paddle.argmax(probs, axis=1).numpy()
        idx = idx.tolist()
        labels = [label_map[i] for i in idx]
        print(labels)
        results.extend(labels)
    return results


if __name__ == "__main__":
    paddle.set_device(args.device)

    test_data_path = args.test_data_path
    # header = pd.read_csv(test_data_path, nrows=0)
    # head_row_list = list(header)
    csv_lists = pd.read_csv(test_data_path, usecols=["content"])
    lists = csv_lists.values
    test_list = []
    for it in lists:
        test_list.append(it[0])

    label_map_path = args.label_map_path
    header = pd.read_csv(label_map_path, nrows=0)
    head_row_list = list(header)
    csv_lists = pd.read_csv(label_map_path, usecols=head_row_list)
    lists = csv_lists.values
    label_map = {}
    for it in lists:
        label_map[it[0]] = it[1]

    model = AutoModelForSequenceClassification.from_pretrained(
        'checkpoint/model_6000', num_classes=len(label_map))
    tokenizer = AutoTokenizer.from_pretrained('checkpoint/model_6000')

    Total_params = 0
    for p in model.parameters():
        mulValue = np.prod(p.shape)  # 使用numpy prod接口计算数组所有元素之积
        Total_params += mulValue  # 总参数量
    print(f'Total params: {Total_params}')

    results = predict(model,
                      test_list,
                      tokenizer,
                      label_map,
                      batch_size=args.batch_size)
    for idx, text in enumerate(test_list):
        print('Data: {} \t Lable: {}'.format(text, results[idx]))

python train.py --device cpu

多分类:
损失函数:CrossEntropyLoss
激活函数:softmax

多标签分类(一句话有多个标签):
损失函数:BCEWithLogitsLoss
激活函数:sigmod

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,082评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,231评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,047评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,977评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,893评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,976评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,605评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,888评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,906评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,732评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,513评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,980评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,027评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,232评论 2 339

推荐阅读更多精彩内容