Keras深度学习框架第二十四讲:KerasNLP概述

1、KerasNLP简介

KerasNLP是一个与TensorFlow深度集成的库,旨在简化NLP(自然语言处理)任务的建模过程。它提供了一系列高级API,用于预处理文本数据、构建序列模型和执行常见的NLP任务,如情感分析、命名实体识别和机器翻译等。

通过KerasNLP,开发者可以轻松地构建和训练复杂的NLP系统,而无需深入理解底层实现的复杂性。KerasNLP提供了清晰、简洁的API设计,使开发者可以快速上手。例如,只需几行代码,就可以进行分词、词汇嵌入(Word Embeddings)、句子编码等操作。

KerasNLP基于TensorFlow,因此可以充分利用GPU和TPU加速计算,为大规模NLP任务提供高性能支持。库中的每个组件都是模块化的,允许开发者根据需要自由组合和扩展。

KerasNLP是一个功能强大、易于使用的NLP库,为开发者提供了一种高效、灵活的方式来处理NLP任务。

1.1 KerasNLP的主要应用场景

KerasNLP在多个自然语言处理(NLP)应用场景中表现出色,主要包括但不限于以下方面:

  • 文本分类:利用KerasNLP可以快速构建和优化文本分类模型,如情感分析、新闻主题分类等。这些模型可以识别文本中的关键信息,并将其归类到预定义的类别中。
  • 机器翻译:KerasNLP具有强大的序列模型构建能力,因此可以作为搭建神经网络机器翻译系统的基础。通过训练模型,可以实现源语言到目标语言的自动翻译。
  • 问答系统:在对话式AI开发中,KerasNLP可以帮助提取关键信息并生成准确的响应。这包括从文本中提取关键信息以回答问题,或者生成与问题相关的自然语言回答。
  • 命名实体识别:KerasNLP可以识别文本中的专有名词、人名、地名等命名实体,并将其分类到预定义的类别中。这对于信息抽取、知识图谱构建等任务非常有用。
  • 语音识别:虽然KerasNLP主要关注NLP任务,但它也可以与语音识别技术结合使用。例如,可以使用KerasNLP对语音转文字后的文本进行进一步处理和分析。
  • 推荐系统:虽然Keras本身不直接针对推荐系统,但结合NLP技术,KerasNLP可以用于构建基于文本内容的推荐系统。通过分析用户的文本偏好和行为,可以生成个性化的推荐内容。
  • 时间序列分析:虽然这不是KerasNLP的专长领域,但由于其底层支持TensorFlow,因此也可以用于处理和分析时间序列数据,如股票价格预测、天气预测等。

1.2 KerasNLP的优点和缺点

KerasNLP是一个专注于自然语言处理(NLP)任务的库,其基于Keras框架,并与TensorFlow等深度学习框架紧密集成。以下是KerasNLP的一些优点和缺点:

优点:

  • 简单易用:KerasNLP继承了Keras简洁、直观的API设计,使得开发者可以快速上手,并高效构建NLP模型。无需深入了解底层实现的复杂性,即可进行分词、词汇嵌入、句子编码等操作。
  • 基于TensorFlow:KerasNLP基于TensorFlow框架,因此可以充分利用GPU和TPU加速计算,为大规模NLP任务提供高性能支持。同时,TensorFlow的广泛支持和丰富的生态系统也为KerasNLP提供了强大的后盾。
  • 丰富的NLP工具:KerasNLP提供了丰富的NLP工具,包括预训练的词嵌入模型、文本分类模型、序列生成模型等,使得开发者可以快速地构建和训练NLP应用。
  • 模块化设计:KerasNLP的组件采用模块化设计,允许开发者根据需要自由组合和扩展。这种灵活性使得KerasNLP能够适应各种复杂的NLP任务。
  • 强大的社区支持:由于KerasNLP基于Keras和TensorFlow等广泛使用的框架,因此它拥有庞大的用户社区。这意味着开发者可以通过社区获取支持、分享经验和解决问题,从而更高效地学习和使用KerasNLP。

缺点:

  • 灵活性相对较低:虽然KerasNLP提供了简洁易用的API和丰富的NLP工具,但这也可能导致其在某些方面缺乏灵活性。对于一些特殊的NLP任务或需求,可能需要开发者自行编写代码或寻找其他解决方案。
  • 学习曲线可能较陡峭:虽然KerasNLP的API设计相对简洁直观,但对于初学者来说,学习和理解NLP任务和深度学习模型的基本原理可能需要一定的时间和努力。
  • 依赖外部框架:KerasNLP基于Keras和TensorFlow等外部框架,因此可能需要安装和配置这些框架才能使用KerasNLP。这可能会增加一些额外的复杂性和开销。
  • 更新速度可能较慢:由于NLP领域的研究和进展非常迅速,新的算法和技术不断涌现。然而,由于KerasNLP需要基于Keras和TensorFlow等框架进行开发和维护,因此其更新速度可能相对较慢,无法及时跟进最新的NLP技术和算法。

2、KerasNLP的使用方法

2.1内容梗概

