专栏首页程序生活文本分类上分微调技巧实战

文本分类上分微调技巧实战

目录

  • 引言
  • How to Fine-Tune BERT for Text Classification 论文
    • 微调策略
    • ITPT:继续预训练
  • 学术论文分类挑战赛微调
    • huggingface工具介绍
    • bert模型介绍
    • 数据创建
    • 模型定义
    • 模型训练与评估
    • 模型改进

How to Fine-Tune BERT for Text Classification 论文

微调策略

  1. 处理长文本 我们知道BERT 的最大序列长度为 512,BERT 应用于文本分类的第一个问题是如何处理长度大于 512 的文本。本文尝试了以下方式处理长文章。

Truncation methods 截断法 文章的关键信息位于开头和结尾。 我们可以使用三种不同的截断文本方法来执行 BERT 微调。

head-only: keep the first 510 tokens 头部510个字符,加上两个特殊字符刚好是512 ; tail-only: keep the last 510 tokens;尾部510个字符,同理加上两个特殊字符刚好是512 ; head+tail: empirically select the first 128and the last 382 tokens.:尾部结合

Hierarchical methods 层级法 输入的文本首先被分成k = L/510个片段,喂入 BERT 以获得 k 个文本片段的表示向量。 每个分数的表示是最后一层的 [CLS] 标记的隐藏状态,然后我们使用均值池化、最大池化和自注意力来组合所有分数的表示。

  1. 不同层的特征 BERT 的每一层都捕获输入文本的不同特征。 文本研究了来自不同层的特征的有效性, 然后我们微调模型并记录测试错误率的性能。

image

我们可以看到:最后一层表征效果最好;最后4层进行max-pooling效果最好

  1. 灾难性遗忘 Catastrophic forgetting (灾难性遗忘)通常是迁移学习中的常见诟病,这意味着在学习新知识的过程中预先训练的知识会被遗忘。 因此,本文还研究了 BERT 是否存在灾难性遗忘问题。 我们用不同的学习率对 BERT 进行了微调,发现需要较低的学习率,例如 2e-5,才能使 BERT 克服灾难性遗忘问题。 在 4e-4 的较大学习率下,训练集无法收敛。

image

这个也深有体会,当预训练模型失效不能够收敛的时候多检查下超参数是否设置有问题。

  1. Layer-wise Decreasing Layer Rate 逐层降低学习率 下表 显示了不同基础学习率和衰减因子在 IMDb 数据集上的性能。 我们发现为下层分配较低的学习率对微调 BERT 是有效的,比较合适的设置是 ξ=0.95 和 lr=2.0e-5

为不同的BERT设置不同的学习率及衰减因子,BERT的表现如何?

image

η^l代表第几层的学习率

ITPT:继续预训练

ITPT:继续预训练 Bert是在通用的语料上进行预训练的,如果要在特定领域应用文本分类,数据分布一定是有一些差距的。这时候可以考虑进行深度预训练。

  1. Within-task pre-training:Bert在训练语料上进行预训练 In-domain pre-training:在同一领域上的语料进行预训练 Cross-domain pre-training:在不同领域上的语料进行预训练 Within-task pretraining [图片上传失败...(image-177ffd-1627289320036)] BERT-ITPT-FiT 的意思是“BERT + with In-Task Pre-Training + Fine-Tuning”,上图表示IMDb 数据集上进行不同步数的继续预训练是有收益的。
  2. In-Domain 和 Cross-Domain Further Pre-Training

image 我们发现几乎所有进一步的预训练模型在所有七个数据集上的表现都比原始 BERT 基础模型。 一般来说,域内预训练可以带来比任务内预训练更好的性能。 在小句子级 TREC 数据集上,任务内预训练会损害性能,而在使用 Yah 的领域预训练中。Yah. A.语料库可以在TREC上取得更好的结果。 这篇论文与其他模型进行了比较,结果如下表所示:

image

改进1 Last 4 Layers Concatenating

