使用 Transformers 在你自己的数据集上训练文本分类模型

最近实在是有点忙,没啥时间写博客了。趁着周末水一文,把最近用 huggingface transformers 训练文本分类模型时遇到的一个小问题说下。

背景

之前只闻 transformers 超厉害超好用,但是没有实际用过。之前涉及到 bert 类模型都是直接手写或是在别人的基础上修改。但这次由于某些原因,需要快速训练一个简单的文本分类模型。其实这种场景应该挺多的,例如简单的 POC 或是临时测试某些模型。

我的需求很简单:用我们自己的数据集,快速训练一个文本分类模型,验证想法。

我觉得如此简单的一个需求,应该有模板代码。但实际去搜的时候发现,官方文档什么时候变得这么多这么庞大了?还多了个 Trainer API?瞬间让我想起了 Pytorch Lightning 那个坑人的同名 API。但可能是时间原因,找了一圈没找到适用于自定义数据集的代码,都是用的官方、预定义的数据集。

所以弄完后,我决定简单写一个文章,来说下这原本应该极其容易解决的事情。

数据

假设我们数据的格式如下:

0 第一个句子
1 第二个句子
0 第三个句子

即每一行都是 label sentence 的格式,中间空格分隔。并且我们已将数据集分成了 train.txtval.txt

代码

加载数据集

首先使用 datasets 加载数据集:

from datasets import load_dataset
dataset = load_dataset('text', data_files={'train': 'data/train_20w.txt', 'test': 'data/val_2w.txt'})

加载后的 dataset 是一个 DatasetDict 对象:

DatasetDict({
    train: Dataset({
        features: ['text'],
        num_rows: 3
    })
    test: Dataset({
        features: ['text'],
        num_rows: 3
    })
})

类似 tf.data ,此后我们需要对其进行 map ,对每一个句子进行 tokenize、padding、batch、shuffle:

def tokenize_function(examples):
    labels = []
    texts = []
    for example in examples['text']:
        split = example.split(' ', maxsplit=1)
        labels.append(int(split[0]))
        texts.append(split[1])
    tokenized = tokenizer(texts, padding='max_length', truncation=True, max_length=32)
    tokenized['labels'] = labels
    return tokenized

tokenized_datasets = dataset.map(tokenize_function, batched=True)
train_dataset = tokenized_datasets["train"].shuffle(seed=42)
eval_dataset = tokenized_datasets["test"].shuffle(seed=42)

根据数据集格式不同,我们可以在 tokenize_function 中随意自定义处理过程,以得到 text 和 labels。注意 batch_sizemax_length 也是在此处指定。处理完我们便得到了可以输入给模型的训练集和测试集。

训练

model = AutoModelForSequenceClassification.from_pretrained("bert-base-cased", num_labels=2, cache_dir='data/pretrained')
training_args = TrainingArguments('ckpts', per_device_train_batch_size=256, num_train_epochs=5)
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset
)
trainer.train()

你可以根据情况修改训练 batchsize per_device_train_batch_size

完整代码

完整代码见 GitHub

END

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
1.项目代码均经过功能验证ok,确保稳定可靠运行。欢迎下载体验!下载完使用问题请私信沟通。 2.主要针对各个计算机相关专业,包括计算机科学、信息安全、数据科学与大数据技术、人工智能、通信、物联网等领域的在校学生、专业教师、企业员工。 3.项目具有丰富的拓展空间,不仅可作为入门进阶,也可直接作为毕设、课程设计、大作业、初期项目立项演示等用途。 4.当然也鼓励大家基于此进行二次开发。在使用过程中,如有问题或建议,请及时沟通。 5.期待你能在项目中找到乐趣和灵感,也欢迎你的分享和反馈! 【资源说明】 基于PyTorch的BERT中文文本分类项目python源码+项目说明+数据集+详细注释.zip 本项目仅仅提供了最基础的BERT文本分类模型,代码是作者在入门NLP时自己写的,对于初学者还算比较好理解,细节上有不足的地方,大家可以自行修改。 数据集是从清华大学的[THUCNews](http://thuctc.thunlp.org/)中提取出来的部分数据训练集中有5万条数据,分成了10类,每类5000条数据。 ```JSON {"体育": 5000, "娱乐": 5000, "家居": 5000, "房产": 5000, "教育": 5000, "时尚": 5000, "时政": 5000, "游戏": 5000, "科技": 5000, "财经": 5000} ``` 验证集中有5000条数据,每类500条数据。 ```JSON {"体育": 500, "娱乐": 500, "家居": 500, "房产": 500, "教育": 500, "时尚": 500, "时政": 500, "游戏": 500, "科技": 500, "财经": 500} ``` 数据集放在了百度网盘上:链接: https://pan.baidu.com/s/1FVV8fq7vSuGSiOVnE4E_Ag 提取码: bbwv 模型描述 整个分类模型首先把句子输入到Bert预训练模型,然后将*句子的embedding*(CLS位置的Pooled output)输入给一个Linear,最后把Linear的输出输入到softmax中。 ![Figure 1: Model](figure/model.png) 环境 | 硬件 | 环境 | | ---- | ---- | | GPU | GTX1080 | | RAM | 64G | | 软件 | 环境 | | ---- | ---- | | OS | Ubuntu 18.04 LTS | | CUDA | 10.2 | | PyTorch | 1.6.0 | | transformers | 3.2.0 | 结果 分类报告: ``` * Classification Report: precision recall f1-score support 体育 1.00 0.99 0.99 500 娱乐 0.99 0.92 0.96 500 家居 0.96 0.73 0.83 500 房产 0.83 0.94 0.88 500 教育 0.94 0.75 0.84 500 时尚 0.89 0.99
好的,以下是使用 transformers 包构建文本分类模型的示例代码: ```python from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments import torch # 加载预训练模型tokenizer和模型 model_name = "distilbert-base-uncased" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSequenceClassification.from_pretrained(model_name) # 定义文本分类任务的数据集 train_texts = ["This is a positive example.", "This is a negative example."] train_labels = [1, 0] train_encodings = tokenizer(train_texts, truncation=True, padding=True) class TextClassificationDataset(torch.utils.data.Dataset): def __init__(self, encodings, labels): self.encodings = encodings self.labels = labels def __getitem__(self, idx): item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()} item['labels'] = torch.tensor(self.labels[idx]) return item def __len__(self): return len(self.labels) train_dataset = TextClassificationDataset(train_encodings, train_labels) # 定义训练参数 training_args = TrainingArguments( output_dir='./results', num_train_epochs=1, per_device_train_batch_size=2, per_device_eval_batch_size=2, warmup_steps=500, weight_decay=0.01, logging_dir='./logs', logging_steps=10, ) # 训练模型 trainer = Trainer( model=model, args=training_args, train_dataset=train_dataset, ) trainer.train() ``` 这个示例代码使用了 DistilBERT 模型,可以根据实际情况选择不同的预训练模型训练数据集中包含两个样本,分别为正例和反例。你需要根据自己的数据集修改训练数据集的内容。训练参数可以根据实际情况进行调整,比如训练轮数、批次大小等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

secsilm

来一根火腿?

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

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

打赏作者

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

抵扣说明:

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

余额充值