本文将通过情感分析的例子,展示六个不同复杂度的模块化方法:

  • 使用预训练分类器进行推理

这一步是最简单的,直接使用已有的预训练模型进行推理,无需进行任何修改或训练。只需要加载预训练好的模型,并传入待分析的文本即可获取情感倾向。

  • 微调预训练的主干模型
    在这一步中,我们将加载一个预训练的主干模型(如BERT、Transformer等),并在一个特定任务(如情感分析)的数据集上进行微调。微调意味着我们保留模型的大部分权重,但会更新一部分权重以适应新任务。

  • 使用用户控制的预处理进行微调
    在微调模型时,预处理步骤(如文本清洗、分词、词汇嵌入等)通常对模型性能有很大影响。在这一步中,我们将展示如何自定义预处理步骤,并在微调模型时应用这些步骤。

  • 微调自定义模型
    在这一步中,我们将从头开始构建一个自定义的模型结构(基于现有的模型架构,但可能包含一些自定义层或连接),并在情感分析数据集上进行微调。

  • 预训练主干模型
    在某些情况下,我们可能需要从头开始训练一个全新的模型,而不是使用预训练的模型。在这一步中,我们将展示如何预训练一个主干模型,使其能够在各种NLP任务上具有良好的泛化能力。

  • 从头开始构建和训练自己的Transformer模型
    这是最复杂的一步,我们将从头开始设计并训练一个完整的Transformer模型。这包括定义模型的架构、编写自定义层、实现训练循环等。这一步需要深厚的NLP和深度学习知识,但也会带来最大的灵活性和定制性。

通过本文,读者可以逐步了解如何从简单的模型使用开始,逐步深入到模型的自定义和训练,以及最终构建自己的NLP模型。每一步都展示了如何利用KerasNLP(或其他NLP库)的模块化特性,使得NLP任务的开发更加高效和灵活。

2.2 安装和导入

!pip install -q --upgrade keras-nlp
!pip install -q --upgrade keras  # Upgrade to Keras 3.
import osos.environ["KERAS_BACKEND"] = "jax"  # or "tensorflow" or "torch"import keras_nlp
import keras# Use mixed precision to speed up all training in this guide.
keras.mixed_precision.set_global_policy("mixed_float16")

2.3API 快速入门

我们最高级的API是keras_nlp.models。这些符号涵盖了将字符串转换为标记、将标记转换为密集特征,以及将密集特征转换为特定任务输出的完整用户流程。对于每种XX架构(例如,Bert),我们提供以下模块:

