【NLP】第 6 章 :微调预训练模型

2023-11-20

到目前为止,我们已经了解了如何使用包含预训练模型的huggingface API 来创建简单的应用程序。如果您可以从头开始并仅使用您自己的数据来训练您自己的模型,那不是很棒吗?

如果您没有大量空闲时间或计算资源可供使用,那么使用迁移学习 是最有效的策略。与在训练模型时从头开始相比,使用 Hugging Face 的迁移学习有两个主要优点。

正如我们在第4章中所述,像GPT3 这样的模型需要大量的基础设施资源来训练。这超出了我们大多数人的能力。那么我们如何以更灵活的方式使用这些模型,而不仅仅是通过下载预训练模型来使用它们呢?答案在于使用我们拥有的额外数据对这些模型进行微调。与从头开始训练完整的大型语言模型相比,这将需要很少的资源并且很容易实现。

要将基本模型转变为能够产生可靠结果的模型,需要投入大量时间和资源。由于迁移学习 ,您可以放弃费力的训练步骤,只需花费少量时间来根据您的特定要求调整数据集。

事实上,Hugging Face 的预训练模型能够在各种领域的任务中表现出色,甚至不需要额外的微调。人们很可能也可以在零样本学习 场景中使用这些模型,但是如果有一个特定的数据集,那么我们的好朋友 huggingface API 会为我们提供微调这些现有模型所需的抽象.

因此,我们基本上可以认为迁移学习 是训练的一种捷径。只需使用预训练的语言模型,您就可以在计算需求方面节省数万美元和数千小时。你应该坚持迁移学习,除非你正在处理的任务非常具体并且无法使用已经存在的模型来解决。

我们现在可以继续使用Hugging Face 进行微调指南 ,因为我们对迁移学习的应用和优势有了更好的理解。

微调的工作流程 如下所示:

  • 从 huggingface 中选择适合您的用例需求的预训练模型。

  • 额外的自定义数据集必须遵守 huggingface 数据集规范,因此我们需要预处理我们的数据,使其符合所需的格式。

  • 将数据集上传到 Colab、S3 或任何其他存储。

  • 使用 huggingface 的 Trainer API 微调现有模型。

  • 在本地保存模型或将其上传到 huggingface 存储库。

有了一些基本的想法,让我们开始使用 Hugging Face 库进行一些迁移学习。

在微调阶段,大部分神经结构 被冻结。这意味着我们只调整输出层的权重。由于我们已经在前面的章节中介绍了分词器,因此我们将在此处简要概述 huggingface 数据集,这是本章最重要的结构。了解数据集 API 后,我们将继续通过迁移学习将自定义数据集用于预训练模型。

数据集

在本节中,我们描述了 huggingface 的基本数据集 构造及其一些基本功能。

您在任何机器学习项目的整个过程中使用的数据都将非常重要。真正的准确性不仅取决于数量,还取决于所使用数据的质量,无论您使用何种算法或模型,这一点都是正确的。

访问大型数据集有时可能是一项具有挑战性的工作。以适当的方式抓取、积累然后清理这些数据的过程可能会花费大量时间。Hugging Face 对于对 NLP 以及图像和音频处理感兴趣的人来说是幸运的,它带有一个已经准备好使用的数据集的中央存储库。在以下段落中,我们将简要介绍如何使用此数据集 模块来为您的项目选择和准备合适的数据集。

要安装数据集库,请使用以下命令:

!pip 安装数据集

在阅读数据集 存储库的文档时,我们发现有几种主要方法。第一种方法是我们能够用来调查现成的数据集列表的方法。您应该会看到处理近 6800 个不同数据集的选项,所有这些数据集当前都可用:

from datasets import list_datasets, load_dataset, list_metrics, load_metric
# 打印所有可用的数据集
print(len(list_datasets()))

DatasetDict({ train: Dataset({ features: ['text', 'label'], num_rows: 25000 }) test: Dataset({ features: ['text', 'label'], num_rows: 25000 }) unsupervised: 数据集({ features: ['text', 'label'], num_rows: 50000 }) })

