创建和微调句子变换器以提升分类准确性 机器学习博客

5

提升分类准确度的句子变换器创建与微调

作者:Kara Yang Farshad Harirchi 和 James Poquiz 发布于 2024年10月30日 亚马逊 SageMaker

重点总结

句子变换器是一种强大的深度学习模型,能够将句子转化为高质量的固定长度嵌入,从而捕捉其语义含义。在这篇文章中,我们将展示如何微调句子变换器,以便更好地将亚马逊产品分类。我们比较了两种不同的句子变换器,并证明了基于亚马逊产品数据微调的模型能显著提高分类准确度。具体步骤包括:

数据预处理与微调使用 XGBoost 分类器提升产品分类准确率测试不同句子变换器的分类表现

引言

句子变换器是强大的深度学习模型,能够将句子转换为高质量的、固定长度的嵌入表示,捕捉其语义含义。这些嵌入对于各种自然语言处理NLP任务都非常有用,例如文本分类、聚类、语义搜索和信息检索。

在本文中,我们展示了如何专门微调句子变换器,以便将亚马逊产品分类如玩具或运动器材。我们对比了两种不同的句子变换器paraphraseMiniLML6v2和一个名为M5ASINSMALLV20的亚马逊专有大语言模型LLM,并比较了它们的结果。M5 LLMS 是基于 BERT 的 LLM,已在内部亚马逊产品目录数据上微调,使用了产品标题、要点和描述等信息。我们的假设是,由于M5ASINSMALLV20是基于亚马逊产品数据微调的,因此在亚马逊产品分类的用例中,它的表现会更好。我们将在后续实验中证明这一假设。

解决方案概述

在本文中,我们演示了如何利用亚马逊产品数据微调句子变换器,并使用所得到的句子变换器提高使用 XGBoost 决策树的产品类别分类准确率。为此,我们使用了一个名为Amazon Product Dataset 2020的公共亚马逊产品数据集,该数据集来自一个kaggle比赛。该数据集包含以下属性和字段:

属性描述域名amazoncom日期范围2020年1月1日到2020年1月31日文件扩展名CSV可用字段唯一 ID、产品名称、品牌名称、ASIN、类别、UPC EAN 代码、上市价格、销售价格、数量、型号、关于产品、产品规格、技术细节、运输重量、产品维度、图片、变体、SKU、产品网址、库存、产品详细信息、维度、颜色、成分、使用说明、是否为亚马逊卖家、尺寸数量变体、产品描述标签字段类别

前提条件

在开始之前,请安装以下软件包,可以在亚马逊 SageMaker 笔记本或本地 Jupyter 笔记本中运行以下命令:

bash!pip install sentencepiece quiet!pip install sentencetransformers quiet!pip install xgboost quiet!pip install scikitlearn quiet

数据预处理

微调句子变换器的第一步是对亚马逊产品数据进行预处理,以便其能够有效地消耗数据并进行微调。这包括规范化文本数据,从类别字段中提取主要类别,定义产品的主要类别,并选择数据集中最重要的字段,以准确分类产品的主要类别。我们使用以下代码进行预处理:

pythonimport pandas as pdfrom sklearnpreprocessing import LabelEncoder

data = pdreadcsv(marketingsampleforamazoncomecommerce202001012020013110kdatacsv)datacolumns = datacolumnsstrlower()strreplace( )data[maincategory] = data[category]strsplit()str[0]data[alltext] = dataapply( lambda r join( [ str(r[productname]) if pdnotnull(r[productname]) else str(r[aboutproduct]) if pdnotnull(r[aboutproduct]) else str(r[productspecification]) if pdnotnull(r[productspecification]) else str(r[technicaldetails]) if pdnotnull(r[technicaldetails]) else ] ) axis=1)labelencoder = LabelEncoder()labelstransform = labelencoderfittransform(data[maincategory])data[label]=labelstransformdata[[alltextlabel]]

以下截图展示了数据预处理后我们的数据集的示例。

微调句子变换器 paraphraseMiniLML6v2

我们微调的第一个句子变换器称为paraphraseMiniLML6v2。它使用流行的BERT模型作为基础架构,将产品描述文本转化为 384 维的密集向量嵌入,供我们的 XGBoost 分类器用于产品类别分类。我们使用以下代码对 paraphraseMiniLML6v2 进行微调,使用的正是预处理后的亚马逊产品数据:

pythonfrom sentencetransformers import SentenceTransformermodelname=paraphraseMiniLML6v2model = SentenceTransformer(modelname)

第一步是定义一个分类头,以表示亚马逊产品可以分类到的 24 个产品类别。此分类头将用于专门训练句子变换器,以便在将产品描述转化为嵌入时,更加有效地按照 24 个产品类别进行转换。我们的想法是,同一类别的所有产品描述,其生成的向量嵌入应该在距离上更接近,而不同类别的产品描述则应相对遥远。

