NLP transformers - token 分类

文章目录

    • 加载 WNUT 17 数据集
    • 预处理
    • Evaluate
    • Train
    • 推理


  • 本文翻译整理自:https://huggingface.co/docs/transformers/tasks/token_classification
  • video : https://youtu.be/iY2AZYdZAr0

标记分类为句子中的各个标记分配标签。最常见的标记分类任务之一是命名实体识别 (NER)。 NER 尝试为句子中的每个实体查找标签,例如人、位置或组织。

本指南将向您展示如何:

  1. 在WNUT 17数据集上微调DistilBERT以检测新实体。
  2. 使用您的微调模型进行推理。

在开始之前,请确保已安装所有必需的库:

pip install transformers datasets evaluate seqeval

我们鼓励您登录 Hugging Face 帐户,以便您可以上传模型并与社区分享。出现提示时,输入您的令牌进行登录:

from huggingface_hub import notebook_login

notebook_login()

加载 WNUT 17 数据集

首先从 🤗 数据集库加载 WNUT 17 数据集:

from datasets import load_dataset

wnut = load_dataset("wnut_17")

然后看一个数据样例:

wnut["train"][0]

{'id': '0',
 'ner_tags': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 8, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0],
 'tokens': ['@paulwalk', 'It', "'s", 'the', 'view', 'from', 'where', 'I', "'m", 'living', 'for', 'two', 'weeks', '.', 'Empire', 'State', 'Building', '=', 'ESB', '.', 'Pretty', 'bad', 'storm', 'here', 'last', 'evening', '.']
}

每个数字ner_tags代表一个实体。将数字转换为其标签名称 以找出实体是:

label_list = wnut["train"].features[f"ner_tags"].feature.names
label_list

[
    "O",
    "B-corporation",
    "I-corporation",
    "B-creative-work",
    "I-creative-work",
    "B-group",
    "I-group",
    "B-location",
    "I-location",
    "B-person",
    "I-person",
    "B-product",
    "I-product",
]

每个前缀的字母ner_tag表示实体的标记位置:

  • B-表示实体的开始。
  • I-表示令牌包含在同一实体内(例如,State令牌是实体的一部分,如 Empire State Building)。
  • 0表示该 token 不对应于任何实体。

预处理

下一步是加载 DistilBERT 分词器来预处理该tokens字段:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")

正如您在上面的示例tokens字段中看到的,看起来输入已经被tokenized。

但输入实际上尚未被标记化,您需要设置is_split_into_words=True将单词标记为子词。例如:

example = wnut["train"][0]
tokenized_input = tokenizer(example["tokens"], is_split_into_words=True)
tokens = tokenizer.convert_ids_to_tokens(tokenized_input["input_ids"])
tokens
['[CLS]', '@', 'paul', '##walk', 'it', "'", 's', 'the', 'view', 'from', 'where', 'i', "'", 'm', 'living', 'for', 'two', 'weeks', '.', 'empire', 'state', 'building', '=', 'es', '##b', '.', 'pretty', 'bad', 'storm', 'here', 'last', 'evening', '.', '[SEP]']

然而,这会添加一些特殊的标记[CLS][SEP],并且子词tokenization 会在输入和标签之间造成不匹配。

对应于单个标签的单个单词 现在可以被分成两个子单词。您需要通过以下方式重新对齐标记和标签:

  1. 使用 word_ids 方法将 所有tokens 映射到其相应的单词。
  2. 将标签分配-100给特殊标记[CLS][SEP],因此 PyTorch 损失函数会忽略它们(请参阅CrossEntropyLoss)。
  3. 仅标记给定单词的第一个标记。分配-100给同一单词的其他子标记。

以下是如何创建一个函数来重新对齐标记和标签,并将序列截断为不长于 DistilBERT 的最大输入长度:

def tokenize_and_align_labels(examples):
    tokenized_inputs = tokenizer(examples["tokens"], truncation=True, is_split_into_words=True)

    labels = []
    for i, label in enumerate(examples[f"ner_tags"]):
        word_ids = tokenized_inputs.word_ids(batch_index=i)  # Map tokens to their respective word.
        previous_word_idx = None
        label_ids = []
        for word_idx in word_ids:  # Set the special tokens to -100.
            if word_idx is None:
                label_ids.append(-100)
            elif word_idx != previous_word_idx:  # Only label the first token of a given word.
                label_ids.append(label[word_idx])
            else:
                label_ids.append(-100)
            previous_word_idx = word_idx
        labels.append(label_ids)

    tokenized_inputs["labels"] = labels
    return tokenized_inputs