class LastFourModel(nn.Module):
    
    def __init__(self):
        super().__init__()
        
        config = AutoConfig.from_pretrained(PRE_TRAINED_MODEL_NAME)
        config.update({'output_hidden_states':True})
        self.model = AutoModel.from_pretrained(PRE_TRAINED_MODEL_NAME, config=config)
        self.linear = nn.Linear(4*HIDDEN_SIZE, n_classes)
        
    def forward(self, input_ids, attention_mask):
        
        outputs = self.model(input_ids, attention_mask)
        all_hidden_states = torch.stack(outputs[2])
        concatenate_pooling = torch.cat(
            (all_hidden_states[-1], all_hidden_states[-2], all_hidden_states[-3], all_hidden_states[-4]), -1
        )
        concatenate_pooling = concatenate_pooling[:,0]
        output = self.linear(concatenate_pooling)
        
        return soutput

改进2 模型层间差分学习率

def get_parameters(model, model_init_lr, multiplier, classifier_lr):
    parameters = []
    lr = model_init_lr
    for layer in range(12,-1,-1):
        layer_params = {
            'params': [p for n,p in model.named_parameters() if f'encoder.layer.{layer}.' in n],
            'lr': lr
        }
        parameters.append(layer_params)
        lr *= multiplier
    classifier_params = {
        'params': [p for n,p in model.named_parameters() if 'layer_norm' in n or 'linear' in n 
                   or 'pooling' in n],
        'lr': classifier_lr
    }
    parameters.append(classifier_params)
    return parameters
parameters=get_parameters(model,2e-5,0.95, 1e-4)
optimizer=AdamW(parameters)

改进3 ITPT 继续预训练

import warnings
import pandas as pd
from transformers import (AutoModelForMaskedLM,
                          AutoTokenizer, LineByLineTextDataset,
                          DataCollatorForLanguageModeling,
                          Trainer, TrainingArguments)

warnings.filterwarnings('ignore')

train_data = pd.read_csv('data/train/train.csv', sep='\t')
test_data = pd.read_csv('data/test/test.csv', sep='\t')
train_data['text'] = train_data['title'] + '.' + train_data['abstract']
test_data['text'] = test_data['title'] + '.' + test_data['abstract']
data = pd.concat([train_data, test_data])
data['text'] = data['text'].apply(lambda x: x.replace('\n', ''))

text = '\n'.join(data.text.tolist())

with open('text.txt', 'w') as f:
    f.write(text)

model_name = 'roberta-base'
model = AutoModelForMaskedLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.save_pretrained('./paper_roberta_base')

train_dataset = LineByLineTextDataset(
    tokenizer=tokenizer,
    file_path="text.txt",  # mention train text file here
    block_size=256)

valid_dataset = LineByLineTextDataset(
    tokenizer=tokenizer,
    file_path="text.txt",  # mention valid text file here
    block_size=256)

data_collator = DataCollatorForLanguageModeling(
    tokenizer=tokenizer, mlm=True, mlm_probability=0.15)

training_args = TrainingArguments(
    output_dir="./paper_roberta_base_chk",  # select model path for checkpoint
    overwrite_output_dir=True,
    num_train_epochs=5,
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    gradient_accumulation_steps=2,
    evaluation_strategy='steps',
    save_total_limit=2,
    eval_steps=200,
    metric_for_best_model='eval_loss',
    greater_is_better=False,
    load_best_model_at_end=True,
    prediction_loss_only=True,
    report_to="none")

trainer = Trainer(
    model=model,
    args=training_args,
    data_collator=data_collator,
    train_dataset=train_dataset,
    eval_dataset=valid_dataset)