分词器 (Tokenizer): keras_nlp.models.XXTokenizer
作用:将字符串转换为标记ID的序列。
为什么它很重要:字符串的原始字节维度太高,不适合作为特征使用,因此我们首先将它们映射到少量的标记上,例如将"The quick brown fox"转换为[“the”, “qu”, “##ick”, “br”, “##own”, “fox”]。
继承自:keras.layers.Layer

预处理器 (Preprocessor): keras_nlp.models.XXPreprocessor
作用:从分词开始,将字符串转换为被主干模型消费的预处理张量字典。
为什么它很重要:每个模型都使用特殊的标记和额外的张量来理解输入,例如分隔输入段和识别填充标记。将每个序列填充到相同的长度可以提高计算效率。
包含:XXTokenizer。
继承自:keras.layers.Layer

注意:这里的"XX"应替换为具体的模型架构名称,如"Bert"或"Transformer"等。

主干模型 (Backbone): keras_nlp.models.XXBackbone

作用:将预处理后的张量转换为密集特征。它不直接处理字符串,需要先调用预处理器。

为什么它很重要:主干模型将输入的标记提炼为密集特征,这些特征可以在下游任务中使用。通常,主干模型会在一个语言建模任务上使用大量无标签数据进行预训练。将这种信息转移到新任务上是现代NLP的重大突破。

继承自:keras.Model

任务模型 (Task): 例如,keras_nlp.models.XXClassifier

作用:将字符串转换为特定任务的输出(例如,分类概率)。

为什么它很重要:任务模型结合了字符串预处理、主干模型和特定任务的层,以解决诸如句子分类、标记分类或文本生成等问题。这些额外的层必须在有标签的数据上进行微调。

包含:XXBackbone 和 XXPreprocessor。

继承自:keras.Model

注意:这里的"XX"应替换为具体的模型架构名称,如"Bert"或"Transformer"等。在实际应用中,你会看到类似keras_nlp.models.BertBackbonekeras_nlp.models.BertClassifier这样的具体类名。

以下是BertClassifier的模块化层次结构(所有关系都是组合性的):
在这里插入图片描述
所有的模块都可以独立使用,并且除了标准构造函数外,还提供了from_preset()方法,该方法用于使用预设的架构和权重来实例化类(参见以下示例)。

2.4 数据准备

我们将使用一个运行中的例子,即IMDB电影评论的情感分析任务。在这个任务中,我们使用文本预测评论是否正面(标签 = 1)或负面(标签 = 0)。

我们使用keras.utils.text_dataset_from_directory来加载数据,它利用了功能强大的tf.data.Dataset格式来处理样本。

!curl -O https://ai.stanford.edu/~amaas/data/sentiment/aclImdb_v1.tar.gz
!tar -xf aclImdb_v1.tar.gz
!# Remove unsupervised examples
!rm -r aclImdb/train/unsup
BATCH_SIZE = 16
imdb_train = keras.utils.text_dataset_from_directory("aclImdb/train",batch_size=BATCH_SIZE,
)
imdb_test = keras.utils.text_dataset_from_directory("aclImdb/test",batch_size=BATCH_SIZE,
)# Inspect first review
# Format is (review text tensor, label tensor)
print(imdb_train.unbatch().take(1).get_single_element())

3、使用预训练分类器进行推理

在KerasNLP中,最高层次的模块是任务(Task)。一个任务是一个keras.Model,它由(通常是预训练的)主干模型(backbone model)和特定于任务的层组成。下面是一个使用keras_nlp.models.BertClassifier的示例。

注意:输出是每个类别的对数几率(logits,即未归一化的概率)(例如,[0, 0] 表示正类有50%的可能性)。在二元分类中,输出是[负类, 正类]。

classifier = keras_nlp.models.BertClassifier.from_preset("bert_tiny_en_uncased_sst2")
# Note: batched inputs expected so must wrap string in iterable
classifier.predict(["I love modular workflows in keras-nlp!"])

所有任务都有一个from_preset方法,该方法使用预设的预处理、架构和权重来构造一个keras.Model实例。这意味着我们可以传递任何被keras.Model接受的原始字符串格式,并获得特定于我们任务的输出。

这个特定的预设是一个在sst2(另一个电影评论情感分析任务,这次来自Rotten Tomatoes)上微调过的"bert_tiny_uncased_en"主干模型。我们为了演示目的使用了小型架构,但为了达到最佳性能,建议使用更大的模型。对于BertClassifier可用的所有特定于任务的预设,请查看我们的keras.io模型页面。

现在让我们在IMDB数据集上评估我们的分类器。你会注意到我们不需要在这里调用keras.Model.compile。所有像BertClassifier这样的任务模型都带有编译的默认设置,这意味着我们可以直接调用keras.Model.evaluate。当然,你总是可以像平常一样调用compile来覆盖这些默认设置(例如,添加新的指标)。

下面的输出是[损失, 准确率]。

classifier.evaluate(imdb_test)

4、微调预训练的BERT主干模型

当我们的任务有特定的标记文本可用时,微调一个自定义的分类器可以提高性能。如果我们想要预测IMDB评论的情感倾向,使用IMDB数据应该比使用Rotten Tomatoes数据表现得更好!而且,对于许多任务来说,可能没有相关的预训练模型可用(例如,分类客户评论)。

微调的工作流程几乎与上述相同,除了我们请求仅针对主干模型的预设,而不是整个分类器的预设。当传入一个主干预设时,任务模型会随机初始化所有特定于任务的层,以准备进行训练。对于BertClassifier可用的所有主干预设,请查看我们的keras.io模型页面。

要训练你的分类器,就像使用任何其他keras.Model一样,使用keras.Model.fit。就像我们在推理示例中一样,我们可以依赖任务的编译默认值,并跳过keras.Model.compile。由于包含了预处理步骤,我们再次直接传入原始数据。

classifier = keras_nlp.models.BertClassifier.from_preset("bert_tiny_en_uncased",num_classes=2,
)
classifier.fit(imdb_train,validation_data=imdb_test,epochs=1,
)

在这里,即使IMDB数据集比sst2小得多,但仅通过一个训练周期,我们就看到了验证准确率的大幅提升(从0.78提高到0.87)。

5、用户控制预处理的微调

用户控制预处理的微调(Fine tuning with user-controlled preprocessing)是指在微调预训练模型时,用户能够根据自己的需求和数据特性来控制数据预处理步骤。这通常包括文本清洗、分词、标记化(tokenization)、填充(padding)、截断(truncation)等步骤,以确保输入数据符合模型的要求,并优化模型在新任务上的性能。

通过用户控制预处理,可以确保预处理步骤与任务的特定需求相匹配,避免不必要的信息丢失或引入噪声,从而提高模型在特定任务上的准确性和泛化能力。此外,用户还可以根据数据的特点和模型的性能进行迭代和优化,以找到最佳的预处理策略。

对于某些高级训练场景,用户可能更希望直接控制预处理步骤。对于大型数据集,可以在训练前对数据进行预处理并将其保存到磁盘,或者使用tf.data.experimental.service的单独工作池进行预处理。在其他情况下,需要自定义预处理来处理输入。

通过在任务模型的构造函数中传递preprocessor=None,可以跳过自动预处理,或者传递一个自定义的BertPreprocessor

从相同预设中分离预处理
每个模型架构都有一个与之平行的预处理器层(Layer),该层有自己的from_preset构造函数。为这个层使用相同的预设将返回与任务相匹配的预处理器。

在这个工作流程中,我们使用tf.data.Dataset.cache()在三个训练周期中训练模型,这会在拟合开始前计算一次预处理并将结果缓存。

注意:即使在运行Jax或PyTorch后端时,我们也可以使用tf.data进行预处理。在训练过程中,输入数据集会自动转换为后端原生张量类型。事实上,鉴于tf.data在运行预处理方面的效率,在所有后端上这都是一个良好的做法。

import tensorflow as tfpreprocessor = keras_nlp.models.BertPreprocessor.from_preset("bert_tiny_en_uncased",sequence_length=512,
)# Apply the preprocessor to every sample of train and test data using `map()`.
# [`tf.data.AUTOTUNE`](https://www.tensorflow.org/api_docs/python/tf/data/AUTOTUNE) and `prefetch()` are options to tune performance, see
# https://www.tensorflow.org/guide/data_performance for details.# Note: only call `cache()` if you training data fits in CPU memory!
imdb_train_cached = (imdb_train.map(preprocessor, tf.data.AUTOTUNE).cache().prefetch(tf.data.AUTOTUNE)
)
imdb_test_cached = (imdb_test.map(preprocessor, tf.data.AUTOTUNE).cache().prefetch(tf.data.AUTOTUNE)
)classifier = keras_nlp.models.BertClassifier.from_preset("bert_tiny_en_uncased", preprocessor=None, num_classes=2
)
classifier.fit(imdb_train_cached,validation_data=imdb_test_cached,epochs=3,

经过三个训练周期后,我们的验证准确率仅提高到0.88。这既是因为我们的数据集较小,也是因为我们的模型。为了超过90%的准确率,可以尝试使用更大的预设,如"bert_base_en_uncased"。对于BertClassifier可用的所有主干预设,请查看我们的keras.io模型页面。

自定义预处理
在需要自定义预处理的情况下,我们提供了直接访问Tokenizer类的功能,该类将原始字符串映射为标记(tokens)。Tokenizer类还提供了一个from_preset()构造函数,用于获取与预训练相匹配的词汇表。

注意BertTokenizer默认情况下不会填充序列,因此输出是参差不齐的(每个序列的长度不同)。下面的MultiSegmentPacker用于将这些参差不齐的序列填充为密集的张量类型(例如tf.Tensortorch.Tensor)。

tokenizer = keras_nlp.models.BertTokenizer.from_preset("bert_tiny_en_uncased")
tokenizer(["I love modular workflows!", "Libraries over frameworks!"])# Write your own packer or use one of our `Layers`
packer = keras_nlp.layers.MultiSegmentPacker(start_value=tokenizer.cls_token_id,end_value=tokenizer.sep_token_id,# Note: This cannot be longer than the preset's `sequence_length`, and there# is no check for a custom preprocessor!sequence_length=64,
)# This function that takes a text sample `x` and its
# corresponding label `y` as input and converts the
# text into a format suitable for input into a BERT model.
def preprocessor(x, y):token_ids, segment_ids = packer(tokenizer(x))x = {"token_ids": token_ids,"segment_ids": segment_ids,"padding_mask": token_ids != 0,}return x, yimdb_train_preprocessed = imdb_train.map(preprocessor, tf.data.AUTOTUNE).prefetch(tf.data.AUTOTUNE
)
imdb_test_preprocessed = imdb_test.map(preprocessor, tf.data.AUTOTUNE).prefetch(tf.data.AUTOTUNE
)# Preprocessed example
print(imdb_train_preprocessed.unbatch().take(1).get_single_element())

6、使用自定义模型进行微调

使用自定义模型进行微调(Fine tuning with a custom model)是指在深度学习或机器学习任务中,使用用户自定义的模型架构进行微调操作。微调通常是在一个预训练模型(如BERT、GPT等)的基础上进行,但也可以应用于任何自定义构建的模型。

微调意味着在已存在的模型权重基础上,针对特定的任务或数据集进行训练,以调整模型的参数,从而提高模型在目标任务上的性能。当使用自定义模型进行微调时,用户可以根据自己的需求和数据特性设计模型架构,并在预训练的基础上进一步训练模型,以适应特定的任务需求。

这种方法的优点在于可以利用预训练模型中的知识和特征,同时又能根据具体任务进行灵活调整,以实现更好的性能。然而,这也要求用户具有一定的深度学习知识和经验,以设计有效的模型架构和微调策略。

对于更高级的应用,可能没有一个合适的任务模型可用。在这种情况下,我们提供了直接访问基础模型(backbone Model)的接口,基础模型有自己的from_preset构造函数,并且可以与自定义层(Layers)组合使用。详细的示例可以在我们的迁移学习指南中找到。

基础模型不包括自动预处理,但可以与匹配的预处理器配对使用,如之前工作流程中所示,使用相同的预设。

在这个工作流程中,我们尝试冻结基础模型,并添加两个可训练的Transformer层以适应新的输入。

注意:我们可以忽略关于pooled_dense层的梯度警告,因为我们使用的是BERT的序列输出。这意味着我们可能并不直接对BERT模型中的pooled_dense层(通常是用于分类任务的池化层)进行训练,而是将输出传递给其他层进行进一步处理。在这种情况下,不需要计算该层的梯度。

preprocessor = keras_nlp.models.BertPreprocessor.from_preset("bert_tiny_en_uncased")
backbone = keras_nlp.models.BertBackbone.from_preset("bert_tiny_en_uncased")imdb_train_preprocessed = (imdb_train.map(preprocessor, tf.data.AUTOTUNE).cache().prefetch(tf.data.AUTOTUNE)
)
imdb_test_preprocessed = (imdb_test.map(preprocessor, tf.data.AUTOTUNE).cache().prefetch(tf.data.AUTOTUNE)
)backbone.trainable = False
inputs = backbone.input
sequence = backbone(inputs)["sequence_output"]
for _ in range(2):sequence = keras_nlp.layers.TransformerEncoder(num_heads=2,intermediate_dim=512,dropout=0.1,)(sequence)
# Use [CLS] token output to classify
outputs = keras.layers.Dense(2)(sequence[:, backbone.cls_token_index, :])model = keras.Model(inputs, outputs)
model.compile(loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),optimizer=keras.optimizers.AdamW(5e-5),metrics=[keras.metrics.SparseCategoricalAccuracy()],jit_compile=True,
)
model.summary()
model.fit(imdb_train_preprocessed,validation_data=imdb_test_preprocessed,epochs=3,
)

尽管这个模型只有我们BertClassifier模型可训练参数的10%,但它仍然达到了合理的准确率。每个训练步骤所花费的时间大约只有BertClassifier模型的1/3,即使考虑到缓存预处理的时间。

7、预训练基础模型(Pretraining a backbone model)

在深度学习和机器学习的上下文中,预训练基础模型通常指的是在一个大规模数据集上预先训练一个模型的部分或全部,以便在后续的特定任务或数据集上进行微调(fine-tuning)。基础模型通常指的是一个模型的主要组成部分,如卷积神经网络(CNN)中的特征提取层或Transformer模型中的编码器部分。

预训练基础模型的主要目的是利用在大规模数据集上学到的通用特征,这些特征可以捕获数据中的底层结构和模式。通过在后续的特定任务上进行微调,模型可以学习到针对该任务的特定特征,从而在不需要大量标注数据的情况下实现良好的性能。

预训练基础模型在迁移学习(transfer learning)和领域适应(domain adaptation)等场景中特别有用,因为它们可以帮助模型更快地适应新的任务和数据集,同时减少过拟合的风险。

您是否拥有与训练流行的基础模型(如BERT、RoBERTa或GPT2)所用数据集大小相近的、您所在领域的大规模无标签数据集?如果有,那么您可能会从针对自己基础模型的特定领域预训练中受益。

NLP模型通常会在语言建模任务上进行预训练,根据输入句子中的可见单词来预测被掩盖的单词。例如,给定输入“The fox [MASK] over the [MASK] dog”,模型可能会被要求预测出[“jumped”, “lazy”]。然后,该模型的较低层会被打包为基础模型,与新任务的层进行组合。

KerasNLP库提供了无需预设即可从头开始训练的SoTA基础模型和分词器(tokenizers)。

在这个工作流程中,我们使用IMDB评论文本预训练了一个BERT基础模型。我们跳过了“下一句预测”(NSP)损失,因为它给数据处理增加了显著的复杂性,并且像RoBERTa这样的后续模型已经弃用了它。有关如何复制原始论文的详细步骤,请参阅我们的端到端Transformer预训练。

具体来说,BERT(Bidirectional Encoder Representations from Transformers)是一个基于Transformer的预训练语言表示模型,它包含两个主要的预训练任务:Masked Language Modeling(MLM)和Next Sentence Prediction(NSP)。其中,MLM是通过在输入语句中随机选择一些单词并将它们替换成掩码(如[MASK]),然后让模型预测这些掩码的正确词语来训练模型对上下文的理解能力。而NSP则是通过随机选择两个句子A和B,并将它们组合成一个输入序列,然后让模型判断B是否是A的下一句来训练模型对句子间关系的理解能力。然而,后续的研究(RoBERTa)发现,NSP任务对于模型性能的提升并不明显,因此在预训练过程中可以省略。

在预训练BERT或类似模型时,通常需要使用大量的无标签语料库,这些语料库可以包含数十亿甚至更多的单词。预训练完成后,模型可以在特定的NLP任务上进行微调,以适应不同的应用场景。

关于KerasNLP库,它提供了许多用于自然语言处理的先进模型和工具,包括用于构建和训练模型的API、用于处理文本数据的分词器和嵌入层等。这些工具可以帮助研究人员和开发人员更轻松地构建和训练NLP模型。

# All BERT `en` models have the same vocabulary, so reuse preprocessor from
# "bert_tiny_en_uncased"
preprocessor = keras_nlp.models.BertPreprocessor.from_preset("bert_tiny_en_uncased",sequence_length=256,
)
packer = preprocessor.packer
tokenizer = preprocessor.tokenizer# keras.Layer to replace some input tokens with the "[MASK]" token
masker = keras_nlp.layers.MaskedLMMaskGenerator(vocabulary_size=tokenizer.vocabulary_size(),mask_selection_rate=0.25,mask_selection_length=64,mask_token_id=tokenizer.token_to_id("[MASK]"),unselectable_token_ids=[tokenizer.token_to_id(x) for x in ["[CLS]", "[PAD]", "[SEP]"]],
)def preprocess(inputs, label):inputs = preprocessor(inputs)masked_inputs = masker(inputs["token_ids"])# Split the masking layer outputs into a (features, labels, and weights)# tuple that we can use with keras.Model.fit().features = {"token_ids": masked_inputs["token_ids"],"segment_ids": inputs["segment_ids"],"padding_mask": inputs["padding_mask"],"mask_positions": masked_inputs["mask_positions"],}labels = masked_inputs["mask_ids"]weights = masked_inputs["mask_weights"]return features, labels, weightspretrain_ds = imdb_train.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE).prefetch(tf.data.AUTOTUNE
)
pretrain_val_ds = imdb_test.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)# Tokens with ID 103 are "masked"
print(pretrain_ds.unbatch().take(1).get_single_element())

