初级网站建设,手机商城积分兑换,wordpress用户批量注册,wordpress搭建商城文章目录 简介个人博客与相关链接1 实验数据与任务说明2 模型介绍2.1 TransformerTransformer能做什么#xff1f; 2.2 Hugging FaceHugging Face的Transformers库社区支持和资源预训练模型的应用 2.3 T5模型#xff08;Text-To-Text Transfer Transformer#xff09;T5的核… 文章目录 简介个人博客与相关链接1 实验数据与任务说明2 模型介绍2.1 TransformerTransformer能做什么 2.2 Hugging FaceHugging Face的Transformers库社区支持和资源预训练模型的应用 2.3 T5模型Text-To-Text Transfer TransformerT5的核心理念T5的架构和训练方法T5在多标签分类任务中的运用 3 实验步骤3.1 数据预处理3.2 模型训练与测试模型选择参数设置 3.3 结果转化与评估 4 代码与实验4.1 数据预处理4.2 模型训练与预测自定义批处理函数自定义Dataset自定义LightningModule训练与预测函数保存结果以及任务启动 4.3 结果转化与模型评估 5 实验结果 简介
在《【NLP】多标签分类》系列的上一篇文章中我们深入探讨了三种机器学习方法Binary Relevance (BR)、Classifier Chains (CC) 以及 Label Powerset (LP)旨在解决多标签分类的挑战。这些方法各展所长为我们提供了不同角度解析和处理多标签问题的视角。继先前对这些机器学习方法的详尽分析之后本篇文章转向更为先进的解决策略——专注于序列生成方法并以Transformer模型的一种变体即T5预训练模型为核心进行实验探索。
本文将不仅详细介绍如何利用T5模型对多标签分类任务进行微调而且还将通过实验对比展现其相较于之前讨论的传统方法在性能上的优势和潜在应用价值。通过精心设计的实验和深入的结果分析揭示序列生成方法特别是Transformer架构的强大能力和灵活性。
个人博客与相关链接
本文相关代码和数据集已同步上传github: issey_Kaggle/MultiLabelClassification at main · iceissey/issey_Kaggle (github.com)
本文代码Notebook已公布至kaggle: Transformer-Multi-Label-Classification (kaggle.com)
博主个人博客链接issey的博客 - 愿无岁月可回首
1 实验数据与任务说明
数据来源Multi-Label Classification Dataset (kaggle.com)
任务说明
背景NLP——多标签分类数据集。内容该数据集包含6个不同的标签计算机科学、物理学、数学、统计学、定量生物学、定量金融用于根据摘要和标题对研究论文进行分类。 标签列中的值1表示该标签属于该论文每篇论文可以有多个标签为1。 2 模型介绍
2.1 Transformer
Transformer模型自从2017年由Vaswani等人在论文《Attention Is All You Need》中首次提出以来已经证明了其在多种自然语言处理任务上的强大能力。尽管本文不会深入讲解Transformer的详细架构及其组成模块我们仍然强烈推荐感兴趣的读者参考原始论文以获得全面的理解。
Transformer能做什么
Transformer的创新之处在于其独特的自注意力机制使其能够在处理文本时更有效地捕捉长距离依赖关系。这一特性不仅提高了处理速度还提升了模型对文本的理解深度打开了自然语言处理领域的新篇章。以下是Transformer在NLP领域的一些关键应用
文本分类Transformer能够理解复杂的文本结构和语义使其在文本分类任务上表现优异包括情感分析、主题识别等。机器翻译由于其强大的语言模型能力Transformer模型已成为机器翻译领域的主导技术提供了更加流畅和准确的翻译结果。文本摘要Transformer模型能够理解和提取文本的关键信息生成准确且连贯的摘要无论是抽取式还是生成式摘要。问答系统利用其深度理解能力Transformer能够从大量文本中提取答案为问答系统提供强有力的支持。语言生成Transformer的变体如GPT系列已经展示了在生成文本、编写代码等任务上的卓越能力推动了创造性文本生成和自动编程的新发展。
2.2 Hugging Face
在深入探讨如何将Transformer模型应用于多标签分类任务之前让我们先了解一下Hugging Face。作为一个致力于推进机器学习技术民主化的开源社区和公司Hugging Face为研究者和开发者们提供了丰富的预训练模型库及相关工具极大地简化了NLP任务的开发流程。
官网链接Hugging Face – The AI community building the future.
Hugging Face的Transformers库
作为一个广泛使用的Python库Hugging Face的Transformers库集合了数百种预训练的Transformer模型支持轻松应用于文本分类、文本生成、问答等多种NLP任务。该库的一个主要优势是其提供了统一的接口让不同的Transformer模型比如BERT、GPT-2、RoBERTa等在几乎不需修改代码的情况下就能互相替换使用。
社区支持和资源
Hugging Face不仅提供预训练模型还维护着一个充满活力的社区社区成员在此分享经验、解决方案及最佳实践。这样的平台为初学者和专家提供了交流与学习的机会进一步推动了NLP领域的发展。更进一步Hugging Face也提供了模型共享平台允许研究者和开发者上传及分享自己训练的模型进一步增强了社区资源。
预训练模型的应用
对于多标签分类任务而言Hugging Face的Transformers库开辟了一个既简单又强大的途径以便利用最先进的模型。用户可根据自身任务需求选择合适的预训练模型并通过微调fine-tuning的方式使其适应具体的多标签分类任务从而大幅度降低了模型开发和训练的时间及资源消耗。在接下来的部分中我们会详细展示这一过程的实现包括模型的选择、数据准备、训练以及性能评估等关键步骤。
2.3 T5模型Text-To-Text Transfer Transformer
本节将介绍我们在本次实验中使用的预训练模型T5全称为Text-To-Text Transfer Transformer。T5模型以其创新性著称其设计理念是将所有自然语言处理NLP任务转化为一个统一的文本到文本的格式。这种独特的通用性使得T5成为解决多标签分类等复杂任务的理想选择。
T5的核心理念
T5模型的设计核心在于将各种NLP任务统一到一个简单的框架中接受文本输入并产生文本输出。这意味着无论是进行文本分类、翻译还是处理更为复杂的多标签分类和问答任务T5模型都以相同的方法处理极大地提升了模型的灵活性和适用范围。
T5的架构和训练方法
T5遵循了经典的Encoder-Decoder架构但在训练策略上进行了创新。它首先在大量文本数据上进行预训练掌握语言的广泛知识然后在特定任务的数据集上进行微调fine-tuning。这种结合预训练和微调的方法使T5在许多NLP任务上取得了卓越的表现。
T5在多标签分类任务中的运用
在多标签分类任务中T5模型将任务视为一个文本到文本的转换问题它将文章内容作为输入并输出一系列的标签作为分类结果。这种方法简化了任务的处理流程并允许T5利用其预训练阶段学到的丰富语言知识以提升任务的处理效率和分类准确性。
3 实验步骤
本实验的主要步骤包括1数据预处理。2模型训练与测试。3结果转化与评估。
3.1 数据预处理
正如前一节所述T5模型以序列生成的形式处理任务即接收文本输入并产生文本输出。因此我们需要将原始数据转换成符合这一格式的形式以便模型能够有效处理。以下是我们的原始数据格式示例
文本内容计算机科学物理数学统计学定量生物学定量金融学这是一个文本示例。100100
为了将这些数据转换为适合序列生成任务的格式我们需要将标签即标记为1的类别转化为一串文本标签如下所示
示例
文本内容标签这是一个文本示例。计算机科学;统计学
注意标签之间可以使用其他符号进行隔开本例中使用的是分号;。我们的目标是将标记为1的标签拼接成一条文本数据以便模型可以将这些标签作为生成任务的一部分来处理。
3.2 模型训练与测试
模型选择
模型名称T5-Small
模型链接google-t5/t5-small · Hugging Face
参数设置
batch_size 16
epochs 5
learning_rate 2e-53.3 结果转化与评估
在使用T5模型完成多标签分类任务后我们会得到模型生成的文本序列作为输出。这些输出序列以文本形式列出了预测的标签例如
预测标签统计学;定量生物学;定量金融学
为了对模型的性能进行评估并使用我们在上篇文章中介绍的多标签分类评估方法必须先将这些文本格式的标签转换回原始数据的格式即将每个标签对应到它们各自的分类列上并用0或1表示其是否被预测为该类。转换后的格式如下所示
计算机科学物理数学统计学定量生物学定量金融学000111
在这个转换过程中我们首先将每个预测的标签字符串分割为单独的标签在本例中我们使用分号;作为分隔符。然后我们检查每个原始标签列并将其与分割后的标签进行匹配如果预测中包含某个标签则在相应的列中标记为1如果不包含则标记为0。这样我们就能得到一个与原始数据格式相匹配的矩阵便于我们采用上篇文章中介绍的评估方法来量化模型的性能。
4 代码与实验 该部分强烈建议搭配Kaggle使用见相关链接部分。如果觉得有帮助可以顺便在Kaggle点个赞谢谢 4.1 数据预处理
将原始的多标签分类数据集转换为适用于T5模型的格式。具体来说我们将文章的标题和摘要合并为一个单独的文本输入并将标记为1的多个标签合并为一个分号分隔的标签字符串。最终这一预处理步骤将生成一个清晰的文本到文本格式为T5模型的训练做好准备。
DataPreprocessing.py
import pandas as pd准备数据
input_csv ../../../archive/train.csv
data pd.read_csv(input_csv)
print(len(data))
label_columns data.columns[-6:] # 提取labels列
print(label_columns)data[text] data[TITLE] data[ABSTRACT] # 准备text
print(data[text].head())data[labels] data[label_columns].apply(lambda x: ; .join(x.index[x 1]), axis1)
print(data[labels])
# Displaying the updated dataset
preprocessed_data data[[text, labels]]
print(preprocessed_data.head())# 存储为新的 CSV 文件
output_path ../../../archive/preprocessed_data.csv
preprocessed_data.to_csv(output_path, indexFalse)4.2 模型训练与预测
本次仍然使用了Pytorch以及Pytorch lightning作为实验框架关于Pytorch lightning的使用方法请自行查阅官网。
Pytorch lightning Welcome to ⚡ PyTorch Lightning — PyTorch Lightning 2.2.1 documentation
该部分对应文件名Transformer.py
自定义批处理函数
def collate_fn(batch):自定义批处理函数texts [item[text] for item in batch]labels [item[labels] for item in batch]# 使用 tokenizer 对文本和标签进行编码,最大长度512encoding tokenizer(texts, paddingTrue, truncationTrue, max_length512, return_tensorspt)# 使用 tokenizer 的 target_tokenizer 对标签进行编码with tokenizer.as_target_tokenizer():labels_encoding tokenizer(labels, paddingTrue, truncationTrue, max_length512, return_tensorspt)# 将标签中的 pad token 替换为 -100这是 T5 模型的要求labels_encoding[input_ids][labels_encoding[input_ids] tokenizer.pad_token_id] -100return {input_ids: encoding[input_ids],attention_mask: encoding[attention_mask],labels: labels_encoding[input_ids]}自定义Dataset
class T5Dataset(Dataset):自定义数据集def __init__(self, dataset):self.dataset datasetdef __getitem__(self, idx):item self.dataset[idx]return {text: item[text],labels: item[labels]}def __len__(self):return len(self.dataset)自定义LightningModule
class T5FineTuner(pl.LightningModule):自定义LightningModuledef __init__(self, train_dataset, val_dataset, test_dataset, learning_rate2e-5):super(T5FineTuner, self).__init__()self.validation_loss []self.model T5ForConditionalGeneration.from_pretrained(t5-small)self.learning_rate learning_rate # 微调self.train_dataset train_datasetself.val_dataset val_datasetself.test_dataset test_datasetself.prediction []def forward(self, input_ids, attention_mask, labelsNone):output self.model(input_idsinput_ids,attention_maskattention_mask,labelslabels)return outputdef configure_optimizers(self):return AdamW(self.model.parameters(), lrself.learning_rate)def train_dataloader(self):train_loader DataLoader(datasetself.train_dataset, batch_sizebatch_size, collate_fncollate_fn,shuffleTrue)return train_loaderdef val_dataloader(self):val_loader DataLoader(datasetself.val_dataset, batch_sizebatch_size, collate_fncollate_fn,shuffleFalse)return val_loaderdef test_dataloader(self):test_loader DataLoader(datasetself.test_dataset, batch_sizebatch_size, collate_fncollate_fn,shuffleFalse)return test_loaderdef training_step(self, batch, batch_idx):input_ids batch[input_ids]attention_mask batch[attention_mask]labels batch[labels]output self(input_ids, attention_mask, labels)loss output.lossself.log(train_loss, loss, prog_barTrue, loggerTrue, on_stepTrue, on_epochTrue) # 将loss输出在控制台return lossdef validation_step(self, batch, batch_idx):input_ids batch[input_ids]attention_mask batch[attention_mask]labels batch[labels]output self(input_ids, attention_mask, labels)loss output.lossself.log(val_loss, loss, prog_barFalse, loggerTrue, on_stepTrue, on_epochTrue)return lossdef test_step(self, batch, batch_idx):input_ids batch[input_ids]attention_mask batch[attention_mask]self.model.eval()# 生成输出序列generated_ids self.model.generate(input_idsinput_ids, attention_maskattention_mask)# 将生成的token ids转换为文本generated_texts [tokenizer.decode(generated_id, skip_special_tokensTrue, clean_up_tokenization_spacesTrue)for generated_id in generated_ids]# 返回解码后的文本# print(generated_texts)self.prediction.extend(generated_texts)训练与预测函数
def test(model, fast_run):trainer pl.Trainer(fast_dev_runfast_run)trainer.test(model)test_result model.prediction# print(type(test_result))for text in test_result[:10]:print(text)return test_resultdef train(fast_run):# 增加回调最优模型checkpoint_callback ModelCheckpoint(monitorval_loss, # 监控对象为val_lossdirpath../../archive/log/T5FineTuner_checkpoints, # 保存模型的路径filenameModels-{epoch:02d}-{val_loss:.2f}, # 最优模型的名称save_top_k1, # 只保存最好的那个modemin # 当监控对象指标最小时)# 设置日志保存的路径log_dir ../../archive/loglogger TensorBoardLogger(save_dirlog_dir, nameT5FineTuner_logs)# Trainer可以帮助调试比如快速运行、只使用一小部分数据进行测试、完整性检查等# 详情请见官方文档https://lightning.ai/docs/pytorch/latest/debug/debugging_basic.html# auto自适应gpu数量trainer pl.Trainer(max_epochsepochs, log_every_n_steps10, acceleratorgpu, devicesauto, fast_dev_runfast_run,callbacks[checkpoint_callback], loggerlogger)model T5FineTuner(train_dataset, valid_dataset, test_dataset, learning_rate)trainer.fit(model)return model保存结果以及任务启动
当在Kaggle上进行操作时请注意直接使用load_dataset函数从CSV文件加载数据集可能会导致错误。为了避免这个问题推荐先使用pandas库将CSV文件读入为DataFrame之后再将其转换为适合模型训练的格式。具体的代码实现和操作可以参考Kaggle笔记本中的相关部分。
def save_to_csv(test_dataset, predictions, filename../../archive/test_predictions.csv):with open(filename, modew, newline, encodingutf-8) as file:writer csv.writer(file)writer.writerow([text, true_labels, pred_labels])for item, pred_label in zip(test_dataset, predictions):text item[text]true_labels item[labels]writer.writerow([text, true_labels, pred_label])if __name__ __main__:data load_dataset(csv, data_files{train: ../../archive/preprocessed_data.csv})[train]# 分割数据集为训练集和测试验证集train_testvalid data.train_test_split(test_size0.3, seed42)# 分割测试验证集为测试集和验证集test_valid train_testvalid[test].train_test_split(test_size0.5, seed42)# 现在我们有了训练集、验证集和测试集train_dataset train_testvalid[train]valid_dataset test_valid[train]test_dataset test_valid[test]# 打印各个数据集的大小print(Training set size:, len(train_dataset))print(Validation set size:, len(valid_dataset))print(Test set size:, len(test_dataset))# 准备Datasettrain_dataset T5Dataset(train_dataset)valid_dataset T5Dataset(valid_dataset)test_dataset T5Dataset(test_dataset)# print(train_dataset.__len__())# print(train_dataset[0])# 初始化分词器tokenizer T5Tokenizer.from_pretrained(t5-small)# 装载dataLoadertrain_dataloader DataLoader(datasettrain_dataset, batch_sizebatch_size,collate_fncollate_fn, shuffleTrue, drop_lastTrue)# 查看装载情况for i, batch in enumerate(train_dataloader):print(fBatch {i 1})print(Input IDs:, batch[input_ids])print(Input IDs shape:, batch[input_ids].shape)print(Attention Mask:, batch[attention_mask])print(Attention Mask shape:, batch[attention_mask].shape)print(Labels:, batch[labels])print(\n)if i 0:breakfast_run Truemodel train(fast_run)# model T5FineTuner.load_from_checkpoint(# ../../archive/log/T5FineTuner_checkpoints/model-epoch09-val_loss0.32.ckpt,# train_datasettrain_dataset, val_datasetvalid_dataset,# test_datasettest_dataset)pre_texts test(model, fast_run)save_to_csv(test_dataset, pre_texts)4.3 结果转化与模型评估
Estimate.py
import pandas as pd
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.metrics import precision_score, recall_score, f1_score, accuracy_score
import numpy as npdef convert_labels(label_str):return label_str.split(;) if label_str else []def clean_label(label):return label.strip()# 读取提供的 CSV 文件
file_path ../../archive/test_predictions.csv
data pd.read_csv(file_path)
# print(data.head())# 提取并转换真实标签和预测标签
true_labels [convert_labels(label_str) for label_str in data[true_labels]]
pred_labels [convert_labels(label_str) for label_str in data[pred_labels]]
# 使用清理后的标签重新创建真实标签和预测标签列表
true_labels_cleaned [list(map(clean_label, label_list)) for label_list in true_labels]
pred_labels_cleaned [list(map(clean_label, label_list)) for label_list in pred_labels]# 使用 MultiLabelBinarizer 对标签进行独热编码
mlb MultiLabelBinarizer()
mlb.fit(true_labels_cleaned pred_labels_cleaned)
y_true mlb.transform(true_labels_cleaned)
y_pred mlb.transform(pred_labels_cleaned)print(Transformer(T5) Accuracy , accuracy_score(y_true, y_pred))
print(Transformer(T5) Precision (micro-average) , precision_score(y_true, y_pred, averagemicro))
print(Transformer(T5) Recall (micro-average) , recall_score(y_true, y_pred, averagemicro))
print(Transformer(T5) F1 Score (micro-average) , f1_score(y_true, y_pred, averagemicro))print(\nAnother way to calculate accuracy:)
# 计算每一列的准确率
column_accuracies np.mean(y_true y_pred, axis0)
# 为每列准确率添加列名
column_accuracy_with_labels list(zip(mlb.classes_, column_accuracies))
# 计算列准确率的均值
mean_column_accuracy np.mean(column_accuracies)for acc in column_accuracy_with_labels:print(acc)
# print(column_accuracy_with_labels)
print(Average accuracy , mean_column_accuracy)5 实验结果
本节汇总并比较了上篇和下篇文章中各种实验的结果。我们采用了几种不同的算法来处理多标签分类问题包括Binary RelevanceBR与Random Forest组合、Classifier ChainsCC与Random Forest组合、Label PowersetLP与Random Forest组合、LP与SVM组合以及使用了TransformerT5模型的序列生成方法。
通过对比准确率Accuracy、微观精确度Precision_micro、微观召回率Recall_micro和微观F1分数F1_micro这四个关键性能指标我们发现
使用基于Random Forest的BR、CC和LP方法可以得到相对较好的预测性能。当LP与SVM组合使用时性能有所提高特别是在召回率和F1分数方面。最为显著的是TransformerT5模型尤其在准确率、召回率和F1分数上达到了最高值。
具体数值如下所示
AlgorithmsAcc P r e m i c r o Pre_{micro} Premicro R e m i c r o Re_{micro} Remicro F 1 m i c r o F1_{micro} F1microBR(RandomForest)0.44770.80380.49780.6149CC(RandomForest)0.47870.80120.52770.6363LP(RandomForest)0.53490.71790.58890.6470LP(SVM)0.59140.73680.72450.7306Transformer(T5)0.64270.79940.78400.7916
从结果中我们可以得出结论Transformer模型在处理复杂的多标签分类任务时展现出了其强大的能力。这也表明了序列到序列模型在NLP领域的广泛应用潜力和有效性。