应用实践:Paddle分类模型的集成者[PaddleHub、Finetune、prompt

1.基于PaddleHub下的分类模型构建

PaddleHub–API接口文档说明:遇到不知道参数设置具体情况清查接口说明!!!

https://paddlehub.readthedocs.io/zhCN/release-v2.1/apiindex.html

使用PaddleHub Fine-tune API进行Fine-tune可以分为4个步骤。

  1. 选择模型
  2. 加载数据集
  3. 选择优化策略和运行配置
  4. 执行fine-tune并评估模型

1.1 二分类模型demo

选择模型

paddlehub支持模型列表

PaddleHub还提供BERT等模型可供选择, 当前支持文本分类任务的模型对应的加载示例如下:

通过以上的一行代码,model初始化为一个适用于文本分类任务的模型,为ERNIE的预训练模型后拼接上一个全连接 络(Full Connected)。

model = hub.Module(name='ernie',task='seq-cls', num_classes=2)

hub.Module的参数用法如下:

  • name:模型名称,可以选择ernieernie_tinybert-base-casedbert-base-chinese, roberta-wwm-extroberta-wwm-ext-large等。
  • task:fine-tune任务。此处为seq-cls,表示文本分类任务。
  • num_classes:表示当前文本分类任务的类别数,根据具体使用的数据集确定,默认为2。
  • 加载数据集:

    加载官方提供数据集:选用中文情感分类公开数据集ChnSentiCorp为示例(二分类经典数据集)

    train_dataset = hub.datasets.ChnSentiCorp(tokenizer=model.get_tokenizer(), max_seq_len=128, mode='train')dev_dataset = hub.datasets.ChnSentiCorp(tokenizer=model.get_tokenizer(), max_seq_len=128, mode='dev')test_dataset = hub.datasets.ChnSentiCorp(tokenizer=model.get_tokenizer(), max_seq_len=128, mode='test')#查看数据集for i in range(10):    print(test_dataset.examples[i])

    参数问题请查看文档:
    https://paddlehub.readthedocs.io/zh

    CN/release-v2.1/api/datasets
    index.html

    ChnSentiCorp的参数用法如下:

  • tokenizer:表示该module所需用到的tokenizer,其将对输入文本完成切词,并转化成module运行所需模型输入格式。
  • mode:选择数据模式,可选项有 train, dev, test, 默认为train
  • max_seq_len:ERNIE/BERT模型使用的最大序列长度,若出现显存不足,请适当调低这一参数。
  • tokenizer的作用是将原始输入文本转化成模型model可以接受的输入数据形式。 PaddleHub 2.0中的各种预训练模型已经内置了相应的tokenizer,可以通过model.get_tokenizer方法获取。

    optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters())  # 优化器的选择和参数配置trainer = hub.Trainer(model, optimizer, checkpoint_dir='./chekpoint', use_gpu=True,use_vdl=True)        # fine-tune任务的执行者

    优化策略

    Paddle2.0-rc提供了多种优化器选择,如SGD, Adam, Adamax等,详细参见
    https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/optimizer/Overview_cn.html#about-lr

    在本教程中选择了Adam优化器,其的参数用法:

  • learning_rate: 全局学习率。默认为1e-3;
  • parameters: 待优化模型参数。
  • 运行配置
  • Trainer 主要控制Fine-tune任务的训练,是任务的发起者,包含以下可控制的参数:

  • model: 被优化模型;
  • optimizer: 优化器选择;
  • use_gpu: 是否使用gpu训练;
  • use_vdl: 是否使用vdl可视化训练过程;
  • checkpoint_dir: 保存模型参数的地址;
  • compare_metrics: 保存最优模型的衡量指标;
  • 执行fine-tune并评估模型

    trainer.train(train_dataset, epochs=3, batch_size=32, eval_dataset=dev_dataset,log_interval=10, save_interval=1)   # 配置训练参数,启动训练,并指定验证集

    trainer.train 主要控制具体的训练过程,包含以下可控制的参数:

    def train(    train_dataset: paddle.io.Dataset,    epochs: int = 1,    batch_size: int = 1,    num_workers: int = 0,    eval_dataset: paddle.io.Dataset = None,    log_interval: int = 10,    save_interval: int = 10,    collate_fn: Callable = None):
  • train_dataset: 训练时所用的数据集;
  • epochs: 训练轮数;
  • batch_size: 训练的批大小,如果使用GPU,请根据实际情况调整batch_size;
  • num_workers: works的数量,默认为0;
  • eval_dataset: 验证集;
  • log_interval: 打印日志的间隔, 单位为执行批训练的次数,推荐设置为50,100 默认值为10。
  • save_interval: 保存模型的间隔频次,单位为执行训练的轮数。
  • result = trainer.evaluate(test_dataset, batch_size=32)    # 在测试集上评估当前训练模型
    def evaluate(    eval_dataset: paddle.io.Dataset,    batch_size: int = 1,    num_workers: int = 0,    collate_fn: Callable = None):

    使用模型进行预测

    当Finetune完成后,我们加载训练后保存的最佳模型来进行预测,完整预测代码如下:

    import numpy as np# Data to be prdicteddata = [    ["这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般"],     ["交通方便;环境很好;服务态度很好 房间较小"],    ["还稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。其他要进一步验证。贴的几种膜气泡较多,用不了多久就要更换了,屏幕膜稍好点,但比没有要强多了。建议配赠几张膜让用用户自己贴。"],    ["前台接待太差,酒店有A B楼之分,本人check-in后,前台未告诉B楼在何处,并且B楼无明显指示;房间太小,根本不像4星级设施,下次不会再选择入住此店啦"],     ["19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~"]]label_map = {0: 'negative', 1: 'positive'}#加载模型model = hub.Module(    name='ernie',    task='seq-cls',    load_checkpoint='./ckpt/best_model/model.pdparams',    label_map=label_map)results = model.predict(data, max_seq_len=128, batch_size=1, use_gpu=True)for idx, text in enumerate(data):    print('Data: {} t Lable: {}'.format(text[0], results[idx]))
    Data: 这个宾馆比较陈旧了,特价的房间也很一般。总体来说一般      Lable: negativeData: 交通方便;环境很好;服务态度很好 房间较小      Lable: positiveData: 还稍微重了点,可能是硬盘大的原故,还要再轻半斤就好了。其他要进一步验证。贴的几种膜气泡较多,用不了多久就要更换了,屏幕膜稍好点,但比没有要强多了。建议配赠几张膜让用用户自己贴。      Lable: negativeData: 前台接待太差,酒店有A B楼之分,本人check-in后,前台未告诉B楼在何处,并且B楼无明显指示;房间太小,根本不像4星级设施,下次不会再选择入住此店啦      Lable: negativeData: 19天硬盘就罢工了~~~算上运来的一周都没用上15天~~~可就是不能换了~~~唉~~~~你说这算什么事呀~~~      Lable: negative

    至此二分类任务完成,需要完成程序,见文件paddlehub train 和predic文件,进行脚本运行!

    1.2 多分类任务demo

    1.2.1自定义数据集

    本示例数据集是由清华大学提供的新闻文本数据集THUCNews。THUCNews是根据新浪新闻RSS订阅频道2005~2011年间的历史数据筛选过滤生成,包含74万篇新闻文档(2.19 GB),均为UTF-8纯文本格式。我们在原始新浪新闻分类体系的基础上,重新整合划分出14个候选分类类别:财经、彩票、房产、股票、家居、教育、科技、 会、时尚、时政、体育、星座、游戏、娱乐。为了快速展示如何使用PaddleHub完成文本分类任务,该示例数据集从THUCNews训练集中随机抽取了9000条文本数据集作为本示例的训练集,从验证集中14个类别每个类别随机抽取100条数据作为本示例的验证集,测试集抽取方式和验证集相同

    如果希望使用自定义的数据集,则需要对自定义数据进行相应的预处理,将数据集文件处理成预训练模型可以读取的格式。例如用PaddleHub文本分类任务使用自定义数据时,需要切分数据集,将数据集切分为训练集、验证集和测试集。

    a. 设置数据集目录。 用户需要将数据集目录设定为如下格式。

    ├──data: 数据目录   ├── train.txt: 训练集数据   ├── dev.txt: 验证集数据   └── test.txt: 测试集数据

    b. 设置文件格式和内容。 训练集、验证集和测试集文件的编码格式建议为utf8格式。内容的第一列是文本内容,第二列为文本类别标签。列与列之间以Tab键分隔。建议在数据集文件第一行填写列说明”label”和”text_a”,中间以Tab键分隔,示例如下:

    label    text_a房产    昌平京基鹭府1029日推别墅1200万套起享97折教育    贵州2011高考录取分数线发布理科一本448分 会    众多白领因集体户口面临结婚难题
    #查看数据集%cd /home/aistudio/数据集!tar -zxvf thu_news.tar.gz!ls -hl thu_news!head -n 3 thu_news/train.txt

    c. 加载自定义数据集。 加载文本分类的自定义数据集,用户仅需要继承基类TextClassificationDataset,修改数据集存放地址以及类别即可,具体可以参考如下代码:

    # 方法二:对上述步骤精简了一下,但是出现了一些警告,不过对结果不影响,介意的话推荐用第一个from paddlehub.datasets.base_nlp_dataset import TextClassificationDatasetclass SeqClsDataset(TextClassificationDataset):    # 数据集存放目录    base_path = '/home/aistudio/数据集/thu_news'    # 数据集的标签列表    label_list=['体育', '科技', ' 会', '娱乐', '股票', '房产', '教育', '时政', '财经', '星座', '游戏', '家居', '彩票', '时尚']    def __init__(self, tokenizer, max_seq_len: int = 128, mode: str = 'train'):        if mode == 'train':            data_file = 'train.txt'        elif mode == 'test':            data_file = 'test.txt'        else:            data_file = 'dev.txt'        super().__init__(            base_path=self.base_path,            tokenizer=tokenizer,            max_seq_len=max_seq_len,            mode=mode,            data_file=data_file,            label_list=self.label_list,            is_file_with_header=True)# 选择所需要的模型,获取对应的tokenizerimport paddlehub as hubmodel = model = hub.Module(name='ernie_tiny', task='seq-cls', num_classes=len(SeqClsDataset.label_list))tokenizer = model.get_tokenizer()# 实例化训练集train_dataset = SeqClsDataset(tokenizer)

    至此用户可以通过SeqClsDataset实例化获取对应的数据集,可以通过hub.Trainer对预训练模型model完成文本分类任务

    更多关于图像分类、序列标注等数据自定义参考开发文档:
    https://github.com/PaddlePaddle/PaddleHub/blob/release/v2.0.0-rc/docs/docs
    ch/tutorial/howtoloaddata.md#
    %E5%9B%9B%E6%96%87%E6%9C%AC%E5%88%86%E7%B1%BB%E6%95%B0%E6%8D%AE%E9%9B%86

    1.2.2 训练&预测结果

    optimizer = paddle.optimizer.Adam(learning_rate=5e-5, parameters=model.parameters())  # 优化器的选择和参数配置trainer = hub.Trainer(model, optimizer, checkpoint_dir='./ckpt', use_gpu=True,use_vdl=True)  # fine-tune任务的执行者,开启可视化trainer.train(train_dataset, epochs=3, batch_size=32, eval_dataset=dev_dataset, save_interval=1)   # 配置训练参数,启动训练,并指定验证集result = trainer.evaluate(test_dataset, batch_size=32)    # 在测试集上评估当前训练模型

    训练结果部分展示:

    声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

    上一篇 2022年10月18日
    下一篇 2022年10月18日

    相关推荐