预训练模型

# BERT backbone
backbone = keras_nlp.models.BertBackbone(vocabulary_size=tokenizer.vocabulary_size(),num_layers=2,num_heads=2,hidden_dim=128,intermediate_dim=512,
)# Language modeling head
mlm_head = keras_nlp.layers.MaskedLMHead(token_embedding=backbone.token_embedding,
)inputs = {"token_ids": keras.Input(shape=(None,), dtype=tf.int32, name="token_ids"),"segment_ids": keras.Input(shape=(None,), dtype=tf.int32, name="segment_ids"),"padding_mask": keras.Input(shape=(None,), dtype=tf.int32, name="padding_mask"),"mask_positions": keras.Input(shape=(None,), dtype=tf.int32, name="mask_positions"),
}# Encoded token sequence
sequence = backbone(inputs)["sequence_output"]# Predict an output word for each masked input token.
# We use the input token embedding to project from our encoded vectors to
# vocabulary logits, which has been shown to improve training efficiency.
outputs = mlm_head(sequence, mask_positions=inputs["mask_positions"])# Define and compile our pretraining model.
pretraining_model = keras.Model(inputs, outputs)
pretraining_model.summary()
pretraining_model.compile(loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),optimizer=keras.optimizers.AdamW(learning_rate=5e-4),weighted_metrics=[keras.metrics.SparseCategoricalAccuracy()],jit_compile=True,
)# Pretrain on IMDB dataset
pretraining_model.fit(pretrain_ds,validation_data=pretrain_val_ds,epochs=3,  # Increase to 6 for higher accuracy
)