它构成了一个包含训练、测试和无监督数据集的字典 ,每个数据集都具有特征和 num_rows 作为值。这里,示例取自 IMDB 数据集,因此我们将对其进行情感分析的文本也取自 IMDB。

让我们访问火车数据集:

dataset['train'][2]

dataset['train'][2]

{'label': 0, 'text': "If only to avoid making this type of film in the future. This film is interesting as an experiment but tells no cogent story.<br /><br />One might feel virtuous for sitting thru it because it touches on so many IMPORTANT issues but it does so without any discernable motive. The viewer comes away with no new perspectives (unless one comes up with one while one's mind wanders, as it will invariably do during this pointless film).<br /><br />One might better spend one's time staring out a window at a tree growing.<br /><br />"}

描述数据集:

dataset['train'].description

我们得到以下 输出:

Large Movie Review Dataset.\nThis is a dataset for binary sentiment classification containing substantially more data than previous benchmark datasets. We provide a set of 25,000 highly polar movie reviews for training, and 25,000 for testing. There is additional unlabeled data for use as well.

列出数据集的特征:

dataset['train'].features

我们可以看到有两个特点:

{'label': ClassLabel(num_classes=2, names=['neg', 'pos'], id=None), 'text': Value(dtype='string', id=None)}

在某些情况下,您可能不想处理使用 Hugging Face 数据集之一。除了其他类型的文件之外,此数据集对象仍然能够加载本地存储的CSV 文件。 例如,如果您想使用 CSV 文件,您可以轻松地将此信息连同本地计算机上 CSV 文件的路径传递到加载数据集方法。

微调预训练模型

现在既然我们了解了数据集构造,就该使用我们自己的数据集在预训练模型上应用一些迁移学习了。在下文中,我们将展示如何使用 IMDB 数据集微调预训练模型的示例。

我们将微调方面分为两部分。训练部分是我们将使用 huggingface 的Trainer API 微调模型并保存的地方。另一部分是推理部分,我们将在其中加载这个微调模型以实现推理。

微调训练

首先,使用以下命令安装转换 器和数据集:

!pip install datasets transformers

接下来,加载 IMDB 数据集:

from datasets import load_dataset
dataset = load_dataset("imdb")
dataset["train"][100]

以下是评论范例:

{'label': 0, 'text': "Terrible movie. Nuff Said.<br /><br />These Lines are Just Filler. The movie was bad. Why I have to expand on that I don't know. This is already a waste of my time. I just wanted to warn others. Avoid this movie. The acting sucks and the writing is just moronic. Bad in every way. Even that was ruined though by a terrible and unneeded rape scene. The movie is a poorly contrived and totally unbelievable piece of garbage.<br /><br />OK now I am just going to rag on IMDb for this stupid rule of 10 lines of text minimum. First I waste my time watching this offal. Then feeling compelled to warn others I create an account with IMDb only to discover that I have to write a friggen essay on the film just to express how bad I think it is. Totally unnecessary."}

接下来,我们需要使用 BERT 分词器对加载的数据集进行分词。 第一步是在Google Colab 中新建一个 Jupyter notebook,逐行复制以下代码:

from transformers import AutoTokenizer
brt_tkn = AutoTokenizer.from_pretrained("bert-base-cased")
def generate_tokens_for_imdb(examples):
    return brt_tkn(examples["text"], padding="max_length", truncation=True)
tkn_datasets = dataset.map(generate_tokens_for_imdb, batched=True)

上述代码产生 以下输出:

loading configuration file https://huggingface.co/bert-base-cased/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/a803e0468a8fe090683bdc453f4fac622804f49de86d7cecaee92365d4a0f829.a64a22196690e0e82ead56f388a3ef3a50de93335926ccfa20610217db589307

Model config BertConfig {

"_name_or_path": "bert-base-cased",

"architectures": [

"BertForMaskedLM"

],

"attention_probs_dropout_prob": 0.1,

"classifier_dropout": null,

"gradient_checkpointing": false,

"hidden_act": "gelu",

"hidden_dropout_prob": 0.1,

"hidden_size": 768,

"initializer_range": 0.02,

"intermediate_size": 3072,

"layer_norm_eps": 1e-12,

"max_position_embeddings": 512,

"model_type": "bert",

"num_attention_heads": 12,

"num_hidden_layers": 12,

"pad_token_id": 0,

"position_embedding_type": "absolute",

"transformers_version": "4.20.1",

"type_vocab_size": 2,

"use_cache": true,

"vocab_size": 28996

}

