Transformers 从pytorch-pretrained-bert迁移 | 十
本文是全系列中第2 / 13篇:Transformers
- Transformers 词汇表 | 二
- Transformers 从pytorch-pretrained-bert迁移 | 十
- Transformers 库常见的用例 | 三
- Transformers 多语言模型 | 十一
- Transformers 中使用 TorchScript | 四
- Transformers 模型上传和共享 | 五
- Transformers 示例 | 六
- Transformers 简介(上)
- Transformers 加载预训练模型 | 七
- Transformers 简介(下)
- Transformers 保存并加载模型 | 八
- Transformers 快速入门 | 一
- Transformers 转换Tensorflow的Checkpoints | 九
作者|huggingface
编译|VK
来源|Github
这是从pytorch-pretrained-bert
迁移到transformers
时应注意的事项的快速摘要。
模型始终输出tuple
从pytorch-pretrained-bert
迁移到transformers
时,主要的突破性变化是模型forward方法始终根据模型和配置参数输出带有各种元素的tuple
。
每个模型的元组的确切内容在模型的文档字符串和文档(https://huggingface.co/transformers/)中进行了详细说明。
在几乎每种情况下,你都可以通过将输出的第一个元素用作先前在pytorch-pretrained-bert中使用的输出来正常工作。
这是BertForSequenceClassification
分类模型的pytorch-pretrained-bert
到transformers
的转换示例:
# 让我们加载模型
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
# 如果你以前在pytorch-pretrained-bert中使用此行:
loss = model(input_ids, labels=labels)
# 现在只需在transformers中使用以下代码即可从输出元组中提取loss:
outputs = model(input_ids, labels=labels)
loss = outputs[0]
# 在transformers你也可以访问logits:
loss, logits = outputs[:2]
# 将模型配置为输出注意力权重的话,可以输出注意力权重值(其他输出,也请参阅文档字符串和文档)
model = BertForSequenceClassification.from_pretrained('bert-base-uncased', output_attentions=True)
outputs = model(input_ids, labels=labels)
loss, logits, attentions = outputs
序列化
from_pretrained()
方法的重大变化:
- 现在,在使用
from_pretrained()
方法实例化时,默认情况下将模型设置为评估模式。要训练它们,不要忘记将它们重新设置为训练模式(model.train()
)以激活dropout模块。 -
提供给
from_pretrained()
方法的附加*inputs
和** kwargs
参数通常直接传递给基础模型的类__init __()方法。现在,它们可用于首先更新模型配置属性,这可以突破先前的BertForSequenceClassification
示例构建的派生模型类。更确切地说,提供给from_pretrained()
的位置参数* inputs
被直接转发给model的__init __()
方法,而与配置类属性匹配的关键字参数** kwargs
:(i)匹配配置类属性用于更新所述属性(ii)与任何配置类属性都不匹配的属性被转发到model的__init __()
方法。
同样,虽然没有什么大的变化,但是序列化方法已经标准化,如果以前使用过任何其他序列化方法,则可能应该切换到新方法save_pretrained(save_directory)
。
这是一个例子:
###让我们加载模型和令牌生成器
model = BertForSequenceClassification.from_pretrained('bert-base-uncased')
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
### 对我们的模型和令牌生成器做一些事情
# 例如: 将新标记添加到模型的词汇表和嵌入中
tokenizer.add_tokens(['[SPECIAL_TOKEN_1]', '[SPECIAL_TOKEN_2]'])
model.resize_token_embeddings(len(tokenizer))
# 训练模型
train(model)
### 现在让我们将模型和tokenizer保存到目录中
model.save_pretrained('./my_saved_model_directory/')
tokenizer.save_pretrained('./my_saved_model_directory/')
### 重新加载模型和tokenizer
model = BertForSequenceClassification.from_pretrained('./my_saved_model_directory/')
tokenizer = BertTokenizer.from_pretrained('./my_saved_model_directory/')
优化程序:BertAdam和OpenAIAdam现在是AdamW,日程表是标准的PyTorch日程表
以前包括的两个优化器,BertAdam
和OpenAIAdam
,已由单个的AdamW
优化器代替,但有一些区别:
– 仅实现权重衰减校正,
– schedules现在是外部的(请参阅下文),
– 梯度裁剪现在也是外部的(请参阅下文)。
新的优化器AdamW
与PyTorchAdam
优化器API匹配,可让你使用标准的PyTorch或apex方法进行schedule和裁剪。
现在,这些schedules已成为标准的PyTorch学习率调度程序,现在不再是优化程序的一部分。
以下是转换示例:
# 参数:
lr = 1e-3
max_grad_norm = 1.0
num_training_steps = 1000
num_warmup_steps = 100
warmup_proportion = float(num_warmup_steps) / float(num_training_steps) # 0.1
### 以前,BertAdam优化器是这样实例化的:
optimizer = BertAdam(model.parameters(), lr=lr, schedule='warmup_linear', warmup=warmup_proportion, t_total=num_training_steps)
### 并像这样使用:
for batch in train_data:
loss = model(batch)
loss.backward()
optimizer.step()
### 在“Transformer”中,优化器和schedules按如下方式拆分和实例化:
optimizer = AdamW(model.parameters(), lr=lr, correct_bias=False) # 要重现BertAdam特定的行为,请设置correct_bias = False
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=num_warmup_steps, num_training_steps=num_training_steps) # PyTorch调度程序用法如下:
for batch in train_data:
model.train()
loss = model(batch)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_grad_norm) # 梯度裁剪不再在AdamW中了(因此你可以毫无问题地使用放大器)
optimizer.step()
scheduler.step()
optimizer.zero_grad()
原文链接:https://huggingface.co/transformers/migration.html
原创文章,作者:磐石,如若转载,请注明出处:https://panchuang.net/2020/04/29/transformers-%e4%bb%8epytorch-pretrained-bert%e8%bf%81%e7%a7%bb-%e5%8d%81/