8、从零开始构建和训练自己的Transformer模型

从IMDB数据构建和训练你自己的Transformer

想要实现一个新颖的Transformer架构吗?KerasNLP库提供了用于构建我们模型API中SoTA(State-of-the-Art)架构的所有底层模块。这包括keras_nlp.tokenizers API,它允许你使用WordPieceTokenizer、BytePairTokenizer或SentencePieceTokenizer来训练你自己的子词分词器。

在这个工作流程中,我们将在IMDB数据上训练一个自定义的分词器,并设计一个具有自定义Transformer架构的基础模型。为了简化,我们将直接在分类任务上进行训练。对更多细节感兴趣吗?我们在keras.io上撰写了关于预训练和微调自定义Transformer的完整指南。

从IMDB数据训练自定义词汇

这意味着你将从IMDB的电影评论数据集中提取文本,并使用上述提到的分词器之一(如WordPieceTokenizer)来训练一个自定义的词汇表。这个词汇表将用于将原始文本转换为模型可以理解的数字序列,这是处理自然语言数据的重要步骤。一旦你有了自定义的分词器和词汇表,你就可以开始构建你的Transformer模型了。

vocab = keras_nlp.tokenizers.compute_word_piece_vocabulary(imdb_train.map(lambda x, y: x),vocabulary_size=20_000,lowercase=True,strip_accents=True,reserved_tokens=["[PAD]", "[START]", "[END]", "[MASK]", "[UNK]"],
)
tokenizer = keras_nlp.tokenizers.WordPieceTokenizer(vocabulary=vocab,lowercase=True,strip_accents=True,oov_token="[UNK]",
)