loading file https://huggingface.co/bert-base-cased/resolve/main/vocab.txt from cache at /root/.cache/huggingface/transformers/6508e60ab3c1200bffa26c95f4b58ac6b6d95fba4db1f195f632fa3cd7bc64cc.437aa611e89f6fc6675a049d2b5545390adbc617e7d655286421c191d2be2791

loading file https://huggingface.co/bert-base-cased/resolve/main/tokenizer.json from cache at /root/.cache/huggingface/transformers/226a307193a9f4344264cdc76a12988448a25345ba172f2c7421f3b6810fddad.3dab63143af66769bbb35e3811f75f7e16b2320e12b7935e216bd6159ce6d9a6

loading file https://huggingface.co/bert-base-cased/resolve/main/added_tokens.json from cache at None

loading file https://huggingface.co/bert-base-cased/resolve/main/special_tokens_map.json from cache at None

loading file https://huggingface.co/bert-base-cased/resolve/main/tokenizer_config.json from cache at /root/.cache/huggingface/transformers/ec84e86ee39bfe112543192cf981deebf7e6cbe8c91b8f7f8f63c9be44366158.ec5c189f89475aac7d8cbd243960a0655cfadc3d0474da8ff2ed0bf1699c2a5f

loading configuration file https://huggingface.co/bert-base-cased/resolve/main/config.json from cache at /root/.cache/huggingface/transformers/a803e0468a8fe090683bdc453f4fac622804f49de86d7cecaee92365d4a0f829.a64a22196690e0e82ead56f388a3ef3a50de93335926ccfa20610217db589307

Model config BertConfig {

"_name_or_path": "bert-base-cased",

"architectures": [

"BertForMaskedLM"

],

"attention_probs_dropout_prob": 0.1,

"classifier_dropout": null,

"gradient_checkpointing": false,

"hidden_act": "gelu",

"hidden_dropout_prob": 0.1,

"hidden_size": 768,

"initializer_range": 0.02,

"intermediate_size": 3072,

"layer_norm_eps": 1e-12,

"max_position_embeddings": 512,

"model_type": "bert",

"num_attention_heads": 12,

"num_hidden_layers": 12,

"pad_token_id": 0,

"position_embedding_type": "absolute",

"transformers_version": "4.20.1",

"type_vocab_size": 2,

"use_cache": true,

"vocab_size": 28996

}

一旦我们标记 了数据集,我们将只对 200 个样本进行微调,以便我们可以为了简单起见更快地调整模型。我们鼓励您尝试更多样本:

training_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(200))
evaluation_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(200))

加载基于 BERT 的序列分类模型:

from transformers import AutoModelForSequenceClassification
mdl = AutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=2)

Transformers 库 包含一个Trainer 类 ,专门用于训练 huggingface transformer 模型。此类使开始训练变得更加简单,而无需手动编写自己的代码。Trainer API 提供日志记录、监控等功能。

在这里,我们通过实例化一个名为 TrainingArguments 的类来提供训练参数 ,该类具有可以试验的所有超参数 。在这种情况下,我们将只使用默认值:

from transformers import TrainingArguments
training_args = TrainingArguments(output_dir="imdb")

在训练期间,Trainer 不会自动评估模型的执行情况。如果您希望 Trainer 能够计算和报告指标,则需要向其传递 一个函数。这就是我们将在以下代码段中执行的操作:

import numpy as np
from datasets import load_metric
mdl_metrics = load_metric("accuracy")
def calculate_metrics(eval_pred):
    logits, labels = eval_pred
    predictions = np.argmax(logits, axis=-1)
    return mdl_metrics.compute(predictions=predictions, references=labels)
from transformers import TrainingArguments, Trainer
trng_args = TrainingArguments(output_dir="test_trainer", evaluation_strategy="epoch", num_train_epochs=3)

实例化一个 Trainer 对象,其中包含您的模型、训练参数、用于训练和测试的数据集 以及评估函数:

