使用Hugging Face的Transformers库加载预训练的BERT模型和分词器

释放双眼,带上耳机,听听看~!
本文介绍了如何使用Hugging Face的Transformers库加载预训练的BERT模型和分词器,以及相关的代码示例。

碎碎念

不知道哪年辈子订阅的书突然上架了,昨天就熬夜看了一遍,今天跑作者仓库看了一下代码。顺路参加一下金石计划。因为作者代码是两年前的了,有的已经跑不通了,所以改了改。

使用BERT预训练模型

第一节是如何使用预训练好的BERT模型,我们这里是直接使用huggingface🤗为我们提供的预训练模型。

Hugging Face 是一家人工智能公司,成立于2016年,主要致力于自然语言处理 (NLP) 技术的研究和开发。该公司的主要产品是开源软件库 Transformers,该库提供了一系列强大的预训练模型和工具,可以用于多种 NLP 任务,如文本分类、命名实体识别、问答等。

Transformers 库基于 PyTorch 和 TensorFlow 框架,提供了易于使用的 API,可以帮助开发人员快速地使用和微调预训练模型。该库还提供了许多有用的工具,如 Tokenizers、Datasets 和 Metrics,可以帮助用户更轻松地处理和分析文本数据。

除了 Transformers 库外,Hugging Face 还开发了一些其他的 NLP 工具和应用程序,如 Datasets、Tokenizers 和 Trainers 等,这些工具可以帮助开发人员更好地处理文本数据和构建自己的 NLP 模型。

代码

Ann likes to eat chocolate这个句子为例,假设需要提取句子中每个词的上下文嵌入。我们将数据集中的所有句子的标记长度设为10。

我们首先需要对句子进行标记,并将这些标记送入预训练的BERT模型,该模型将返回每个标记的嵌入。除了获得标记级(词级)的特征外,还可以获得句级的特征。

pip install transformers

使用pip安装Transformers库

from transformers import BertModel, BertTokenizer
import torch

导入必要的库模块

model = BertModel.from_pretrained('bert-base-uncased', output_hidden_states = True)
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

这是使用 Hugging Face 的 Transformers 库加载预训练的 BERT 模型和分词器的代码。

  • BertModel.from_pretrained() 方法加载了一个预训练的 BERT 模型,'bert-base-uncased' 是指加载的是 BERT 模型的基础版本(即不包含其他特定任务的微调)。output_hidden_states = True 则指定在使用该模型进行推理时,将返回所有的隐藏状态。

  • BertTokenizer.from_pretrained() 方法加载了一个与 BERT 模型相对应的分词器,'bert-base-uncased' 表示加载的是 BERT 模型的基础版本的分词器,该分词器将输入的文本转换为一系列对应的 token,以便 BERT 模型进行处理。这个分词器是用来对待处理文本进行划分和编码,使其能够与BERT模型进行输入。

sentence = 'Ann likes to eat chocolate'
tokens = tokenizer.tokenize(sentence)
tokens = ['[CLS]'] + tokens + ['[SEP]']

注意,下边这几段加特殊标签啊,attention mask啊都是可以同tokenizer完成的,这里实现一下仅仅是为了回顾一下BERT的工作流程,下一篇文章微调模型的时候就直接用tokenizer一步实现了。

这段代码使用了之前加载的 BERT 分词器,对输入的英文句子进行了分词处理。

  • 使用了tokenizer.tokenize() 方法对输入句子进行划分,将其转换为一个 token 列表

  • 添加一些特殊的标记 [CLS][SEP]

    • [CLS] 标记是 BERT 模型中用于表示句子开始的特殊标记

    • [SEP] 标记是用于表示句子结束的特殊标记。

在该代码段中,首先使用 [CLS] 标记将输入句子的开头进行标记化,然后将分词处理后的结果添加到 token 列表中,最后再添加一个 [SEP] 标记来表示句子的结尾,以便 BERT 模型能够正确地处理整个句子。

这样处理后,tokens 就是一个包含了特殊标记和分词结果的 token 列表,可以直接用作输入 BERT 模型的参数。

tokens = tokens + ['[PAD]'] + ['[PAD]'] + ['[PAD]']
attention_mask = [1 if i!= '[PAD]' else 0 for i in tokens]

我们可以看到,标记列表的开头处有一个[CLS]标记,其结尾处有一个[SEP]标记,且标记长度为5。假设需要将标记长度设为10,那么需要在列表最后添加3个[PAD]标记来满足长度要求,如下所示。