使用自定义分词器预处理数据

这个步骤涉及使用你之前训练或定义的自定义分词器来将原始文本数据转换为模型可以理解的格式。分词器会将文本拆分为较小的单元(如单词、子词或字符),并为每个单元分配一个唯一的标识符(如ID或索引)。这样,模型就可以接收这些标识符序列作为输入,并输出对应的预测或结果。

在预处理阶段,除了分词之外,还可能包括其他步骤,如文本清洗(去除HTML标签、特殊字符、停用词等)、大小写转换、文本截断或填充等,以确保数据格式符合模型的要求。

使用自定义分词器进行预处理可以提高模型在特定任务上的性能,因为分词器可以根据你的数据和任务进行定制和优化。

packer = keras_nlp.layers.StartEndPacker(start_value=tokenizer.token_to_id("[START]"),end_value=tokenizer.token_to_id("[END]"),pad_value=tokenizer.token_to_id("[PAD]"),sequence_length=512,
)def preprocess(x, y):token_ids = packer(tokenizer(x))return token_ids, yimdb_preproc_train_ds = imdb_train.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)
imdb_preproc_val_ds = imdb_test.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE
).prefetch(tf.data.AUTOTUNE)print(imdb_preproc_train_ds.unbatch().take(1).get_single_element())

设计一个微型Transformer

