使用 Trainer API 预训练 BERT 模型时出现 ValueError
Posted
技术标签:
【中文标题】使用 Trainer API 预训练 BERT 模型时出现 ValueError【英文标题】:ValueError when pre-training BERT model using Trainer API 【发布时间】:2022-01-12 17:03:08 【问题描述】:我正在尝试使用 transformers
库中的 Trainer API 微调/预训练现有的 BERT 模型以进行情绪分析。我的训练数据集如下所示:
Text Sentiment
This was good place 1
This was bad place 0
我的目标是能够将情绪分类为正面/负面。这是我的代码:
from datasets import load_dataset
from datasets import load_dataset_builder
import datasets
import transformers
from transformers import TrainingArguments
from transformers import Trainer
dataset = load_dataset('csv', data_files='my_data.csv', sep=';')
tokenizer = transformers.BertTokenizer.from_pretrained("bert-base-cased")
model = transformers.BertForMaskedLM.from_pretrained("bert-base-cased")
print(dataset)
def tokenize_function(examples):
return tokenizer(examples["Text"], examples["Sentiment"], truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
training_args = TrainingArguments("test_trainer")
trainer = Trainer(
model=model, args=training_args, train_dataset=tokenized_datasets
)
trainer.train()
这会引发错误消息:
ValueError: text input must of type `str` (single example), `List[str]` (batch or single pretokenized example) or `List[List[str]]` (batch of pretokenized examples).
我做错了什么?非常感谢任何建议。
【问题讨论】:
我更新了我的答案,请看一下,如果有帮助请告诉我。 【参考方案1】:您需要注意以下几点才能使您的代码正常工作。
首先,您正在处理序列分类任务,特别是二进制分类,因此您需要相应地实例化您的模型:
# replace this:
# model = transformers.BertForMaskedLM.from_pretrained("bert-base-cased")
# by this:
model = transformers.BertForSequenceClassification.from_pretrained("bert-base-cased", num_labels=2)
您不应将标签 (examples["Sentiment"]
) 提供给分词器,因为它们不需要被分词:
# use only the text as input
# use padding to standardize sequence length
return tokenizer(examples["Text"], truncation=True, padding='max_length')
谈到标签,您的培训师会期望它们位于名为“标签”的列中,因此您必须相应地重命名您的“情绪”。请注意,此方法不会像您预期的那样在原地运行,它会返回一个您必须捕获的新数据集。
# for example, after you tokenized the dataset:
tokenized_datasets = tokenized_datasets.rename_column('Sentiment', 'label')
最后,您需要指定实际要用于训练的数据集的拆分。在这里,由于您没有拆分数据集,它应该只包含一个:'train'
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets['train'] # here
)
这应该会让你的代码工作,但并不意味着你会得到任何有趣的结果。由于您对使用变形金刚感兴趣,我强烈建议您查看series of notebooks by huggingface。
【讨论】:
谢谢,这解决了 OP 中的错误,但我可能需要为下一个问题提出新问题。现在它说:The following columns in the training set don't have a corresponding argument in BertForMaskedLM.forward and have been ignored: Text, Sentiment.
这给出了错误“训练集中的以下列在 BertForSequenceClassification.forward 中没有相应的参数并且已被忽略:Text.” 后跟“ValueError: Target size (torch.Size ([8])) 必须与输入大小相同 (torch.Size([8, 2]))´
第一条消息只是一个警告,它不会阻止您的代码运行。您可以通过在训练之前删除“文本”列来摆脱它,例如tokenized_datasets = tokenized_datasets.remove_columns('Text')
。很难猜测是什么触发了第二条消息。它可能来自数据集本身。你能分享文件,或从中摘录吗?
这是 CSV 文件:github.com/JereRajala00/training-data。您知道该错误消息的一般含义吗?以上是关于使用 Trainer API 预训练 BERT 模型时出现 ValueError的主要内容,如果未能解决你的问题,请参考以下文章