生成式人工智能(Generative AI)是机器学习的一个分支,专注于创建新的数据,如图像、文本和音频。这些模型是在现有数据集上进行训练的,然后利用所学知识生成与训练数据相似的新的独特数据。
最流行的生成式人工智能类型之一是生成对抗网络(Generative Adversarial Network,GAN)。GAN包括两个神经网络,一个生成器(generator)和一个判别器(discriminator),它们共同协作生成新的数据。生成器创建新的数据,而判别器试图区分生成的数据和真实数据。随着生成器改进其创建逼真数据的能力,判别器变得更擅长识别假数据,从而在生成器和判别器之间形成一个反馈循环,使得两个网络随着时间的推移不断改进。
另一种流行的生成式人工智能类型是变分自编码器(Variational Autoencoders,VAEs)。VAEs由一个编码器网络和一个解码器网络组成。编码器将输入数据压缩成低维表示,称为潜在编码(latent code),而解码器从潜在编码生成新的数据。VAEs对于图像和文本生成等任务非常有用,因为它们可以生成与训练数据相似的新数据,同时又具有一定程度的随机性或变化。
生成式人工智能模型具有许多潜在应用,例如为视频游戏和电影创建逼真的图像和视频,为聊天机器人和语言翻译生成新的文本,以及创作新的音乐和音效。此外,生成式人工智能模型还可用于异常检测和缺失数据插补等任务。
Transformer
最流行的生成式人工智能模型之一是Transformer模型。这个模型在2017年的论文《Attention Is All You Need》中提出,它是一种使用注意力机制处理输入数据的神经网络架构。Transformer模型已被广泛应用于许多自然语言处理任务,如语言翻译和文本生成。
Transformer模型的一个关键优势是其处理顺序数据(如文本)的能力。与传统的神经网络通过固定长度的窗口处理输入数据不同,Transformer模型能够处理任意长度的输入数据。这使得它非常适用于语言翻译等任务,其中输入和输出的长度可能不同。
Transformer模型的另一个优势是其使用注意力机制。注意力使得模型能够专注于输入数据的特定部分,而不是平等地处理所有数据。这提高了模型理解输入数据和生成更准确输出的能力。
近年来,Transformer模型还被应用于计算机视觉任务,如图像生成,以及音频任务,如语音合成。Transformer架构在这些任务中被证明非常有效,很可能我们将在未来看到更多这些模型的应用。
变压器的种类
有三种不同的高级Transformer架构,分别是编码器-解码器(encoder-decoder)、编码器(encoder)和解码器(decoder)。
编码器-解码器架构是一种常用于机器学习任务的神经网络结构,例如语言翻译、图像字幕和文本摘要。这些架构由两个主要组件组成:编码器和解码器。
编码器负责处理输入数据,并将其压缩成一个紧凑的、低维表示,称为潜在编码(latent code)。这个编码包含了输入数据中最重要的信息,并被解码器用于生成输出数据。编码器通常是一个使用循环或卷积层处理输入数据的神经网络。
解码器负责接收潜在编码并生成输出数据。它通常是一个使用循环或转置卷积层处理编码并生成输出数据的神经网络。解码器被训练用于重构输入数据或生成与输入数据相似的新数据。
解码器Transformer包含因果掩码,用于生成文本。一个著名的解码器模型是由OpenAI开发的GPT-3模型,它被训练用于预测文本中的下一个单词。
编码器Transformer就是没有因果掩码的解码器Transformer。它们不用于文本生成,因此允许令牌之间相互关注以捕捉所有交叉依赖关系,无论顺序如何。相反,它们用于需要全局理解输入的任务,例如句子分类、命名实体识别和抽取式问答等。
使用TensorFlow和Keras从头开始开发Transformer模型
在这个部分,我们将构建Transformer架构来生成文本并实现期望的结果。
我们将利用TensorFlow中提供的IMDB电影评论数据集进行文本分类。
导入库
我们将使用 Transformers 导入文本分类项目所需的所有基本库。
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import MultiHeadAttention, LayerNormalization, Dropout, Layer
from tensorflow.keras.layers import Embedding, Input, GlobalAveragePooling1D, Dense
from tensorflow.keras.datasets import imdb
from tensorflow.keras.models import Sequential, Model
import numpy as np
import warnings
warnings.filterwarnings("ignore", category=np.VisibleDeprecationWarning)
创建Transformer块和位置编码
Transformer块将按照文章前面部分详细介绍的块的方式构建。虽然我将使用TensorFlow/Keras深度学习框架中的多头注意力层,但您可以调整代码并创建自己独特的多头层,以提供对多个因素的更多控制和访问。
在Transformer块的第一个函数中初始化前馈网络、批量归一化和丢弃层以及注意力层。根据给定的架构概述,在Transformer块的调用函数中定义这些层。
class TransformerBlock(Layer):
def __init__(self, embed_dim, num_heads, ff_dim, rate=0.1):
super(TransformerBlock, self).__init__()
self.att = MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
self.ffn = Sequential(
[Dense(ff_dim, activation="relu"),
Dense(embed_dim),]
)
self.layernorm1 = LayerNormalization(epsilon=1e-6)
self.layernorm2 = LayerNormalization(epsilon=1e-6)
self.dropout1 = Dropout(rate)
self.dropout2 = Dropout(rate)
def call(self, inputs, training):
attn_output = self.att(inputs, inputs)
attn_output = self.dropout1(attn_output, training=training)
out1 = self.layernorm1(inputs + attn_output)
ffn_output = self.ffn(out1)
ffn_output = self.dropout2(ffn_output, training=training)
return self.layernorm2(out1 + ffn_output)
以下代码块中定义了另一个函数,用于管理研究文章中提供的位置嵌入。对于令牌和令牌索引位置,我们正在构建两个嵌入层。使用下面的代码块可以创建一个具有两个函数的类。令牌和位置嵌入在第一个函数中初始化,并在第二个函数中调用和适当编码。完成这个阶段后,我们可以继续准备数据集并创建文本分类的Transformer模型。
class TokenAndPositionEmbedding(Layer):
def __init__(self, maxlen, vocab_size, embed_dim):
super(TokenAndPositionEmbedding, self).__init__()
self.token_emb = Embedding(input_dim=vocab_size, output_dim=embed_dim)
self.pos_emb = Embedding(input_dim=maxlen, output_dim=embed_dim)
def call(self, x):
maxlen = tf.shape(x)[-1]
positions = tf.range(start=0, limit=maxlen, delta=1)
positions = self.pos_emb(positions)
x = self.token_emb(x)
return x + positions
我们将使用TensorFlow和Keras提供的IMDB数据集来达到这个特定目的。数据集由50,000条评论组成,我们将将其分为25,000个训练序列和25,000个测试序列。此外,产品上有相同数量的评论,被平均分为50%的好评和50%的负面评价。在预处理阶段,我们的目标是将每个单词转换为一组数字,以便我们可以使用它们来构建Transformer的架构,并根据需要验证结果。
vocab_size = 20000 # Only consider the top 20k words20000 # Only consider the top 20k words
maxlen = 200 # Only consider the first 200 words of each movie review
(x_train, y_train), (x_val, y_val) = imdb.load_data(num_words=vocab_size)
print(len(x_train), "Training sequences")
print(len(x_val), "Validation sequences")
在以下的代码片段中,我们将查看给出的前五个测试序列的标签。这些标签给我们提供了对我们所检查的数据有什么期望的一般概念。我们将在本节的后面部分对前五个数据片段进行预测,以了解我们的模型在这些数据集上的工作效果如何。
y_val[:5]5]
输出:
array([0, 1, 1, 0, 1], dtype=int64)0, 1, 1, 0, 1], dtype=int64)
在读取了前五个元素的标签之后,我们将为训练和验证数据填充序列,如下方的代码块所示。完成这个过程后,我们将开始创建我们的Transformer模型。
x_train = tf.keras.preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen)
x_val = tf.keras.preprocessing.sequence.pad_sequences(x_val, maxlen=maxlen)
模型的开发
文本分类的Transformer模型可以通过不同的编码器和解码器类以多种方式实现。通常,使用不同的编码器和解码器类来独立完成这些任务是被接受的做法。在本节中,我们将使用一种相当直接的方式来构建我们的模型,并适当地应用于文本分类的目标。我们将在Transformer中声明前馈网络层的大小、要使用的注意力头数量以及每个令牌的嵌入维度。然后,借助之前的Transformer块和位置嵌入类提供的工具,我们将开发模型。
我们同时使用Sequential和Functional API模型的事实值得注意,因为它使我们在模型设计上具有额外的自由度。我们将提供一个由句子的向量组成的输入,为其创建一个嵌入层,然后将其通过一个Transformer块。最后,为了返回句子可能结果的概率,我们使用了一个全局平均池化层、一个dropout层和一个全连接层。我们可以利用numpy的Argmax函数来获取正确的答案。下面是创建模型的代码块。
embed_dim = 32 # Embedding size for each token32 # Embedding size for each token
num_heads = 2 # Number of attention heads
ff_dim = 32 # Hidden layer size in feed forward network inside transformer
inputs = Input(shape=(maxlen,))
embedding_layer = TokenAndPositionEmbedding(maxlen, vocab_size, embed_dim)
x = embedding_layer(inputs)
transformer_block = TransformerBlock(embed_dim, num_heads, ff_dim)
x = transformer_block(x)
x = GlobalAveragePooling1D()(x)
x = Dropout(0.1)(x)
x = Dense(20, activation="relu")(x)
x = Dropout(0.1)(x)
outputs = Dense(2, activation="softmax")(x)
model = Model(inputs=inputs, outputs=outputs)
编译模型
我们将在以下步骤中继续组合我们创建的Transformer模型。我们将应用Adam优化器、稀疏分类交叉熵损失函数,并适当地指定计算准确度指标以进行编译过程。之后,我们将适配模型并对其进行几个epoch的训练。下面的代码片段展示了如何执行这些操作。
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
history = model.fit(x_train, y_train,
batch_size=64, epochs=2,
validation_data=(x_val, y_val)
)
在训练过程完成后,我们可以继续保存在拟合步骤中计算得到的权重。以下是实现此操作的步骤。
model.save_weights("predict_class.h5")"predict_class.h5")
模型评价
即使在拟合过程中我们对模型的训练效果有了初步的了解,仍然很重要对模型进行评估,并检查它在测试数据上的表现如何。因此,为了确定结果,我们将评估测试数据和其对应的标签。在测试数据上,模型将生成特定的预测来预测每个标签,然后将其与原始标签进行比较。最后,我们将得到代表模型准确性的最终数值。
results = model.evaluate(x_val, y_val, verbose=2)2)
for name, value in zip(model.metrics_names, results):
print("%s: %.3f" % (name, value))
前五个测试标签的值打印在本节之前的其中一个部分中。使用我们训练好的模型和predict函数,我们可以生成相应的预测结果。这是一个屏幕截图,展示了我训练好的模型允许我预测的结果。
从上方的屏幕截图中可以看出,该模型能够预测正确序列句子所表示的各个类别。由于我们能够在大多数预测中获得期望的结果,因此Transformer模型在文本分类任务中表现不错。尽管仍有改进的潜力,但观众可以尝试使用不同的Transformer设计配置来获得最佳结果。为了获得最佳效果,建议您尝试各种不同的选项进行实验。
结论
自然语言处理是与计算机视觉和图像处理一样,颇具前沿性和重要性的研究领域之一。在机器翻译、文本分类、语音转文本等各种任务中,深度学习和神经网络模型在解决与自然语言处理相关的问题上表现出更高的成功率。随着深度学习领域的不断发展,我们在处理这样的项目并取得有效进展以及可观结果方面的能力有所提升。
总之,生成式人工智能的Transformer模型是用于创建新数据的强大而多功能的工具,在娱乐、语言处理和计算机视觉等领域有许多潜在应用。随着生成式人工智能和Transformer模型领域的不断发展,我们可以预期将来这些模型将有更多创造性和实用性的应用。