trainer.train()
trainer.save_model(f'./paper_roberta_base')

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Keras文本分类实战(上)

    很多时候,人们在网上晒各种东西、抒发情感。个体的情感分析可能没有多大用处,但对大多数人的情感进行分析,就能得到比较有趣的结果。想象一下,当一个热点新闻事件出现后...

    用户3578099
  • LSTM文本分类实战

    作者:王千发 编辑:龚 赛 什么是文本分类 1 文本分类在文本处理中是很重要的一个模块,它的应用也非常广泛,比如:垃圾过滤,新闻分类,等等...

    机器学习算法工程师
  • Flair实战文本分类

    Flair是一个基于PyTorch构建的NLP开发包,它在解决命名实体识别(NER)、语句标注(POS)、文本分类等NLP问题时达到了当前的顶尖水准。本文将介绍...

    用户1408045
  • 【论文解读】文本分类上分利器:Bert微调trick大全

    论文标题:How to Fine-Tune BERT for Text Classification? 中文标题:如何微调 BERT 进行文本分类? 论文作...

    致Great
  • Keras文本分类实战(下)

    在上一节Keras文本分类实战(上),讲述了关于NLP的基本知识。这部分,将学会以不同方式将单词表示为向量。

    用户3578099
  • Snorkel实战NLP文本分类

    本文是作者一个tweet/微博文本分类实战项目的全程重现与总结。该项目的最大特点是使用了弱监督技术(Snorkel)来获得海量标注数据,同时使用预训练语言模型进...

    用户1408045
  • 【NLP实战】文本分类之 TextCNN

    上面一篇文章中,我介绍了一篇利用RNN via Attention解决有毒评论文本分类问题。然而,在工业生产中,RNN、LSTM、GRU等循环神经网络不能并行计...

    yuquanle
  • [PLM专题] 十分钟了解文本分类通用训练技巧

    欢迎大家来到预训练语言模型的专题系列分享,本篇推送是该专题系列的第三篇。在前两篇推送[萌芽时代],[风起云涌]中,我们分享了该领域的奠基文章以及声名鹊起却生不逢...

    朴素人工智能
  • 文本分类实战(八)—— Transformer模型

      文本分类这个系列将会有十篇左右,包括基于word2vec预训练的文本分类,与及基于最新的预训练模型(ELMo,BERT等)的文本分类。

    西西嘛呦
  • 用NodeJS/TensorFlowJS调用BERT实现文本分类

    更多内容和代码可以参考这个REPO https://github.com/qhduan/bert-model/

    段清华DEAN
  • 用NodeJS/TensorFlowJS调用BERT实现文本分类

    题图 "JavaScript Logo"byb0neskullis licensed underCC BY-NC-SA 2.0

    段清华DEAN
  • 【NLP实战】文本分类之NBSVM算法

    朴素贝叶斯(Naive Bayes, NB)和支持向量机(Support Vector Machines, SVM)的变体常被用作文本分类的基线方法,但它们的性...

    yuquanle
  • BERT中文实战:文本相似度计算与文本分类

    谷歌提供了以下几个版本的BERT模型,每个模型的参数都做了简单的说明,中文的预训练模型在11月3日的时候提供了,这里我们只需要用到中文的版本

    大数据技术与机器学习
  • 【NLP实战系列】朴素贝叶斯文本分类实战

    实战是学习一门技术最好的方式,也是深入了解一门技术唯一的方式。因此,NLP专栏计划推出一个实战专栏,让有兴趣的同学在看文章之余也可以自己动手试一试。

    用户1508658
  • 【NLP实战】手把手带你CNN文本分类

    本文是对经典论文《Convolutional Neural Networks for Sentence Classification[1]》的详细复现,(应该是...

    yuquanle
  • 【NLP实战】手把手带你RCNN文本分类

    之前介绍的都是属于深度神经网络框架的,那么在Deep Learning出现或者风靡之前,文本分类是怎么做的呢?

    yuquanle
  • 【NLP实战】手把手带你fastText文本分类

    今天的教程是基于FAIR的Bag of Tricks for Efficient Text Classification[1]。也就是我们常说的fastText...

    yuquanle
  • 【NLP实战】手把手带你RNN文本分类

    参考的的论文是来自2016年复旦大学IJCAI上的发表的关于循环神经网络在多任务文本分类上的应用:Recurrent Neural Network for Te...

    yuquanle
  • NLP文本分类 落地实战五大利器!

    文本分类是NLP领域的最常见工业应用之一,也是本人在过去的一年中接触到最多的NLP应用,本文「从工业的角度浅谈实际落地中文本分类的种种常见问题和优化方案」。

    NewBeeNLP

扫码关注云+社区

领取腾讯云代金券