要将预处理函数 应用于整个数据集,请使用 🤗 数据集map函数。您可以通过设置 batched=True 一次处理数据集的多个元素来加速该map函数:

tokenized_wnut = wnut.map(tokenize_and_align_labels, batched=True)

现在使用 DataCollatorWithPadding创建一批示例。在整理过程中动态地将句子填充 到 批次中的最长长度,比将 整个数据集 填充到 最大长度 更有效。


from transformers import DataCollatorForTokenClassification

data_collator = DataCollatorForTokenClassification(tokenizer=tokenizer)

Evaluate

在训练期间包含指标通常有助于评估模型的性能。您可以使用 🤗 Evaluate库快速加载评估方法。对于此任务,加载seqeval框架(请参阅 🤗 评估快速浏览以了解有关如何加载和计算指标的更多信息)。

Seqeval 实际上会产生几个分数:精确度、召回率、F1 和准确度。

import evaluate

seqeval = evaluate.load("seqeval")

首先获取 NER 标签,然后创建一个 传递真实预测 和真实标签的函数 给 compute 来计算分数:

import numpy as np

labels = [label_list[i] for i in example[f"ner_tags"]]


def compute_metrics(p):
    predictions, labels = p
    predictions = np.argmax(predictions, axis=2)

    true_predictions = [
        [label_list[p] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]
    true_labels = [
        [label_list[l] for (p, l) in zip(prediction, label) if l != -100]
        for prediction, label in zip(predictions, labels)
    ]

    results = seqeval.compute(predictions=true_predictions, references=true_labels)
    return {
        "precision": results["overall_precision"],
        "recall": results["overall_recall"],
        "f1": results["overall_f1"],
        "accuracy": results["overall_accuracy"],
    }

您的 compute_metrics 函数现在已准备就绪,您将在设置训练时返回该函数。


Train

在开始训练模型之前,请使用 id2labellabel2id 创建 预期 id 到其标签的映射:

id2label = {
    0: "O",
    1: "B-corporation",
    2: "I-corporation",
    3: "B-creative-work",
    4: "I-creative-work",
    5: "B-group",
    6: "I-group",
    7: "B-location",
    8: "I-location",
    9: "B-person",
    10: "I-person",
    11: "B-product",
    12: "I-product",
}
label2id = {
    "O": 0,
    "B-corporation": 1,
    "I-corporation": 2,
    "B-creative-work": 3,
    "I-creative-work": 4,
    "B-group": 5,
    "I-group": 6,
    "B-location": 7,
    "I-location": 8,
    "B-person": 9,
    "I-person": 10,
    "B-product": 11,
    "I-product": 12,
}

如果您不熟悉使用 Trainer微调模型,请查看此处的基本教程!

您现在就可以开始训练您的模型了!使用AutoModelForTokenClassification加载 DistilBERT以及预期标签的数量和标签映射:

from transformers import AutoModelForTokenClassification, TrainingArguments, Trainer

model = AutoModelForTokenClassification.from_pretrained(
    "distilbert/distilbert-base-uncased", num_labels=13, id2label=id2label, label2id=label2id
)

此时,只剩下三步:

  1. 在 TrainingArguments中定义训练超参数。唯一必需的参数是output_dir指定保存模型的位置。您可以通过设置 push_to_hub=True 将此模型推送到 Hub (您需要登录 Hugging Face 才能上传模型)。在每个 epoch 结束时,Trainer将评估 seqeval 分数并保存训练检查点。
  2. 将训练参数 以及模型、数据集、分词器、数据整理器和 compute_metrics 函数传递给 Trainer 。
  3. 调用train() 来微调您的模型。
training_args = TrainingArguments(
    output_dir="my_awesome_wnut_model",
    learning_rate=2e-5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    num_train_epochs=2,
    weight_decay=0.01,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    load_best_model_at_end=True,
    push_to_hub=True,
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_wnut["train"],
    eval_dataset=tokenized_wnut["test"],
    tokenizer=tokenizer,
    data_collator=data_collator,
    compute_metrics=compute_metrics,
)

trainer.train()

训练完成后,使用 push_to_hub()方法将您的模型共享到 Hub,以便每个人都可以使用您的模型:

trainer.push_to_hub()

有关如何微调标记分类模型的更深入示例,请查看相应的 PyTorch 笔记本 或TensorFlow 笔记本。


推理

太好了,现在您已经微调了模型,您可以使用它进行推理!

获取一些您想要进行推理的文本:

text = "The Golden State Warriors are an American professional basketball team based in San Francisco."

尝试微调模型进行推理的最简单方法是在pipeline()中使用它。使用您的模型实例化pipelinefor NER,并将您的文本传递给它:

from transformers import pipeline

classifier = pipeline("ner", model="stevhliu/my_awesome_wnut_model")
classifier(text)


[{'entity': 'B-location',
  'score': 0.42658573,
  'index': 2,
  'word': 'golden',
  'start': 4,
  'end': 10},
 {'entity': 'I-location',
  'score': 0.35856336,
  'index': 3,
  'word': 'state',
  'start': 11,
  'end': 16},
 {'entity': 'B-group',
  'score': 0.3064001,
  'index': 4,
  'word': 'warriors',
  'start': 17,
  'end': 25},
 {'entity': 'B-location',
  'score': 0.65523505,
  'index': 13,
  'word': 'san',
  'start': 80,
  'end': 83},
 {'entity': 'B-location',
  'score': 0.4668663,
  'index': 14,
  'word': 'francisco',
  'start': 84,
  'end': 93}]

pipeline如果您愿意,您还可以手动复制结果:


对文本进行分词 并返回 PyTorch 张量:

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("stevhliu/my_awesome_wnut_model")
inputs = tokenizer(text, return_tensors="pt")

将您的输入传递给模型并返回logits

from transformers import AutoModelForTokenClassification

model = AutoModelForTokenClassification.from_pretrained("stevhliu/my_awesome_wnut_model")
with torch.no_grad():
    logits = model(**inputs).logits

获取概率最高的类,并使用模型的id2label映射将其转换为文本标签:

predictions = torch.argmax(logits, dim=2)
predicted_token_class = [model.config.id2label[t.item()] for t in predictions[0]]
predicted_token_class

['O',
 'O',
 'B-location',
 'I-location',
 'B-group',
 'O',
 'O',
 'O',
 'O',
 'O',
 'O',
 'O',
 'O',
 'B-location',
 'B-location',
 'O',
 'O']

2024-04-29(一)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/583332.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux详解:进程等待

文章目录 进程等待等待的必要性进程等待的方法waitwaitpid获取子进程status阻塞等待 与 非阻塞等待 进程等待 等待的必要性 子进程退出,父进程不进行回收的话,就可能造成僵尸进程,进而造成内存泄露 如果进程进入了僵尸状态,kill…

机器学习:驱动现代交通运输革命的AI智慧引擎

🧑 作者简介:阿里巴巴嵌入式技术专家,深耕嵌入式人工智能领域,具备多年的嵌入式硬件产品研发管理经验。 📒 博客介绍:分享嵌入式开发领域的相关知识、经验、思考和感悟,欢迎关注。提供嵌入式方向…

玄子Share-引导过程与服务控制

玄子Share-引导过程与服务控制 Linux操作系统引导过程 系统初始化进程 init 进程 由 Linux 内核加载运行 /sbin/init 程序init 进程是系统中第一个进程init 进程的 PID(进程标记)号永远为 1 Systemd Systemd是Linux操作系统的一种init软件CentOS7中采用…

【Linux开发 第十二篇】搭建JavaEE环境

搭建开发环境 搭建javaEE环境 搭建javaEE环境 在Linux下开发JavaEE需要安装软件包: 安装jdk 安装步骤: 在opt目录下创建jdk目录通过xftp上床到jdk目录中进入到jdk目录中,解压jdk压缩包在/usr/local下创建java目录将解压完成的jdk文件移动…

SpringBoot框架学习笔记(一):依赖管理和自动配置

本文为个人笔记,仅供学习参考之用,如有不当之处请指出。 本文基于springboot2.5.3版本,开发环境需要是 jdk 8 或以上,maven 在 3.5 1 SpringBoot 基本介绍 1.1 官方文档 (1) 官网 : https://spring.io/pr…

张朝阳对话华为Fellow陈海波:万物智联时代,鸿蒙如何实现“换道超车”?

随着智能终端设备的普及和万物智联时代的加速到来,鸿蒙生态的高速发展正引发全行业的关注。 搜狐创始人、董事局主席兼CEO、物理学博士张朝阳与华为Fellow、基础软件首席科学家陈海波带来了一场关于鸿蒙生态的公开课。鸿蒙技术架构有哪些领先性?HarmonyOS发布5年来…

compose调用系统分享功能分享图片文件

compose调用系统分享功能图片文件 简介UI界面提供给外部程序的文件访问权限创建FileProvider设置共享文件夹 通用分享工具虚拟机验证结果参考 本系列用于新人安卓基础入门学习笔记,有任何不同的见解欢迎留言 运行环境 jdk17 andriod 34 compose material3 简介 本案…

Hadoop3:集群搭建及常用命令与shell脚本整理(入门篇,从零开始搭建)

一、集群环境说明 1、用VMware安装3台Centos7.9虚拟机 2、虚拟机配置:2C,2G内存,50G存储 3、集群架构 从表格中,可以看出,Hadoop集群,主要有2部分,一个是HDFS服务,一个是YARN服务 …

[系统安全] 六十.威胁狩猎 (1)APT攻击检测及防御与常见APT组织的攻击案例分析

您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列。因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全、逆向分析和恶意代码检测,“系统安全”系列文章会更加聚焦,更加系…

四、管道与重定向

四、管道与重定向 1 重定向 0,标准输入(键盘) 1,标准输出 2,标准错误, 3,进程在执行过程中打开的其他文件。 &:表示正确错误混合输出1.1 输出重定向 (覆盖,追加) > ----覆盖 >> ----追加 正确输出: 1> 1>> 等价…

Git 仓库内容操作

Git 仓库内容操作 | CoderMast编程桅杆Git 仓库内容操作 添加文件到暂存区 使用如下指令将工作区的文件添加到暂存区,告诉 Git 在下次 commit 时哪些文件做出了修改。 commit 指令详看后续 添加一个或多个文件到暂存区: 添加指定目录到暂存区 添加当前目…

ffmpeg与sdl的个人笔记

说明 这里的ffmpeg基础知识和sdl基础知识仅提及与示例代码相关的知识点, 进阶可学习雷神的博客。 https://blog.csdn.net/leixiaohua1020 当然,如代码写的有问题或有更好的见解,欢迎指正! 音视频基础知识 在学习音视频理论知识时&#xff…

CSS中设置透明度的2个属性:opacity,RGBA以及它们的区别

你好,我是云桃桃。 一个希望帮助更多朋友快速入门 WEB 前端的程序媛。 云桃桃-大专生,一枚程序媛,感谢关注。回复 “前端基础题”,可免费获得前端基础 100 题汇总,回复 “前端工具”,可获取 Web 开发工具合…

试用了三个Ai音乐工具,我的偶像河图要完蛋了

试了三个生成音乐的ai工具,分别是爆火的suno,后期新秀udio,还有我们国内的天工。 先说感受,suno和天工我觉得稍微靠前,udio可能我的配置风格有问题,啪啪啪连选了好几个风格,生成的东西有点怪。 我随手写了…

【机器学习基础1】什么是机器学习、预测模型解决问题的步骤、机器学习的Python生态圈

文章目录 一. 什么是机器学习1. 概念2. 机器学习算法分类 二. 利用预测模型解决问题的步骤三. 机器学习的Python生态圈 一. 什么是机器学习 1. 概念 机器学习(Machine Learning,ML)是一门多领域的交叉学科,涉及概率论、统计学、…

深度学习 --- stanford cs231学习笔记(一)

stanford cs231学习笔记(一) 1,先是讲到了机器学习中的kNN算法,然后因为kNN分类器的一些弊端,引入了线性分类器。 kNN算法的三大弊端: (1),计算量大,当特征比较多时表示性差 (2),训练时耗时少…

01 - 安装Kettle

下载安装包 我这边提供的安装包是绿色版的,开箱即用 Kettle.exe 阿里云盘分享 提取码: 8sd5 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。 启动步骤 解压 双击Spo…

注意力机制(四)(多头注意力机制)

​🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀《深度学习基础知识》 相关专栏: ⚽《机器学习基础知识》 🏐《机器学习项目实战》 🥎《深度学习项目实…

Python | Leetcode Python题解之第55题跳跃游戏

题目&#xff1a; 题解&#xff1a; class Solution:def canJump(self, nums: List[int]) -> bool:n, rightmost len(nums), 0for i in range(n):if i < rightmost:rightmost max(rightmost, i nums[i])if rightmost > n - 1:return Truereturn False

闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子

前言 一个在实际应用中 EF Core 集成 FluentValidation 进行数据校验的例子。 Step By Step 步骤 创建一个 Asp.Net Core WebApi 项目 引用以下 Nuget 包 FluentValidation.AspNetCore Microsoft.AspNetCore.Identity.EntityFrameworkCore Microsoft.EntityFrameworkCore.Re…