Mdl_trainer = Trainer(
    model=model,
    args=trng_args,
    train_dataset=training_dataset,
    eval_dataset=evaluation_dataset,
    compute_metrics=calculate_metrics,
)

训练模型:

trainer.train()

6-1显示了我们用于微调现有预训练模型的 IMDB 数据集的训练 运行。

图 6-1 IMDB 数据集 的训练运行以进行微调

保存经过微调的训练模型:

trainer.save_model()

图 6-2 在本地保存模型(我们有一个基于 PyTorch 的模型,扩展名为 .bin)

我们可以看到微调后的模型以名称pytorch_model.bin 保存。

我们可以使用以下代码检查模型的准确性 :

metrics = mdl_trainer.evaluate(evaluation_dataset)
trainer.log_metrics("eval", metrics)
trainer.save_metrics("eval", metrics)

图 6-3 根据精度评估 微调模型

推理

一旦我们微调 了模型并保存了它,就可以对训练数据集之外的数据进行推理了。

我们将从路径加载微调模型并使用它进行分类,在本例中是对 IMDB 电影评论的情感分类 :

PATH = 'test_trainer/'
md = AutoModelForSequenceClassification.from_pretrained(PATH, local_files_only=True)
def make_classification(text):
    # 分词
    inps = brt_tkn(text, padding=True, truncation=True, max_length=512, return_tensors="pt").to("cuda")
    # 获取输出
    outputs = model(**inps)
    # 用于生成概率的 softmax
    probablities = outputs[0].softmax(1)
    # 获得最佳匹配。
    return probablities .argmax()
Here is the first inference:
text = """
This is the show that puts a smile on your face as you watch it. You get in love with each and every character of the show. At the end, I felt eight episode were not enough. Will wait for season 2.
"""
print(make_classification(text))

这会产生以下输出:

tensor(1, device='cuda:0')

Output of 1 is positive review

这是第二个推论:

text = """
It was fun to watch but It did not impress that much I think i waste my money popcorn time pizza burgers everything.
Akshay should make only comedy movies these King type movies suits on king like personality of actors Total waste.
"""
print(make_classification(text))

这会产生以下 输出:

tensor(0, device='cuda:0')

Output of zero is negative review

概括

在本章中,我们了解了huggingface 数据集 及其不同的功能。我们还学习了如何使用huggingface API 对现有的预训练模型与其他数据集进行微调。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【NLP】第 6 章 :微调预训练模型 的相关文章

  • matlab调用cuda中的cublas对矩阵进行求逆

    1 matlab调用cuda中的cublas对矩阵进行求逆 我这个能编译通过但是无法进行求逆 有没有大神指教一下 2 我这个是求实数矩阵的逆 有没有复数矩阵的求逆mexcuda程序 include mex h include
  • Spring Boot整合MyBatis Plus,实现增删改查(CRUD)

    前言 软件开发中 无论我们身处什么行业 如 金融 电商 医疗 政府 电信等行业 底层实现都离不开数据库的增删改查操作 每个程序开发人员的工作也离不开CRUD 下面通过Spring Boot整合MyBatis Plus来实现数据库的增删改查操