在设计一个微型Transformer时,我们旨在创建一个结构简洁但功能强大的模型,以便在资源受限的环境中(如移动设备或边缘设备)进行有效部署。以下是设计微型Transformer的一些关键考虑因素:

  • 模型深度与宽度:微型Transformer通常具有较浅的层数和较窄的隐藏层维度,以减少参数量和计算复杂度。可以通过调整编码器和解码器堆叠的层数、隐藏层的大小以及自注意力机制中的头数来平衡模型的表达能力和计算资源需求。
  • 自注意力机制:自注意力机制是Transformer模型的核心组件之一,它允许模型捕获输入序列中的依赖关系。在微型Transformer中,可以考虑使用简化的自注意力机制,如局部自注意力(local self-attention)或基于相对位置的自注意力(relative position-based self-attention),以减少计算量和内存占用。
  • 位置编码:由于Transformer模型是基于自注意力的,它无法直接捕获输入序列中的位置信息。因此,需要通过位置编码(positional encoding)将位置信息注入到模型中。在微型Transformer中,可以使用简化的位置编码方法,如绝对位置编码或正弦/余弦位置编码的简化版本。
  • 前馈网络:Transformer模型中的前馈网络(feed-forward network)用于增强模型的非线性表示能力。在微型Transformer中,可以通过减少前馈网络的层数、隐藏层维度和激活函数的选择来简化其结构。
  • 轻量级优化:为了进一步提高微型Transformer的效率和性能,可以采用一些轻量级优化技术,如剪枝(pruning)、量化(quantization)和蒸馏(distillation)。这些技术可以帮助减少模型的参数量和计算复杂度,同时保持较好的性能。

通过综合考虑以上因素,可以设计出一个既具有强大表达能力又能在资源受限环境中高效运行的微型Transformer模型。这样的模型可以广泛应用于各种自然语言处理任务,如文本分类、机器翻译和问答系统等。

token_id_input = keras.Input(shape=(None,),dtype="int32",name="token_ids",
)
outputs = keras_nlp.layers.TokenAndPositionEmbedding(vocabulary_size=len(vocab),sequence_length=packer.sequence_length,embedding_dim=64,
)(token_id_input)
outputs = keras_nlp.layers.TransformerEncoder(num_heads=2,intermediate_dim=128,dropout=0.1,
)(outputs)
# Use "[START]" token to classify
outputs = keras.layers.Dense(2)(outputs[:, 0, :])
model = keras.Model(inputs=token_id_input,outputs=outputs,
)model.summary()

直接在分类目标上训练Transformer