以下代码用于微调句子变换器 1:

pythonimport torchnn as nn

定义分类头

class ClassificationHead(nnModule) def init(self embeddingdim numclasses) super(ClassificationHead self)init() selflinear = nnLinear(embeddingdim numclasses)

def forward(self features)    x = features[sentenceembedding]    x = selflinear(x)    return x

定义分类任务的类别数

numclasses = 24print(分类数量 numclasses)classificationhead = ClassificationHead(modelgetsentenceembeddingdimension() numclasses)

组合句子变换器模型和分类头

class SentenceTransformerWithHead(nnModule) def init(self transformer head) super(SentenceTransformerWithHead self)init() selftransformer = transformer selfhead = head

def forward(self input)    features = selftransformer(input)    logits = selfhead(features)    return logits

modelwithhead = SentenceTransformerWithHead(model classificationhead)

接下来,我们设置微调参数。对于本次文章,我们选择在五个轮次中进行训练,优化交叉熵损失,并使用AdamW优化方法。我们选择第 5 轮是因为,在测试了多种轮次值后,我们发现损失在第 5 轮达到了最小值,这使其成为实现最佳分类结果的理想训练迭代次数。

以下代码用于微调句子变换器 2:

pythonimport ososenviron[TORCHUSECUDADSA] = 1osenviron[CUDALAUNCHBLOCKING] = 1

from sentencetransformers import SentenceTransformer InputExampleimport torchfrom torchutilsdata import DataLoaderfrom transformers import AdamW getlinearschedulewithwarmup

trainsentences = data[alltext]trainlabels = data[label]

训练参数

numepochs = 5batchsize = 2learningrate = 2e5

将数据集转换为 PyTorch 张量

trainexamples = [InputExample(texts=[s] label=l) for s l in zip(trainsentences trainlabels)]

自定义 collatefn 以将 InputExample 对象转换为张量

def collatefn(batch) texts = [exampletexts[0] for example in batch] labels = torchtensor([examplelabel for example in batch]) return texts labels

traindataloader = DataLoader(trainexamples shuffle=True batchsize=batchsize collatefn=collatefn)

定义损失函数、优化器和学习率调度器

criterion = nnCrossEntropyLoss()optimizer = AdamW(modelwithheadparameters() lr=learningrate)totalsteps = len(traindataloader) numepochsscheduler = getlinearschedulewithwarmup(optimizer numwarmupsteps=0 numtrainingsteps=totalsteps)

训练循环

losslist=[]for epoch in range(numepochs) modelwithheadtrain() for step (texts labels) in enumerate(traindataloader) labels = labelsto(modeldevice) optimizerzerograd()

    # 编码文本并通过分类头    inputs = modeltokenize(texts)    inputids = inputs[inputids]to(modeldevice)    inputattentionmask = inputs[attentionmask]to(modeldevice)    inputsfinal = {inputids inputids attentionmask inputattentionmask}    # 将 modelwithhead 移到同一设备    modelwithhead = modelwithheadto(modeldevice)    logits = modelwithhead(inputsfinal)    loss = criterion(logits labels)    lossbackward()    optimizerstep()    schedulerstep()    if step  100 == 0        print(fEpoch {epoch} Step {step} Loss {lossitem()})print(fEpoch {epoch1}/{numepochs} Loss {lossitem()})modelsavepath = f/intermediateoutput/epoch{epoch}modelsave(modelsavepath)losslistappend(lossitem())

保存最终模型

modelfinalsavepath=stftepoch5modelsave(modelfinalsavepath)

啊哈加速器官网版下载

接下来,我们将通过将微调后的句子变换器用作XGBoost分类器的文本嵌入项,以观察其是否提高了产品类别分类准确率。

XGBoost 分类

XGBoost极限梯度提升 分类是一种机器学习技术,常用于分类任务。它是梯度提升框架的一种实现,旨在高效、灵活且便于移植。在这篇文章中,我们使用XGBoost处理句子变换器出的产品描述文本嵌入,并观察产品类别分类准确性。以下代码使用标准的paraphraseMiniLML6v2句子变换器在微调之前将亚马逊产品分类到其各自类别:

pythonfrom sklearnmodelselection import traintestsplitimport xgboost as xgbfrom sklearnmetrics import accuracyscore

model = SentenceTransformer(paraphraseMiniLML6v2)data[textembedding] = data[alltext]apply(lambda x modelencode(str(x)))textembeddings = pdDataFrame(data[textembedding]tolist() index=dataindex dtype=float)

将以字符串存储的数值列转换为浮点数

numericcolumns = [sellingprice shippingweight productdimensions] # 可根据需要添加更多列for col in numericcolumns data[col] = pdtonumeric(data[col] errors=coerce)

将分类列转换为类别类型

categoricalcolumns = [modelnumber isamazonseller] # 可根据需要添加更多列for col in categoricalcolumns data[col] = data[col]astype(category)

