HuggingFace课程笔记:使用BERT进行Token分类任务详解

HuggingFace课程笔记:使用BERT进行Token分类任务详解

course The Hugging Face course on Transformers course 项目地址: https://gitcode.com/gh_mirrors/cou/course

什么是Token分类任务

Token分类是自然语言处理中的一项基础任务,它要求模型为输入文本中的每个token分配一个类别标签。这类任务在实际应用中非常广泛,主要包括以下几种典型场景:

  1. 命名实体识别(NER):识别文本中的人名、地名、组织机构名等实体
  2. 词性标注(POS):标注每个词的语法类别(名词、动词、形容词等)
  3. 组块分析(Chunking):识别文本中的短语组块

这些任务虽然具体目标不同,但都可以抽象为"为每个token分配标签"的问题框架。本文将基于HuggingFace课程内容,详细介绍如何使用BERT模型在NER任务上进行微调。

数据集准备:CoNLL-2003

我们使用经典的CoNLL-2003数据集,它包含新闻文本,已经标注了命名实体标签。数据集的特点包括:

  • 文本以单词列表形式提供(已预分词)
  • 包含三种标注:NER、POS和组块分析
  • 训练集14,041条,验证集3,250条,测试集3,453条

NER标签采用BIO标注方案:

  • O:非实体词
  • B-PER/I-PER:人名开始/内部
  • B-ORG/I-ORG:组织名开始/内部
  • B-LOC/I-LOC:地名开始/内部
  • B-MISC/I-MISC:其他实体开始/内部

数据处理关键步骤

1. Tokenizer的特殊处理

由于数据集已经预分词,我们需要特别注意:

  • 使用is_split_into_words=True参数告诉tokenizer输入已分词
  • 处理子词分词带来的标签对齐问题
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
inputs = tokenizer(raw_datasets["train"][0]["tokens"], is_split_into_words=True)

2. 标签对齐策略

当单词被分成子词时,我们需要调整标签:

  1. 特殊token([CLS]、[SEP])标记为-100(损失计算时忽略)
  2. 子词继承原单词的标签
  3. 对于B-开头的内部子词,改为I-前缀
def align_labels_with_tokens(labels, word_ids):
    new_labels = []
    current_word = None
    for word_id in word_ids:
        if word_id != current_word:
            current_word = word_id
            label = -100 if word_id is None else labels[word_id]
            new_labels.append(label)
        elif word_id is None:
            new_labels.append(-100)
        else:
            label = labels[word_id]
            if label % 2 == 1:  # B-标签转为I-
                label += 1
            new_labels.append(label)
    return new_labels

3. 批量处理数据集

使用Dataset.map()方法高效处理整个数据集:

def tokenize_and_align_labels(examples):
    tokenized_inputs = tokenizer(
        examples["tokens"], truncation=True, is_split_into_words=True
    )
    all_labels = examples["ner_tags"]
    new_labels = []
    for i, labels in enumerate(all_labels):
        word_ids = tokenized_inputs.word_ids(i)
        new_labels.append(align_labels_with_tokens(labels, word_ids))
    
    tokenized_inputs["labels"] = new_labels
    return tokenized_inputs

tokenized_datasets = raw_datasets.map(
    tokenize_and_align_labels,
    batched=True,
    remove_columns=raw_datasets["train"].column_names,
)

模型训练准备

数据收集器(Data Collator)

不同于普通任务,我们需要专门的数据收集器来处理标签填充:

from transformers import DataCollatorForTokenClassification
data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)

该收集器会:

  1. 动态填充每个batch到最长序列长度
  2. 对标签进行与输入相同的填充处理(使用-100)

训练技巧与注意事项

  1. 评估指标:通常使用精确率、召回率和F1值,特别是对实体级别的评估
  2. 长序列处理:注意模型的最大长度限制(BERT通常为512)
  3. 类别不平衡:实体词远少于普通词,可能需要调整损失权重
  4. 子词影响:长实体被切分为多个子词可能影响识别效果

总结

本文详细介绍了使用HuggingFace生态系统进行Token分类任务的全流程,重点解决了预分词数据与子词tokenizer的兼容性问题。通过合理的标签对齐策略和专门的数据处理工具,我们可以有效利用预训练模型如BERT来解决NER等序列标注任务。这种方法不仅适用于CoNLL-2003数据集,也可以方便地迁移到其他自定义的Token分类任务中。

course The Hugging Face course on Transformers course 项目地址: https://gitcode.com/gh_mirrors/cou/course

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俞兰莎Rosalind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值