- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
本文通过文本分类任务演示了HuggingFace自动模型使用方法,既不需要手动计算loss,也不需要手动定义下游任务模型,通过阅读自动模型实现源码,提高NLP建模能力. 一.任务和数据集介绍 1.任务介绍 前面章节通过手动方式定义下游任务模型,HuggingFace也提供了一些常见的预定义下游任务模型,如下所示: 说明:包括预测下一个词,文本填空,问答任务,文本摘要,文本分类,命名实体识别,翻译等. 2.数据集介绍 本文使用ChnSentiCorp数据集,不清楚的可以参考 中文情感分类 介绍。一些样例如下所示: 二.准备数据集 1.使用编码工具 。 输出结果如下所示: 2.定义数据集 直接使用HuggingFace数据集对象,如下所示: 输出结果如下所示: 3.定义计算设备 。 4.定义数据整理函数 。 5.定义数据集加载器 。 输出结果如下所示: 三.加载自动模型 使用HuggingFace的AutoModelForSequenceClassification工具类加载自动模型,来实现文本分类任务,代码如下: 四.训练和测试 1.训练 需要说明自动模型本身包括loss计算,因此在train()中就不再需要手工计算loss,如下所示: 其中,out数据结构如下所示: 2.测试 。 五.深入自动模型源代码 1.加载配置文件过程 在执行 AutoModelForSequenceClassification.from_pretrained(Path(f'{pretrained_model_name_or_path}'), num_labels=2) 时,实际上调用了 AutoConfig.from_pretrained() ,该函数返回的config对象内容如下所示: config对象如下所示: (1) _name_or_path=bert-base-chinese :模型名字。 (2) attention_probs_DropOut_prob=0.1 :注意力层DropOut的比例。 (3) hidden_act=gelu :隐藏层的激活函数。 (4) hidden_DropOut_prob=0.1 :隐藏层DropOut的比例。 (5) hidden_size=768 :隐藏层神经元的数量。 (6) layer_norm_eps=1e-12 :标准化层的eps参数。 (7) max_position_embeddings=512 :句子的最大长度。 (8) model_type=bert :模型类型。 (9) num_attention_heads=12 :注意力层的头数量。 (10) num_hidden_layers=12 :隐藏层层数。 (11) pad_token_id=0 :PAD的编号。 (12) pooler_fc_size=768 :池化层的神经元数量。 (13) pooler_num_attention_heads=12 :池化层的注意力头数。 (14) pooler_num_fc_layers=3 :池化层的全连接神经网络层数。 (15) vocab_size=21128 :字典的大小. 2.初始化模型过程 BertForSequenceClassification 类构造函数包括一个BERT模型和全连接神经网络,基本思路为通过BERT提取特征,通过全连接神经网络进行分类,如下所示: 通过forward()函数可证明以上推测,根据问题类型为regression(MSELoss()损失函数)、single_label_classification(CrossEntropyLoss()损失函数)和multi_label_classification(BCEWithLogitsLoss()损失函数)选择损失函数. 参考文献: [1]HuggingFace自然语言处理详解:基于BERT中文模型的任务实战 [2]https://github.com/ai408/nlp-engineering/blob/main/20230625_HuggingFace自然语言处理详解/第12章:使用自动模型.py 。
def load_encode_tool(pretrained_model_name_or_path):
""
"
加载编码工具
"
""
tokenizer = BertTokenizer.from_pretrained(Path(f
'{pretrained_model_name_or_path}'
))
return
tokenizer
if
__name__ ==
'__main__'
:
# 测试编码工具
pretrained_model_name_or_path = r
'L:/20230713_HuggingFaceModel/bert-base-chinese'
tokenizer = load_encode_tool(pretrained_model_name_or_path)
print
(tokenizer)
BertTokenizer(name_or_path=
'L:\20230713_HuggingFaceModel\bert-base-chinese'
, vocab_size=21128, model_max_length=1000000000000000019884624838656, is_fast=False, padding_side=
'right'
, truncation_side=
'right'
, special_tokens={
'unk_token'
:
'[UNK]'
,
'sep_token'
:
'[SEP]'
,
'pad_token'
:
'[PAD]'
,
'cls_token'
:
'[CLS]'
,
'mask_token'
:
'[MASK]'
}, clean_up_tokenization_spaces=True)
def load_dataset_from_disk():
pretrained_model_name_or_path = r
'L:\20230713_HuggingFaceModel\ChnSentiCorp'
dataset = load_from_disk(pretrained_model_name_or_path)
return
dataset
if
__name__ ==
'__main__'
:
# 加载数据集
dataset = load_dataset_from_disk()
print
(dataset)
DatasetDict({
train: Dataset({
features: [
'text'
,
'label'
],
num_rows: 9600
})
validation: Dataset({
features: [
'text'
,
'label'
],
num_rows: 1200
})
test
: Dataset({
features: [
'text'
,
'label'
],
num_rows: 1200
})
})
# 定义计算设备
device =
'cpu'
if
torch.cuda.is_available():
device =
'cuda'
# print(device)
def collate_fn(data):
sents = [i[
'text'
]
for
i
in
data]
labels = [i[
'label'
]
for
i
in
data]
#编码
data = tokenizer.batch_encode_plus(batch_text_or_text_pairs=sents,
# 输入文本
truncation=True,
# 是否截断
padding=True,
# 是否填充
max_length=512,
# 最大长度
return_tensors=
'pt'
)
# 返回的类型
#转移到计算设备
for
k, v
in
data.items():
data[k] = v.to(device)
data[
'labels'
] = torch.LongTensor(labels).to(device)
return
data
# 数据集加载器
loader = torch.utils.data.DataLoader(dataset=dataset[
'train'
], batch_size=16, collate_fn=collate_fn, shuffle=True, drop_last=True)
print
(len(loader))
# 查看数据样例
for
i, data
in
enumerate(loader):
break
for
k, v
in
data.items():
print
(k, v.shape)
600
input_ids torch.Size([16, 200])
token_type_ids torch.Size([16, 200])
attention_mask torch.Size([16, 200])
labels torch.Size([16])
# 加载预训练模型
model = AutoModelForSequenceClassification.from_pretrained(Path(f
'{pretrained_model_name_or_path}'
), num_labels=2)
model.to(device)
print
(sum(i.numel()
for
i
in
model.parameters()) / 10000)
def train():
# 定义优化器
optimizer = AdamW(model.parameters(), lr=5e-4)
# 定义学习率调节器
scheduler = get_scheduler(name=
'linear'
,
# 调节器名称
num_warmup_steps=0,
# 预热步数
num_training_steps=len(loader),
# 训练步数
optimizer=optimizer)
# 优化器
# 将模型切换到训练模式
model.train()
# 按批次遍历训练集中的数据
for
i, data
in
enumerate(loader):
# print(i, data)
# 模型计算
out = model(**data)
# 计算1oss并使用梯度下降法优化模型参数
out[
'loss'
].backward()
# 反向传播
optimizer.step()
# 优化器更新
scheduler.step()
# 学习率调节器更新
optimizer.zero_grad()
# 梯度清零
model.zero_grad()
# 梯度清零
# 输出各项数据的情况,便于观察
if
i % 10 == 0:
out_result = out[
'logits'
].argmax(dim=1)
accuracy = (out_result == data.labels).sum().item() / len(data.labels)
lr = optimizer.state_dict()[
'param_groups'
][0][
'lr'
]
print
(i, out[
'loss'
].item(), lr, accuracy)
def
test
():
# 定义测试数据集加载器
loader_test = torch.utils.data.DataLoader(dataset=dataset[
'test'
],
batch_size=32,
collate_fn=collate_fn,
shuffle=True,
drop_last=True)
# 将下游任务模型切换到运行模式
model.eval()
correct = 0
total = 0
# 按批次遍历测试集中的数据
for
i, data
in
enumerate(loader_test):
# 计算5个批次即可,不需要全部遍历
if
i == 5:
break
print
(i)
# 计算
with torch.no_grad():
out = model(**data)
# 统计正确率
out = out[
'logits'
].argmax(dim=1)
correct += (out == data.labels).sum().item()
total += len(data.labels)
print
(correct / total)
BertConfig {
"_name_or_path"
:
"L:\\20230713_HuggingFaceModel\\bert-base-chinese"
,
"architectures"
: [
"BertForMaskedLM"
],
"attention_probs_dropout_prob"
: 0.1,
"classifier_dropout"
: null,
"directionality"
:
"bidi"
,
"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,
"pooler_fc_size"
: 768,
"pooler_num_attention_heads"
: 12,
"pooler_num_fc_layers"
: 3,
"pooler_size_per_head"
: 128,
"pooler_type"
:
"first_token_transform"
,
"position_embedding_type"
:
"absolute"
,
"transformers_version"
:
"4.32.1"
,
"type_vocab_size"
: 2,
"use_cache"
:
true
,
"vocab_size"
: 21128
}
def __init__(self, config):
super().__init__(config)
self.num_labels = config.num_labels
self.config = config
self.bert = BertModel(config)
classifier_dropout = (
config.classifier_dropout
if
config.classifier_dropout is not None
else
config.hidden_dropout_prob
)
self.dropout = nn.Dropout(classifier_dropout)
self.classifier = nn.Linear(config.hidden_size, config.num_labels)
# Initialize weights and apply final processing
self.post_init()
最后此篇关于使用自动模型的文章就讲到这里了,如果你想了解更多关于使用自动模型的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!