X0 = data[[sellingpricemodelnumberisamazonseller]]X = pdconcat([X0 textembeddings] axis=1)labelencoder = LabelEncoder()data[maincategoryencoded] = labelencoderfittransform(data[maincategory])y = data[maincategoryencoded]Xtrain Xtest ytrain ytest = traintestsplit(X y testsize=02 randomstate=42)

重新编码标签,以确保它们是从 0 开始的连续整数

uniquelabels = sorted(set(ytrain) set(ytest))labelmapping = {label idx for idx label in enumerate(uniquelabels)}

ytrain = ytrainmap(labelmapping)ytest = ytestmap(labelmapping)

启用 XGBoost 的类别支持

dtrain = xgbDMatrix(Xtrain label=ytrain enablecategorical=True)dtest = xgbDMatrix(Xtest label=ytest enablecategorical=True)

param = { maxdepth 6 eta 03 objective multisoftmax numclass len(labelmapping) evalmetric mlogloss}

numround = 100bst = xgbtrain(param dtrain numround)

创建和微调句子变换器以提升分类准确性 机器学习博客

评估模型

ypred = bstpredict(dtest)accuracy = accuracyscore(ytest ypred)print(f准确率 {accuracy2f})

准确率 078

我们观察到使用标准paraphraseMiniLML6v2句子变换器的准确率为 78。要查看微调后的 paraphraseMiniLML6v2 的结果,我们需要更新代码开头,如下所示。其余代码保持不变。

pythonmodel = SentenceTransformer(stftepoch5)data[textembeddingminiLMft10] = data[alltext]apply(lambda x modelencode(str(x)))textembeddings = pdDataFrame(data[textembeddingfinetuned]tolist() index=dataindex dtype=float)Xpafinetuned = pdconcat([X0 textembeddings] axis=1)Xtrain Xtest ytrain ytest = traintestsplit(Xpafinetuned y testsize=02 randomstate=42)

重新编码标签,以确保它们是从 0 开始的连续整数

uniquelabels = sorted(set(ytrain) set(ytest))labelmapping = {label idx for idx label in enumerate(uniquelabels)}

ytrain = ytrainmap(labelmapping)ytest = ytestmap(labelmapping)

构建并训练 XGBoost 模型

启用 XGBoost 的类别支持

dtrain = xgbDMatrix(Xtrain label=ytrain enablecategorical=True)dtest = xgbDMatrix(Xtest label=ytest enablecategorical=True)

param = { maxdepth 6 eta 03 objective multisoftmax numclass len(labelmapping) evalmetric mlogloss}

numround = 100bst = xgbtrain(param dtrain numround)

ypred = bstpredict(dtest)accuracy = accuracyscore(ytest ypred)print(f准确率 {accuracy2f})

可选:将预测标签转换回原始类别标签

inverselabelmapping = {idx label for label idx in labelmappingitems()}ypredlabels = pdSeries(ypred)map(inverselabelmapping)

准确率 094

通过微调后的 paraphraseMiniLML6v2句子变换器,我们观察到了 94 的准确率,较基准的 78 提高了 16。通过这项观察,我们得出结论,微调 paraphraseMiniLML6v2 确实有效于将亚马逊产品数据分类到产品类别中。

微调句子变换器 M5ASINSMALLV20

现在,我们将根据一个名为 M5ASINSMALLV20 的基于 BERT 的模型创建一个句子变换器。它是一个拥有 4000 万参数的 BERT 模型,由亚马逊内部团队 M5 训练,专注于利用亚马逊产品数据微调大语言模型。它是从一个更大的教师模型大约 50 亿个参数中提炼出来的,该模型在大量无标签的 ASIN 数据上进行了预训练,并在一组亚马逊监督学习任务上进行预微调多任务预微调。它是一个多任务、多语言、多地区和多模态的 BERT 编码器,仅使用文本和结构化数据输入。其神经网络架构的详细信息如下:

模型基础: 隐藏层大小:384 隐藏层数量

使用 HashiCorp Terraform 部署 Amazon FSx for NetApp ONTAP关键要点部署和管理基础设施是一个复杂的任务,尤其是在多个环境中。使用基础设施即代码IaC可以帮助您安全、可预测地创建、修改和优化基础设施。Amazon FSx for NetApp ONTAP 是理想的共享存储解决方案,可以减轻基础设施管理的负担。本文探讨了 Terraform 的优缺点,并展...

在 Amazon SageMaker 上训练和托管计算机视觉模型进行篡改检测:第 2 部分关键要点本文介绍了如何在 Amazon SageMaker 上开发、训练和部署深度学习计算机视觉模型,以检测抵押贷款中的伪造图像。介绍了错误级分析ELA算法作为验证图像篡改的快速方法。文章提供了整合AWS服务的端到端解决方案,通过自动化文档验证和欺诈检测来提升效率。在这篇三部分系列的第一部分,我们展示了如何利...