Transformer实战(24)——通过数据增强提升Transformer模型性能

Transformer实战(24)------通过数据增强提升Transformer模型性能

    • [0. 前言](#0. 前言)
    • [1. 通过数据增强提升 Transformer 模型性能](#1. 通过数据增强提升 Transformer 模型性能)
    • [2. 字符级增强](#2. 字符级增强)
    • [3. 词级增强](#3. 词级增强)
    • [4. 句子级增强](#4. 句子级增强)
    • [5. 使用数据增强提升 IMDb 文本分类性能](#5. 使用数据增强提升 IMDb 文本分类性能)
    • 小结
    • 系列链接

0. 前言

我们已经使用经典 Tansformer 模型解决了许多任务,但我们可以通过利用特定的技术来进一步提高模型性能。有多种方法可以提升 Transformer 模型的性能,在节中,我们将介绍如何通过数据增强技术将模型性能提升到超越普通训练流程的水平。数据增强广泛应用于提高深度学习模型的准确性,通过增强数据样本,深度学习模型能够更有效地捕捉数据中的潜在模式和关系。

1. 通过数据增强提升 Transformer 模型性能

数据增强是深度学习中提高模型成功率的常用技术,通过对数据样本进行不显著改变其含义的修改来复制数据。这种技术在图像处理和自然语言处理 (Natural Language Processing, NLP) 中得到了广泛应用,因为使用更多的数据训练神经模型通常会带来更好的性能。

我们可以通过向现有数据引入噪声或扰动,创造相同数据的新变体,或者通过插值生成全新的数据点,后者是基于几个相邻的现有数据点生成新数据。数据增强在训练数据有限时尤为有用,它可以让模型更具鲁棒性,并提升其在下游任务中的表现。

数据增强有多种实现方式。在图像处理中,包括翻转图像或调整图像亮度。在 NLP 中,包括删除或替换单词、注入随机字符/单词、改变句子中单词的顺序,以及其它高级技术。

数据增强的过程取决于具体的 NLP 任务。如果正在进行语言可接受性的分类任务,打乱词语顺序可能并不是一种有效的增强方法。如果在进行情感分类任务,这种类型的打乱过程可能是可行的。关键问题是要单独评估每种增强技术,以确定哪些技术有效,因为很难在没有实验的情况下判断哪些增强技术会对我们有所帮助。

数据增强过程在对比学习领域也得到了广泛应用。对比学习方法使我们能够通过数据增强轻松创建正负样本,用于自监督学习。因此,我们不仅能通过增加数据量从数据增强中受益,还能在自监督学习中获益。

接下来,我们通过IMDb 情感分类来探讨常用的数据增强技术,并使用它们来提升模型的性能。

2. 字符级增强

字符级增强仅涉及对字符的操作。我们可以通过操作字符来简单地增强数据,其中常用的方法包括:

字符级增强 原始数据 增强数据
键盘增强器:基于键盘邻近距离替换字符 I love cats and dogs I lobe cats and dogx
随机增强器:随机插入/交换/删除字符 love cats and dogs I love cats an doggs
OCR 错误模拟器:模拟 OCR 识别错误(如 e 识别为 o) branches branchos

3. 词级增强

词级增强方法比字符级增强方法有更多的可能性。我们可以依赖词汇的语义信息,这类技术大多基于预定义的词汇列表,且易于应用。

词级增强 原始数据 增强数据
拼写错误字典:使用一个预定义的常见拼写错误字典 achieve acheive
上下文感知词嵌入增强器:通过深度学习模型(如 Word2VecBERT )将词语替换为上下文语义最接近的词 Banana Apple
同义词替换:基于同义词词典进行替换 large big
反义词替换:基于反义词词典进行替换 large small
随机词删除/插入:随机删除或插入文本中的词语 I love cats and dogs I love cats
词语乱序:随机打乱句中词语顺序 I love cats and dogs love and cats dogs I

尽管词级增强可能非常有效,但它也有一定的局限性,因为词级操作是独立于上下文的,无法利用句子中的语义信息。这就是我们考虑使用基于句子语义的更高级技术的原因。

4. 句子级增强

句子级增强是一种考虑整个句子及其含义的数据增强方法。随着语言模型的不断发展,这种技术变得越来越常见。

回译是将文本翻译成另一种语言(例如从英语翻译成法语),然后再将其翻译回原始语言(从法语翻译成英语)。另一个例子是将文本从语言 A 翻译成语言 B,然后翻译成语言 C,最后以相同的方式翻译回原始语言(从语言 C 到语言 B,再到语言 A)。

释义是另一种语义上重新生成文本的方法,通过使用训练好的模型生成语义相同但表述不同的文本。因此,这种方法非常适合用作数据增强。

但,以上两种方法,由于神经模型的推理时间较长,增强过程比字符级和词级增强耗时更长。以下是一些句子级增强的示例:

句子级增强 原始数据 增强数据
回译:将原文翻译为另一种语言后再译回原语言 You have to think a lot to understand It takes a lot of thought to understand
释译:使用文本到文本模型 Life is the future, not the past The future, not the past, is where life lies

接下来,我们将这些技术应用于 NLP 任务,并观察它们是否能提高模型性能。

5. 使用数据增强提升 IMDb 文本分类性能

接下来,我们将通过使用 nlpaug 库,利用数据增强方法来提高IMDB 情感分析任务的模型性能。
nlpaug 库可以为 IMDB 数据集进行文本数据增强,库中包含多种数据增强方法。在本节中,仅应用了一些随机选择的方法进行演示,但重要的是进行彻底分析,以确定哪些增强技术最适合解决当前的 NLP 任务。

(1) 首先使用 pip 命令安装所需库:

shell 复制代码
$ pip install nlpaug datasets transformers sacremoses

(2) 导入用于增强的工具:

python 复制代码
import nlpaug.augmenter.char as nac
import nlpaug.augmenter.word as naw
import nlpaug.augmenter.sentence as nas
import nlpaug.flow as nafc
from nlpaug.util import Action

在本节中,为了实现快速原型开发以及评估增强技术对模型性能的影响,我们仅使用了 IMDb 数据集的一部分。

(3) 选择 2000 个数据样本作为训练数据:

python 复制代码
from datasets import load_dataset
imdb_train= load_dataset('imdb', split="train[:1000]+train[-1000:]")
imdb_test= load_dataset('imdb', split="test[:500]+test[-500:]")
imdb_val= load_dataset('imdb', split="test[500:1000]+test[-1000:-500]")
imdb_train.shape, imdb_test.shape, imdb_val.shape
# ((2000, 2), (1000, 2), (1000, 2))

(4) 定义所需函数 compute_metrics() 用于评估模型,函数 tokenize_it() 用于分词:

python 复制代码
from sklearn.metrics import (accuracy_score, precision_recall_fscore_support)

def compute_metrics(pred):
    labels = pred.label_ids
    preds = pred.predictions.argmax(-1)
    precision, recall, f1, _ = precision_recall_fscore_support(labels,preds, average='macro')
    acc = accuracy_score(labels, preds)
    return {
    'Accuracy': acc,
    'F1': f1,
    'Precision': precision,
    'Recall': recall
    }

def tokenize_it(e):
    return tokenizer(e['text'], padding=True, truncation=True)

(5) 使用 nlpaug 库实例化 10 个不同的随机增强对象:

python 复制代码
import nlpaug.augmenter.word as naw

#substitute character by keyboard distance
aug1 = nac.KeyboardAug(aug_word_p=0.2, aug_char_max=2, aug_word_max=4)

# random insert/swap/delete
aug2 = nac.RandomCharAug(action="insert", aug_char_max=1)
aug3 = nac.RandomCharAug(action="swap", aug_char_max=1)
aug4 = nac.RandomCharAug(action="delete", aug_char_max=1)

# spelling error
aug5 = naw.SpellingAug()

# contextual word insertion / substitute
aug6 = naw.ContextualWordEmbsAug(model_path='bert-base-uncased', action="insert")
aug7 = naw.ContextualWordEmbsAug(model_path='bert-base-uncased', action="substitute")

# wordnet-based synonym replacement
aug8 = naw.SynonymAug(aug_src='wordnet')

# random word deletion
aug9 = naw.RandomWordAug()

# back-translation
aug10 = naw.BackTranslationAug(from_model_name='facebook/wmt19-en-de', to_model_name='facebook/wmt19-de-en', device='cuda')

(6) 编写包装函数 augment_it(),该函数集成并应用 10 种增强技术。参数包括要增强的原始文本 (text) 和原始标签 (label),为每个增强文本复制原始标签:

python 复制代码
def augment_it(text, label):
    result= [eval("aug"+str(i)).augment(text)[0] for i in range(1,11) ]
    return result, [label]* len(result)

(7) 测试 augment_it() 函数,可以看到,函数返回了 10 个标签为 1 的复制文本:

python 复制代码
augment_it("i like cats and dogs",1)
(['i like cats and cogZ',
  'i *like cats and 2dogs',
  'i ilke cats and odgs',
  'i lke cat and dogs',
  'i like kets and gods',
  'i see like cats birds and dogs',
  'i loved cats and kids',
  'iodin like cats and dogs',
  'i like and',
  'I like cats and dogs'],
 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1])

需要注意的是,回译并没有生成新的句子,而是返回相同的句子,因为给定的数据对于翻译来说非常简单。对于更复杂的数据,我们可能会得到不同的结果。

IMDB 数据集进行随机抽样,选取其中 10% 的数据并进行复制。对于每个被选中的样本,将生成 10 个增强的句子,最终输入数据集的大小将翻倍。由于代码使用了类似BERT的模型,生成过程会相对较慢。

(8) 我们可以通过调整增强程度 (frac -> [0.1 - 1.0]) 来观察对性能的影响,范围可以覆盖整个数据集,或者通过增加增强技术的数量来进一步改进效果:

python 复制代码
import pandas as pd

imdb_df=pd.DataFrame(imdb_train)

texts=[]
labels=[]

for r in imdb_df.sample(frac=0.1).itertuples(index=False):
    t,l=augment_it(r.text, r.label)
    texts+= t
    labels+=l

aug_df=pd.DataFrame()
aug_df["text"]= texts
aug_df["label"]= labels

imdb_augmented=pd.concat([imdb_df, aug_df])
imdb_df.shape, imdb_augmented.shape
# ((2000, 2), (4000, 2))

将数据大小从 2000 增加到了 4000,并得到了 imdb_augmented 数据集。

(9) 代码中包含两个数据集:一个是普通数据集 (imdb_train),另一个是增强数据集 (imdb_augmented)。当前选择的是普通数据集,增强数据集被注释掉。在第二次运行代码时,通过注释掉普通数据集来选择 imdb_augmented 数据集:

python 复制代码
from transformers import BertTokenizerFast, BertForSequenceClassification

model_path= 'bert-base-uncased'
tokenizer = BertTokenizerFast.from_pretrained(model_path)

#imdb train data with augmentation
# imdb_augmented2= Dataset.from_pandas(imdb_augmented)
# enc_train=imdb_augmented2.map(tokenize_it,  batched=True, batch_size=1000)

# imdb train data without augmentation
enc_train=imdb_train.map(tokenize_it,  batched=True, batch_size=1000)
enc_test=imdb_test.map(tokenize_it,  batched=True, batch_size=1000)
enc_val=imdb_val.map(tokenize_it, batched=True, batch_size=1000)

model_path= "bert-base-uncased"
model = BertForSequenceClassification.from_pretrained(model_path,  id2label={0:"NEG", 1:"POS"},  label2id={"NEG":0, "POS":1})

(10)bert-base-uncased 模型进行微调:

python 复制代码
from transformers import TrainingArguments, Trainer

training_args = TrainingArguments(output_dir='./MyIMDBModel',  
                                  do_train=True, 
                                  do_eval=True, 
                                  num_train_epochs=3, 
                                  per_device_train_batch_size=8,
                                  per_device_eval_batch_size=8,
                                  fp16=True,
                                  load_best_model_at_end=True,
                                  save_strategy='epoch',
                                  eval_strategy='epoch')

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=enc_train,
    eval_dataset=enc_val,
    compute_metrics= compute_metrics)

trainer.train()
q=[trainer.evaluate(eval_dataset=data) for data in [enc_train, enc_val, enc_test]]
pd.DataFrame(q, index=["train","val","test"]).iloc[:,:5]

没有使用增强时,输出结果如下所示:

使用增强时,输出结果如下所示:

可以看到,F1 分数87.0 提高到了 89.5。此外,其他指标也有所改善。为了进一步提高性能,我们可以扩大增强技术的应用范围,并对不同的增强方法进行详细分析,以便选择最佳方案。

小结

数据增强是一种简单而有效的方法,能够通过扩充和多样化训练数据,显著提升 Transformer 模型在自然语言处理 (Natural Language Processing, NLP) 任务中的性能,尤其在数据稀缺或多样性不足的场景下具有重要价值。本文首先介绍了数据增强的基本概念及其在深度学习中提高模型准确性的重要性,然后分析了字符级、词级和句子级三种不同粒度的数据增强方法,并以 IMDb 情感分类任务为例,使用 nlpaug 库演示了多种数据增强技术的具体实现,提升模型表现。

系列链接

Transformer实战(1)------词嵌入技术详解
Transformer实战(2)------循环神经网络详解
Transformer实战(3)------从词袋模型到Transformer:NLP技术演进
Transformer实战(4)------从零开始构建Transformer
Transformer实战(5)------Hugging Face环境配置与应用详解
Transformer实战(6)------Transformer模型性能评估
Transformer实战(7)------datasets库核心功能解析
Transformer实战(8)------BERT模型详解与实现
Transformer实战(9)------Transformer分词算法详解
Transformer实战(10)------生成式语言模型 (Generative Language Model, GLM)
Transformer实战(11)------从零开始构建GPT模型
Transformer实战(12)------基于Transformer的文本到文本模型
Transformer实战(13)------从零开始训练GPT-2语言模型
Transformer实战(14)------微调Transformer语言模型用于文本分类
Transformer实战(15)------使用PyTorch微调Transformer语言模型
Transformer实战(16)------微调Transformer语言模型用于多类别文本分类
Transformer实战(17)------微调Transformer语言模型进行多标签文本分类
Transformer实战(18)------微调Transformer语言模型进行回归分析
Transformer实战(19)------微调Transformer语言模型进行词元分类
Transformer实战(20)------微调Transformer语言模型进行问答任务
Transformer实战(21)------文本表示(Text Representation)
Transformer实战(22)------使用FLAIR进行语义相似性评估
Transformer实战(23)------使用SBERT进行文本聚类与语义搜索

相关推荐
悟乙己2 小时前
LangExtract + 知识图谱 — Google 用于 NLP 任务的新库
人工智能·自然语言处理·知识图谱
lpfasd1232 小时前
GEO崛起与AI信任危机:数据源安全如何守护智能时代的基石?
大数据·人工智能·安全
Allen正心正念20252 小时前
提升大语言模型性能的关键技术清单(from 网络)
人工智能·语言模型·自然语言处理
云雾J视界3 小时前
AI驱动半导体良率提升:基于机器学习的晶圆缺陷分类系统搭建
人工智能·python·机器学习·智能制造·数据驱动·晶圆缺陷分类
拂过世俗的风3 小时前
Hopfield神经网络简介
人工智能·深度学习·神经网络
IT_陈寒3 小时前
Vue 3响应式原理深度拆解:5个90%开发者不知道的Ref与Reactive底层实现差异
前端·人工智能·后端
swanwei3 小时前
AI与电力的深度绑定:算力与能源分配的趋势分析
大数据·人工智能
長安一片月3 小时前
深度学习的前世今生
人工智能·深度学习
逻极3 小时前
Spec-Kit 实战指南:从零到一构建“照片拖拽相册”Web App
人工智能·ai·agent·ai编程·web app