我正在处理一个TextClassification问题,为此我试图在huggingface-transformers库中给出的TFBertForSequenceClassification上训练我的模型。
我遵循了他们的github页面上给出的示例,我能够使用tensorflow_datasets.load('glue/mrpc')
运行给定样本数据的示例代码。但是,我无法找到如何加载自己的自定义数据并将其传递到model.fit(train_dataset, epochs=2, steps_per_epoch=115, validation_data=valid_dataset, validation_steps=7)
中的示例。
我如何定义我自己的X,对我的X进行标记化,并用我的X和Y准备train_dataset。其中X表示我的输入文本,Y表示给定X的分类类别。
样本训练 Dataframe :
text category_index
0 Assorted Print Joggers - Pack of 2 ,/ Gray Pri... 0
1 "Buckle" ( Matt ) for 35 mm Width Belt 0
2 (Gagam 07) Barcelona Football Jersey Home 17 1... 2
3 (Pack of 3 Pair) Flocklined Reusable Rubber Ha... 1
4 (Summer special Offer)Firststep new born baby ... 0
字符串
4条答案
按热度按时间91zkwejq1#
微调方式
有多种方法可以为目标任务微调BERT。
1.进一步预训练基础BERT模型
1.在可训练的基础BERT模型之上的自定义分类层
1.基础BERT模型之上的自定义分类层不可训练(冻结)
请注意,BERT基础模型仅针对两个任务进行了预训练,如原始论文中所述。
3.1预训练BERT...我们使用两个无监督任务预训练BERT
因此,基本BERT模型就像是半成品,可以完全用于目标域(第一种方式)。我们可以使用它作为我们自定义模型训练的一部分,使用基础可训练(第二)或不可训练(第三)。
第一种方法
How to Fine-Tune BERT for Text Classification?展示了进一步预训练的第一种方法,并指出学习率是避免灾难性遗忘的关键,在这种情况下,预训练的知识在学习新知识时被删除。
我们发现,一个较低的学习率,如2 e-5,是必要的,使BERT克服灾难性的遗忘问题。在4 e-4的积极学习率下,训练集无法收敛。
x1c 0d1x的数据
也许这就是为什么BERT paper使用5e-5,4 e-5,3e-5和2 e-5进行微调的原因。
我们使用32的批量大小,并对所有GLUE任务的数据进行3个时期的微调。对于每个任务,我们在Dev集上选择最佳微调学习率(在5e-5、4 e-5、3e-5和2 e-5中
注意,基础模型预训练本身使用更高的学习率。
该模型在Pod配置中的4个云TPU(总共16个TPU芯片)上训练一百万步,批量大小为256。对于90%的步骤,序列长度被限制为128个令牌,对于剩余的10%,序列长度被限制为512个令牌。使用的优化器是Adam,学习率为
1e-4
,β1=0.9
和β2=0.999
,权重衰减为0.01
,学习率预热10,000步,之后学习率线性衰减。将描述第一种方法作为下面第三种方法的一部分。
仅供参考:TFDistilBertModel是名为
distilbert
的裸基础模型。字符串
第二种方法
Huggingface采用了第二种方法,如使用原生PyTorch/TensorFlow进行微调,其中
TFDistilBertForSequenceClassification
在可训练的基础distilbert
模型之上添加了自定义分类层classifier
。小的学习率要求也将适用于避免灾难性的遗忘。的数据
第二种方式的实现
型
第三种方法
基础知识
请注意,这些图像是从A Visual Guide to Using BERT for the First Time拍摄并修改的。
Tokenizer
Tokenizer生成BatchEncoding的示例,它可以像Python字典一样使用,也可以作为BERT模型的输入。
保存encode_plus()和batch_encode()方法的输出(tokens、attention_masks等)。
这个类是从python字典派生的,可以用作字典。此外,此类公开实用程序方法以从单词/字符空间Map到标记空间。
主要参数
类的
data
属性是生成的令牌,其中包含input_ids
和attention_mask
元素。input_ids
输入id通常是作为输入传递给模型的唯一所需参数。它们是标记索引,标记的数字表示构建将用作模型输入的序列。
attention_mask
该参数向模型指示哪些令牌应该被关注,哪些不应该。
如果attention_mask为
0
,则忽略令牌id。例如,如果序列被填充以调整序列长度,则填充的字应当被忽略,因此它们的attention_mask为0。特殊令牌
BertTokenizer添加特殊令牌,包含一个序列
[CLS]
和[SEP]
。[CLS]
表示分类,[SEP]
分隔序列。对于问答或释义任务,[SEP]
将两个句子分开进行比较。BertTokenizer
进行序列分类时使用的分类器令牌(对整个序列进行分类,而不是按令牌分类)。当使用特殊标记构建时,它是序列的第一个标记。
分隔符标记,当从多个序列构建序列时使用,例如用于序列分类的两个序列或用于文本和用于问答的问题。它也用作用特殊标记构建的序列的最后一个标记。
A Visual Guide to Using BERT for the First Time显示标记化。
的
[CLS]
在来自基础模型最终层的输出中的**
[CLS]
的嵌入向量表示基础模型已经学习的分类。因此,将[CLS]
**标记的嵌入向量馈送到添加在基础模型之上的分类层中。每个序列的第一个标记始终是
a special classification token ([CLS])
。对应于此标记的最终隐藏状态用作分类任务的聚合序列表示。句子对被打包成单个序列。我们用两种方法来区分句子。首先,我们用一个特殊的标记([SEP])将它们分开。其次,我们将学习嵌入添加到每个标记,以指示它属于句子A还是句子B。该模型结构如下所示。
的
的
向量大小
在模型
distilbert-base-uncased
中,每个标记被嵌入到大小为768的向量中。基础模型输出的形状为(batch_size, max_sequence_length, embedding_vector_size=768)
。这与BERT关于BERT/BASE模型的论文一致(如distilbert-base-uncased中所示)。BERT/底座(L=12,H=768,A=12,总参数= 110 M)和BERT/大型(L=24,H=1024,A=16,总参数= 340 M)。
基本模型- TFDistilBertModel
用于示例化基DistilBERT模型的TFDistilBertModel类**,但顶部没有任何特定的头**(与其他类(如TFDistilBertForSequenceClassification)相反,这些类具有添加的分类头)。
我们不希望附加任何特定于任务的标题,因为我们只是希望基本模型的预训练权重提供对英语的一般理解,并且我们的工作是在微调过程中添加我们自己的分类标题,以便帮助模型区分有害评论。
TFDistilBertModel
生成TFBaseModelOutput
的示例,其last_hidden_state
参数是模型最后一层的输出。型
主要参数
实施
Python模块
型
配置
型
令牌化程序
型
输入图层
基本模型需要
input_ids
和attention_mask
,它们的形状为(max_sequence_length,)
。分别用Input
层为它们生成KerasTensor。型
基础模型层
从基础模型生成输出。基本模型生成
TFBaseModelOutput
。将**[CLS]
**的嵌入进给到下一层。型
分类图层
型
Softmax图层
型
最终定制模型
型
数据分配
型
火车
型
要实施第一种方法,请按如下所示更改配置。
型
然后,将
FREEZE_BASE
更改为False
,并将LEARNING_RATE
更改为5e-5
,这将在基础BERT模型上运行进一步预训练。保存模型
对于第三种方法,保存模型将导致问题。无法使用拥抱面部模型的保存_pretrained方法,因为该模型不是拥抱面部预训练模型的直接子类。
Keras save_model会导致预设
save_traces=True
发生错误,或在载入具有Keras load_model的模型时,导致save_traces=True
发生不同的错误。型
就我测试的情况而言,只有Keras Model保存_weights工作正常。
实验
就我使用Toxic Comment Classification Challenge进行的测试而言,第一种方法的召回率更高(识别真正的有毒注解,真正的无毒注解)。可以按如下方式访问代码。如有任何更正/建议,请提供。
相关
ewm0tg9j2#
使用自定义数据集文件的
HuggingFace
转换器的好例子并不多。让我们首先导入所需的库:
字符串
并定义所需的常量:
型
现在是读取数据集的时候了:
型
然后从预训练的BERT中定义所需的模型用于序列分类:
型
现在我们需要使用定义的函数示例化模型,并编译我们的模型:
型
创建一个用于标记化的函数(将文本转换为标记):
型
加载令牌化器:
型
将数据拆分为训练和验证部分:
型
对集合进行编码:
型
最后,我们可以使用训练集拟合我们的模型,并在每个epoch之后使用验证集进行验证:
型
h6my8fg23#
您需要使用预期的模式转换
tf.data
的输入数据,以便首先创建特征,然后训练分类模型。如果您查看
tensorflow_datasets
link的胶水数据集,您会看到数据具有特定的模式:字符串
如果您希望使用
convert_examples_to_features
来准备好要注入到模型中的数据,则需要这样的模式。转换数据并不像pandas那样简单,它将严重依赖于输入数据的结构。
例如你可以找到here一步一步做这样的转换.这可以使用
tf.data.Dataset.from_generator
来完成。alen0pnh4#
扩展来自konstantin_doncov的答案。
配置文件
在安装模型时,需要定义在Transformers配置文件中定义的模型初始化参数。基类为PretrainedConfig。
所有配置类的基类。处理所有型号配置通用的一些参数以及加载/下载/保存配置的方法。
每个子类都有其自己的参数,例如,Bert预训练模型具有BertConfig。
这是用于存储BertModel或TFBertModel配置的配置类。它用于根据指定的参数示例化BERT模型,定义模型架构。使用默认值示例化配置将产生与BERT bert-base-uncased体系结构类似的配置。
例如,
num_labels
参数来自预训练配置num_labels(int,可选)-要在添加到模型得最后一层中使用得标签数,通常用于分类责任.
字符串
bert-base-uncased
型号的配置文件发布在Huggingface model - bert-base-uncased - config.json上。型
微调(迁移学习)
Huggngface提供了几个示例,用于对您自己的自定义数据集进行微调。例如,利用BERT的序列分类能力进行文本分类。
本教程将带您通过几个例子,使用Transformers模型与您自己的数据集。
如何从变形金刚库中微调预训练的模型。在TensorFlow中,可以使用Keras和拟合方法直接训练模型。
但是,文档中的示例只是概述,缺乏详细信息。
使用原生PyTorch/TensorFlow进行微调
型
github提供了完整的代码。
此文件夹包含一些脚本,这些脚本显示了使用拥抱变形金刚库进行文本分类的示例。
run_text_classification.py是针对TensorFlow进行文本分类微调的示例。
然而,这并不简单,也不直接,因为它是通用的和通用的用法。因此,没有一个很好的例子,让人们开始,造成的情况下,人们需要提出这样的问题。
分类图层
您会看到迁移学习(微调)文章解释了如何在预先训练的基础模型上添加分类层,答案中也是如此。
型
但是,文档中的huggingface示例没有添加任何分类层。
型
这是因为
TFBertForSequenceClassification
已经添加了这些层。基本DistilBERT模型顶部没有任何特定的头(与其他类相反,例如TFDistilBertForSequenceClassification,它具有添加的分类头)。
如果显示Keras模型摘要(例如
TFDistilBertForSequenceClassification
),则会显示添加到基础BERT模型顶部的Dense和Dropout层。型
冻结基础模型参数
有一些讨论,例如Fine Tune BERT Models,但很明显,Huggingface的方法不是冻结基本模型参数。如图所示,Keras模型总结abobe
Non-trainable params: 0
。冻结基础
distilbert
图层。型
资源
Kaggle是其他需要研究的资源。用关键字“huggingface”“BERT”搜索,你会找到为比赛发布的工作代码。