提问人:evader110 提问时间:11/15/2023 最后编辑:evader110 更新时间:11/15/2023 访问量:50
我应该如何预处理此数据集以执行“问答”任务?皮火炬
How should I preprocess this dataset for performing a "Question-Answering" task? Pytorch
问:
所以我有一个 JSON 数据集,其格式如下:
[{
"answer": "...",
"question": "...",
"context": "..."
},
...
]
所有字段都是普通的纯文本。我的目标是在它上面训练一个预训练的 BERT 模型,用于“问答”任务。在查看 HuggingFace 文档时,格式似乎需要与 Squad 数据集格式匹配,上下文需要修剪到最多 394 个字符,并且需要添加 [CLS] 和其他标记之类的内容。
当尝试关注文档时,我会访问此站点进行问题解答,它们提供了一个示例函数来进行预处理。为简单起见,此处提供:
def preprocess_function(examples):
questions = [q.strip() for q in examples["question"]]
inputs = tokenizer(
questions,
examples["context"],
max_length=384,
truncation="only_second",
return_offsets_mapping=True,
padding="max_length",
)
offset_mapping = inputs.pop("offset_mapping")
answers = examples["answers"]
start_positions = []
end_positions = []
for i, offset in enumerate(offset_mapping):
answer = answers[i]
start_char = answer["answer_start"][0]
end_char = answer["answer_start"][0] + len(answer["text"][0])
sequence_ids = inputs.sequence_ids(i)
# Find the start and end of the context
idx = 0
while sequence_ids[idx] != 1:
idx += 1
context_start = idx
while sequence_ids[idx] == 1:
idx += 1
context_end = idx - 1
# If the answer is not fully inside the context, label it (0, 0)
if offset[context_start][0] > end_char or offset[context_end][1] < start_char:
start_positions.append(0)
end_positions.append(0)
else:
# Otherwise it's the start and end token positions
idx = context_start
while idx <= context_end and offset[idx][0] <= start_char:
idx += 1
start_positions.append(idx - 1)
idx = context_end
while idx >= context_start and offset[idx][1] >= end_char:
idx -= 1
end_positions.append(idx + 1)
inputs["start_positions"] = start_positions
inputs["end_positions"] = end_positions
return inputs
使用以下示例代码:
from transformers import AutoTokenizer
from datasets import Dataset
dataset = Dataset.from_pandas(df) # where df is a 3 column Dataframe Object | answer | question | context |
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
tokenized_ds = dataset.map(preprocess_function, batched=True)
当我尝试运行它时,我收到以下错误。
File "c:/project.py", line 234, in preprocess_function
inputs = tokenizer(
TypeError: 'list' object is not callable
所以我的问题是:这只是我的一个愚蠢的错误,还是我应该尝试以不同的方式预处理这个数据集?我是 HuggingFace 和 NLP 的新手,所以我把这个作为一个有趣的项目来做。提前致谢!
更新 1:更仔细地遵循教程,我将我的数据放入 Datasets 对象并正确使用了 map 函数,但现在它说分词器是一个问题,因为它与教程中使用的分词器完全相同。TypeError: 'list' object is not callable
答:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")
questions = dataset['question'].tolist()
contexts = dataset['context'].tolist()
qas = preprocess_function({"question": questions, "context": contexts}, tokenizer)
评论
自己解决了!我的解决方案:
将 df 加载到 Datasets 对象中,以便我可以实际调用 map 函数
在预处理函数上方全局声明分词器
感谢这个问题的帮助
更改预处理函数以匹配我的数据集。
answers = examples["answers"]
-->answers = examples["answer"]
创建
contexts = examples["context"]
start_char = answer["answer_start"][0]
end_char = answer["answer_start"][0] + len(answer["text"][0])
-->
start_char = contexts[i].find(answer)
end_char = start_char + len(answer)
评论