HuggingFace项目实战之分类任务实战

目录:

一、项目准备工作和基础操作

可以参看我的上一篇文章:

https://blog.csdn.net/zouyang920/article/details/156536481?sharetype=blogdetail\&sharerId=156536481\&sharerefer=PC\&sharesource=zouyang920\&spm=1011.2480.3001.8118

二、加载分词器

python 复制代码
import torch

from transformers import AutoTokenizer

#加载tokenizer
tokenizer = AutoTokenizer.from_pretrained('google-bert/bert-base-chinese')

tokenizer

二、加载数据集

python 复制代码
from datasets import load_dataset

#加载数据集
dataset = load_dataset(path='lansinuote/ChnSentiCorp')

dataset, dataset['train'][0]

三、数据处理

python 复制代码
#定义数据集遍历工具
def collate_fn(data):
    text = [i['text'] for i in data]
    label = [i['label'] for i in data]

    #文字编码
    data = tokenizer(text,
                     padding=True,
                     truncation=True,
                     max_length=500,
                     return_tensors='pt',
                     return_token_type_ids=False)

    #设置label
    data['label'] = torch.LongTensor(label)

    return data


loader = torch.utils.data.DataLoader(dataset['train'],
                                     batch_size=8,
                                     shuffle=True,
                                     drop_last=True,
                                     collate_fn=collate_fn)

data = next(iter(loader))

for k, v in data.items():
    print(k, v.shape)

len(loader)

四、使用模型测试分类

python 复制代码
#定义模型
class Model(torch.nn.Module):

    def __init__(self):
        super().__init__()

        #加载预训练模型
        from transformers import AutoModel
        self.pretrained = AutoModel.from_pretrained(
            'google-bert/bert-base-chinese')

        self.fc = torch.nn.Linear(in_features=768, out_features=2)

    def forward(self, input_ids, attention_mask, label=None):
        #使用预训练模型抽取数据特征
        with torch.no_grad():
            last_hidden_state = self.pretrained(
                input_ids=input_ids,
                attention_mask=attention_mask).last_hidden_state

        #只取第0个词的特征做分类,这和bert模型的训练方式有关,此处不展开
        last_hidden_state = last_hidden_state[:, 0]

        #对抽取的特征只取第一个字的结果做分类即可
        out = self.fc(last_hidden_state).softmax(dim=1)

        #计算loss
        loss = None
        if label is not None:
            loss = torch.nn.functional.cross_entropy(out, label)

        return loss, out


model = Model()

model(**data)

五、模型训练

python 复制代码
#执行训练
def train():
    optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)

    for i, data in enumerate(loader):
        loss, out = model(**data)

        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if i % 10 == 0:
            out = out.argmax(dim=1)
            acc = (out == data.label).sum().item() / len(data.label)
            print(i, len(loader), loss.item(), acc)

        if i == 300:
            break


train()

5.1、代码解读一

python 复制代码
acc = (out == data.label).sum().item() / len(data.label)

作用:

衡量模型 预测正确的样本比例,是分类任务中最直观的评价指标。

逐部分解析:

1、out == data.label

  • out:模型的预测结果(经过 softmax 后,通常取 argmax(dim=1) 得到类别索引,如 0, 1, 0, ...)。

  • data.label:真实标签(样本的正确类别,如 1, 1, 0, ...)。

  • 比较结果:返回一个布尔张量(True/False),True 表示预测正确,False 表示预测错误。

  • 例:out = 0, 1, 1,label = 0, 1, 0 → 比较结果为 True, True, False

2、.sum().item()

  • .sum():将布尔张量中的 True(视为1)求和,得到 正确预测的样本数。 例:上述 True, True, False 求和后为 2(2个正确样本)。
  • .item():将 PyTorch 张量转换为 Python 数值(如 tensor(2) → 2)。

3、/ len(data.label)

  • len(data.label):当前批次的总样本数(如一个 batch 有8个样本,则为8)。

  • 最终结果:正确样本数 / 总样本数,即 准确率(Accuracy)。 例:2个正确 / 3个总样本 → 准确率 ≈ 66.7%。

5.2、代码解读二

python 复制代码
loss = torch.nn.functional.cross_entropy(out, label):计算交叉熵损失

作用:

衡量模型 预测概率与真实标签的差距,是训练过程中优化的目标(通过最小化 Loss 提升模型性能)。

逐部分解析:

1、if label is not None

  • 仅在 训练/验证阶段 计算 Loss(此时有真实标签 label)。

  • 测试阶段(仅预测,无标签)可不计算 Loss,直接返回预测结果 out。

2、cross_entropy(out, label)

输入:

  • out:模型的原始输出(Logits,未经过 softmax 的张量,形状为 batch_size, num_classes)。
  • label:真实标签(形状为 batch_size,每个元素是类别索引,如 0 或 1)。

计算逻辑:

  • 对 out 自动应用 softmax,得到每个类别的预测概率 p。
  • 计算真实标签对应类别的负对数概率:-ln(p_true)(概率越低,Loss 越大)。
  • 对 batch 内所有样本的 Loss 取平均值,得到最终的交叉熵损失。
    例: 二分类中,样本真实标签为 1,模型预测 1 类的概率为 0.9 → Loss = -ln(0.9) ≈ 0.105;若概率为 0.1 → Loss = -ln(0.1) ≈ 2.303(差距越大,Loss 越大)。

3、return loss, out

  • 返回 Loss(用于反向传播更新模型权重)和预测结果 out(用于计算准确率或后续处理)。

六、测试训练后的分类结果

python 复制代码
#执行测试
def test():
    loader_test = torch.utils.data.DataLoader(dataset['test'],
                                              batch_size=8,
                                              shuffle=True,
                                              drop_last=True,
                                              collate_fn=collate_fn)

    correct = 0
    total = 0
    for i, data in enumerate(loader_test):
        with torch.no_grad():
            _, out = model(**data)

        out = out.argmax(dim=1)
        correct += (out == data.label).sum().item()
        total += len(data.label)

        print(i, len(loader_test), correct / total)

        if i == 5:
            break

    return correct / total


test()

可以看到训练后的结果准确率比没有训练的准确率高出了不少。

相关推荐
Lihua奏3 天前
从单核到多核:CPU为什么不能再只靠提频变快
深度学习
拾年2753 天前
大模型的"聪明"从哪来?聊聊 AI 数据集的那些事儿
人工智能·深度学习·机器学习
hboot4 天前
AI工程师第四课 - 深度学习入门
pytorch·python·神经网络
weiwei228447 天前
神经网络模型导出及开放标准格式ONNX
pytorch·onnx
饼干哥哥7 天前
开源Skills|搭建亚马逊动态关键词库系统,每天抓SSS级机会词
人工智能·深度学习·数据分析
武子康9 天前
调查研究-191 SenseVoice 不只是 ASR:把语音从“转文字“升级成“理解状态“
人工智能·深度学习·openai
武子康10 天前
调查研究-189 Kronos 调研:金融 K 线基础模型,是真突破,还是量化圈的新玩具?
人工智能·深度学习·openai
程序猿追16 天前
那个右下角的小数字怎么“卡”住我打字——我用 HarmonyOS 自己写了一个字数限制输入框
pytorch·华为·harmonyos
xiao5kou4chang6kai416 天前
MATLAB机器学习、深度学习--从数据预处理到模型训练
深度学习·机器学习·matlab·数据预处理
renhongxia116 天前
世界模型作为AGI落地底层底座的作用
人工智能·深度学习·生成对抗网络·自然语言处理·知识图谱·agi