model.compile(loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),optimizer=keras.optimizers.AdamW(5e-5),metrics=[keras.metrics.SparseCategoricalAccuracy()],jit_compile=True,
)
model.fit(imdb_preproc_train_ds,validation_data=imdb_preproc_val_ds,epochs=3,
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/15462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

风控指南:国内车险欺诈呈现四大趋势

目录 车险欺诈呈现内外勾结的团伙化 防范车险欺诈需要多重合作 保险企业需要提升反欺诈能力 监管部门需要加强协同合作 2024年4月11日,国家金融监督管理总局官网发布国家金融监督管理总局关于《反保险欺诈工作办法(征求意见稿)》公开征求意见…

PCL平面多边形可视化

1、背景介绍 多边形是一个在二维平面上由直线段(称为边或侧)首尾顺次连接围成的封闭图形。这些直线段也称为多边形的边,而它们的交点称为多边形的顶点或角。在点云边缘点提取后,有时候需要将其进行可视化,如下图所示。…

【Mac】跑猫RunCat for mac(菜单栏Cpu可视化监测工具) v10.3免费版安装教程

软件介绍 RunCat是一款为菜单栏提供关键帧动画的软件。动画速度会根据Mac的CPU使用情况而变化。奔跑的小猫通过运行速度告诉您Mac的CPU使用率。 这是一款好玩的软件,可以为您的Mac使用添加一点小确幸。感兴趣的朋友可以试试哦。 安装步骤 1.打开安装包&#xff0…

贵州大学24计算机考研数据速览,国家重点实验室22408复试线285分!贵州大学计算机考研考情分析!

贵州大学计算机科学与技术学院坐落在贵州大学北校区(贵阳花溪)。 学院现有教职工139人,其中专职教师126人,教授17人,副教授37人,讲师46人,高级实验师4人,实验师17人。具有博士学位的…

Django 入门教程

1. Django简介 基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 MVC 与 MVT 模型 MVC 模型 MVC 模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型&am…

图论(三)(最小生成树)

一、图的表示(简要概述) 对于图G(V,E)( V 为节点的集合,E 为边的集合 V*V 的子集)有两种表示方法:邻接链表和邻接矩阵,两种表示方法既可以表示有向图&#x…

【C++STL详解(四)------vector的模拟实现】

文章目录 vector各函数接口总览vector当中的成员变量介绍默认成员函数构造函数1构造函数2构造函数3拷贝构造函数赋值运算符重载函数析构函数 迭代器相关函数begin和end 容量和大小相关函数size和capacityreserveresizeempty 修改容器内容相关函数push_backpop_backinserterases…

基于open3d加载kitti数据集bin文件

前言 在自动驾驶领域,Kitti数据集是一个非常流行的点云数据集,广泛用于3D目标检测、跟踪和其他相关研究。Open3D是一个强大的开源库,专门用于处理和可视化三维数据。本文将介绍如何使用Open3D来加载和可视化Kitti数据集中的.bin文件。 准备…

工业路由器在工厂数字化的应用及价值

随着科技的飞速发展,数字化转型已成为工厂提高效率、降低成本、实现智能化管理的关键途径。在这个过程中,工业路由器凭借其独特的优势,正逐渐成为工厂数字化建设不可或缺的核心组件。本文将深入探讨工业路由器在工厂数字化中的应用及价值&…

linux与windows脚本格式必须转换,linux只有LF

如果windows下的脚本在linux下直接执行,则会造成无穷的错误。 在文本处理中, CR, LF, CR/LF是不同操作系统上使用的换行符. Dos和windows: 采用回车换行CR/LF表示下一行. UNIX/Linux : 采用换行符LF表示下一行. MAC OS : 采用回车…

《计算机网络微课堂》2-3 传输方式

本节课我们介绍几种传输方式: 串行传输和并行传输同步传输和异步传输单工,半双工‍‍以及全双工通信 ​​ ‍ 串行 我们首先来看串行传输和并行传输,串行传输是指‍‍数据是一个比特依次发送的,因此在发送端和接收端之间‍‍只…

Linux--09---RPM 、YUM

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 RPM1 什么是RPM2 RPM包的名称格式3.RPM查询命令4.RPM卸载命令5.RPM安装命令 YUM1 什么是YUMYUM优势1.自动下载RPM包并且安装2.自动处理依赖性关系,并且一…

【论文阅读】AID(ICCV‘23)

paper:https://arxiv.org/abs/2310.05666 code:https://github.com/YilongLv/AID Anchor-Intermediate Detector: Decoupling and Coupling Bounding Boxes for Accurate Object Detection

第十一届蓝桥杯物联网试题(国赛)

国赛题目看着简单其实还是挺复杂的,所以说不能掉以轻心,目前遇到的问日主要有以下几点: 本次题主要注重的是信息交互,与A板通信的有电脑主机和B板,所以处理好这里面的交互过程很重要 国赛中避免不了会收到其他选手的…

题解:P9535 [YsOI2023] 连通图计数

题意 求:在所有 n n n 个点 m m m 条边的无向简单连通图中,满足把第 i i i 个点删去后图被分为 a i a_i ai​​ 个连通块。 n − 1 ≤ m ≤ n 1 n-1\le m\le n1 n−1≤m≤n1。 思路 将 m n − 1 , m n , m n 1 mn-1,mn,mn1 mn−1,mn,mn1​ 三…

从git上拉取项目进行操作

1.Git的概念 Git是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。它实现多人协作的机制是利用clone命令将项目从远程库拉取到本地库,做完相应的操作后再利用push命令从本地库将项目提交至远程库。 2.Git的工作流程…

iMX6ULL 嵌入式linux开发 | 4G无线广播终端实现方案介绍

现有的有线广播,如村上的大喇叭,需要布线,施工麻烦。借助现有的4G网络,传输音频流完全没问题,4G网络结合流媒体技术和MQTT消息传递实现设备间的同步推拉流。这种方案可以避免有线布线的麻烦,同时实现4G无线…

Mysql插入中文内容报错解决及其Mysql常用的存储引擎说明

一、问题描述 我们在Mysql数据库的表中插入带有中文内容时报错,提示【1366 - Incorrect string value: \xE5\x8C\x97\xE4\xBA\xAC... for column UserDealer at row 1】,如下图所示: 二、问题分析 一般来说插入中文内容有问题我们首先想到的就是编码问题;我们可以查看该表使…

【Python】 如何在Python中导入其他Python文件?

基本原理 在Python编程中,我们经常需要将代码组织成模块,以便于重用和维护。模块是包含Python定义和语句的文件。导入模块可以让你访问其他文件中定义的函数、类和变量等。Python提供了几种不同的方法来导入模块。 代码示例 示例1:导入整个…

超值分享50个DFM模型格式的素人直播资源,适用于DeepFaceLive的DFM合集

50直播模型:点击下载 作为直播达人,我在网上购买了大量直播用的模型资源,包含男模女模、明星脸、大众脸、网红脸及各种稀缺的路人素人模型。现在,我将这些宝贵的资源整理成合集分享给大家,需要的朋友们可以直接点击下…