随机推荐

  • VS2022创建动态运行库(DLL)和隐式调用

    创建动态运行库 一 打开VS2022 新建一个DLL工程 二 在项目中新建一个头文件 输入以下代码 pragma once ifdef BUILD DLL 当源文件中有 define BUILD DLL时执行dllexport BUILD
  • 高德地图实现聚合点功能实例

    在进地图API开发时 有时会出现海量数据展示 这里就不得不使用聚合点功能 减少页面初始化过程中加载过多数据而导致卡顿现象 这里通过高德地图API为例 通过简单实例 带大家了解下聚合点实现方法 一 引入相关资源
  • 网站架构探测&chrome插件用于信息收集

    文章目录 0x01 网站架构探测 云悉 潮汐指纹 0x02 chrome插件用于信息收集 添加插件的方法 官网添加方法 开发者模式添加 Wappalyzer 下载方法 功能 FOFA Pro view 下载方法 ModHeader 0x01
  • 博客搭建二:NexT主题相关设置beta

    安装NexT 在你的博客根目录 git clone https github com iissnan hexo theme next themes next 不同版本的NexT配置文件略有不同 本次使用的是hexo theme next 7
  • 多线程(九):JUC组件

    在来时juc组件前 我们先把上一章遗漏的部分给补上 synchronized 实现策略 锁升级 无锁 gt 偏向锁 gt 轻量级锁 gt 重量级锁 还有一个 锁消除 锁消除即删除不必要的加锁操作 JVM在运行时 对一些 在代码上要求同步 但
  • sort快速排序

    sort快速排序 使用sort必须要有相应的头文件 include
  • 中标麒麟系统把玩记录

    1 指令发送邮件 echo content mail vs this is title a a sh XXX XX com 其中 content代表发送的内容 thisistitle代表邮件主题 a sh为附件 2 开机运行脚本 在etc
  • 田忌赛马java代码算法,AcWing 1489. 田忌赛马——Java版代码

    import java io import java util public class 田忌赛马 public static void main String args throws IOException BufferedReader
  • Thrift快速入门

    文章目录 Thrift的安装 windows下安装 Linux下安装 Thrift的使用 编写IDL文件 命名空间 namespace 基本数据类型 类型定义 typedef 结构体类型 struct 枚举类型 enum 异常类型 exce
  • MybatisX简介

    MybatisX简介 前言 一 什么是MybatisX 二 如何使用 1 安装插件 2 创建一个mybatis项目或者于项目中引入mybatis依赖 3 快速生成示例 3 1 快速生成mapper方法 3 2 MybatisX Genera
  • 使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异(R语言)

    使用lattice包的bwplot函数绘制箱图比较多个模型在不同指标上的性能差异 R语言 箱图是一种常用的数据可视化方法 用于表示一组数据的分布特征 包括中位数 四分位数 异常值等 在比较多个模型在多个指标上的性能差异时 箱图可以提供直观的
  • NCCL相关笔记

    本文仅代表个人观点 不保证正确性 一 NCCL简介 1 什么是NCCL NCCL是NVIDIA集合通信库 NVIDIA Collective Communications Library 的简称 是用于加速多GPU之间通信的库 能够实现集合
  • #css# 【四】如何使用hover,实现父对子的样式改变?

    css 如何使用hover 实现父对子的样式改变 思路及做法 鼠标移动到父盒子的时候 里面所有的子盒子的样式都发生变化的 只需要直接在hover后面加上空格 并且加上子盒子的类名 里面再写其他样式 父盒子的类名 hover 子盒子的类名 这
  • iOS系统网络抓包方法

    原文地址 http www cnblogs com ydhliphonedev archive 2011 10 27 2226935 html 在进行iOS开发过程中 经常会遇到各种各样的网络访问问题 以前苦于没有抓包工具 很多网络问题解决
  • 【python-opencv】硬币检测

    使用 python3 8 x opencv 硬币检测 问题描述 设计思路1 使用简单特征识别 具体操作 部分代码 设计思路2 模板匹配 源码 模板制作 完整代码 问题描述 使用图像处理技术 从照片中识别硬币的个数 并判断总价值 设计思路1
  • ESP32开发阶段启用 Secure Boot 与 Flash encryption

    Secure Boot 与 Flash encryption详情 请参考 https blog csdn net espressif article details 79362094 1 开发环境 AT版本 2 4 0 0 发布 IDF 与
  • git忽略文件地址

    git忽略文件地址 Objective C gitignore gitignore
  • String和StringBuffer的常见用法

    链接 https www nowcoder com questionTerminal fe6b651b66ae47d7acce78ffdd9a96c7 answerType 1 f discussion来源 牛客网 String的用法 ja
  • dubbo配置提供者和消费者

    1 找到对应的文件 提供者 消费者 参考dubbo官网 http dubbo apache org zh cn docs user quick start html
  • 【NLP】第 6 章 :微调预训练模型

    到目前为止 我们已经了解了如何使用包含预训练模型的huggingface API 来创建简单的应用程序 如果您可以从头开始并仅使用您自己的数据来训练您自己的模型 那不是很棒吗 如果您没有大量空闲时间或计算资源可供使用 那么使用迁移学习 是最