创建注意力掩码。如果标记不是[PAD],那么将注意力掩码值设置为1,否则我们将其设置为0。

token_ids = tokenizer.convert_tokens_to_ids(tokens)

token_ids = torch.tensor(token_ids).unsqueeze(0)
attention_mask = torch.tensor(attention_mask).unsqueeze(0)

将所有标记转换为它们的标记ID,将所有标记转换为它们的标记ID。

output = model(token_ids, attention_mask = attention_mask)
last_hidden_state = output.last_hidden_state
pooler_output = output.pooler_output
hidden_states = output.hidden_states

这里对人家原来的代码进行了更改,原来代码跑不通了。可能是因为随着版本更改BERT的返回值改了。

在定义模型时,我们设置了output_hidden_states = True,以获得所有编码器层的嵌入。

  • last_hidden_state包含从最后的编码器(编码器12)中获得的所有标记的特征。

  • pooler_output表示来自最后的编码器的[CLS]标记的特征,它被一个线性激活函数和tanh激活函数进一步处理。

  • hidden_states包含从所有编码器层获得的所有标记的特征。

last_hidden_state.shape

它仅有从最后的编码器(编码器12)中获得的所有标记的特征。

输出数组[1, 10, 768]表示[batch_size, sequence_length, hidden_size],其表明批量大小为1,序列长度等于标记长度,即10。隐藏层的大小等于特征向量(嵌入向量)的大小,在BERT-base模型中,其大小为768。

每个标记的嵌入如下所示。

  • last_hidden_state[0][0]给出了第1个标记[CLS]的特征。

  • last_hidden_state[0][1]给出了第2个标记Ann的特征。

  • last_hidden_state[0][2]给出了第3个标记likes的特征

pooler_output.shape

下面来看pooler_output,它包含来自最后的编码器的[CLS]标记的特征,并将被线性激活函数和tanh激活函数进一步处理。

len(hidden_states)

输出数组[1, 768]表示[batch_size, hidden_size]。前面已知,[CLS]标记持有该句子的总特征,因此,可以用pooler_output作为Ann likes to eat chocolate这个句子的特征。

hidden_states[0].shape

hidden_states包含从所有编码器层获得的所有标记的特征。它是一个包含13个值的元组,含有所有编码器层(隐藏层)的特征,即从输入嵌入层h0h_0到最后的编码器层h12h_{12}

输出数组[1, 10, 768]表示[batch_size, sequence_length, hidden_size]

有啥用?

通过这种方式,我们就可以获得所有编码器层的标记嵌入。

开头我们说:

我们首先需要对句子进行标记,并将这些标记送入预训练的BERT模型,该模型将返回每个标记的嵌入。除了获得标记级(词级)的特征外,还可以获得句级的特征。

我们认为[CLS]捕获了句子级特征,而每个词的输出是捕获到标记级(词级)的特征。

所以我们可以拿[CLS]的信息去做简单的分类任务,比如情感分析。

这是试用最后一层的嵌入,我们取之前层的嵌入可以在一些命名实体识别任务中试用。 举个栗子:

BERT的研究人员尝试了从不同的编码器层中提取嵌入。例如,对于命名实体识别任务,研究人员使用预训练的BERT模型来提取特征。他们没有只使用来自顶层编码器(最后的隐藏层)的嵌入作为特征,而是尝试使用来自其他编码器层(其他的隐藏层)的嵌入作为特征,所得到的F1分数,看👇图。

使用Hugging Face的Transformers库加载预训练的BERT模型和分词器

将最后4个编码器层(最后4个隐藏层)的嵌入连接起来可以得到最高的F1分数,即96.1。这说明可以使用其他编码器层的嵌入,而不只是提取顶层编码器(最后的隐藏层)的嵌入。

本文正在参加「金石计划」

本网站的内容主要来自互联网上的各种资源,仅供参考和信息分享之用,不代表本网站拥有相关版权或知识产权。如您认为内容侵犯您的权益,请联系我们,我们将尽快采取行动,包括删除或更正。
AI教程

基于深度学习的高精度工人安全帽检测识别系统使用教程

2023-12-18 13:51:14

AI教程

完美语言建模与人工智能:以色列巴伊兰大学教授关于语言模型的看法

2023-12-18 14:09:14

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索