AIGC之文本内容生成概述(下)——Transformer

在上一篇文章中,我们一口气介绍了LSTM、Word2Vec、GloVe、ELMo等四种模型的技术发展,以及每种模型的优缺点与应用场景,全文超过一万字,显得冗长且繁杂,在下文部分我们将分开介绍Transformer、BERT、GPT1/GPT2/GPT3/ChatGPT等模型的技术发展和相关应用场景等,本文将主要介绍Transformer模型。在整理AIGC系列的的文章内容时,根据成都深度智谷科技有限公司、深度人工智能教育机构的成老师提供的帮助,以及知识查询,完成了该系列目前的内容,后续内容还会继续寻求帮助持续更新。

Transformer(变压器模型)

Transformer模型是Vaswani等人于2017年发布的论文“Attention is All You Need”一文中提出的。Transformer是一种革命性的模型,它在自然语言处理(NLP)等任务上取得了巨大的成功,并在其他领域也得到了广泛应用。

Transformer模型的设计解决了传统循环神经网络(RNN)和卷积神经网络(CNN)在处理长序列数据时的一些限制。其中,最重要的特性是自注意力机制(Self-Attention)和多头注意力机制(Multi-Head Attention)。Transformer 模型通过自注意力机制(self-attention)来建立输入序列中不同位置之间的依赖关系,从而有效地捕捉序列中的长程依赖关系。

Transformer和以往的语言模型最大的区别就是在注意力和位置编码上的区别,并且消除了传统循环神经网络中的瓶颈,允许并行计算,从而加快了训练速度,并且能够更好地处理长序列数据。由于其出色的表现和高效的训练方式,Transformer成为了NLP任务中的主流模型,并对其他领域也产生了重要影响。

下面是对 Transformer 模型主要模块结构的概述:

1. 自注意力机制:

自注意力机制是一种基于注意力机制的技术,用于计算输入数据序列中每个位置与其他位置的相关性权重。这使得模型能够在无需固定窗口大小的情况下,动态地学习每个位置与其他位置的关联程度。

Transformer 模型中的自注意力机制(Self-Attention)是该模型的关键组成部分之一,用于捕捉输入序列中不同位置之间的相关性。自注意力机制通过计算查询(query)、键(key)和值(value)之间的相似度来动态地学习每个位置与其他位置的依赖关系。以下是自注意力机制的基本原理:

1.1. 查询、键和值:

- 对于给定的输入序列,自注意力机制使用线性变换将其映射为查询(Q)、键(K)和值(V)的表示。即输入数据中的每个序列根据计算自注意力的不同阶段,分别担任了查询向量(Q)、键向量(K)和值向量(V)

- 查询表示了需要关注的位置或内容,键表示序列中的所有位置,值表示每个位置的特征表示。

1.2. 相似度计算:

- 自注意力机制通过计算查询和键之间的相似度来确定每个查询与键的相关程度。常用的相似度计算方法是点积(Dot Product)或缩放的点积(Scaled Dot Product)。

- 相似度计算可以量化查询与键之间的关联性,从而为每个位置分配一个权重,用于加权求和值的表示。

1.3. 注意力权重:

- 相似度计算的结果经过 softmax 函数进行归一化,得到注意力权重。注意力权重表示了每个位置与其他位置的关联程度。

- 注意力权重决定了在值的表示中,每个位置对最终输出的贡献程度。

1.4. 加权求和:

- 将注意力权重与值进行加权求和,得到每个位置的加权表示。这样,模型可以根据查询的内容自动选择与之相关的键值对。

- 加权求和的结果即为自注意力机制的输出,它是基于整个输入序列的上下文感知的表示。

1.5. 多头注意力:

- 为了增加模型的表达能力和学习不同关注方面的能力,Transformer 模型采用了多头注意力机制。它通过将自注意力机制应用于多组不同的查询、键和值来进行并行计算。

- 每个注意力头都学习到了不同的查询关注点,从而提供了多个不同的注意力表示。最后,多头注意力的结果通过线性变换和拼接操作进行融合,得到最终的自注意力输出。

下面是基于深度学习框架Pytorch实现的多头自注意力的代码模块:

import torch
import torch.nn as nn


class MultiheadSelfAttention(nn.Module):
    def __init__(self, d_model, num_heads):
        super(MultiheadSelfAttention, self).__init__()


        self.d_model = d_model # 模型向量的维度
        self.num_heads = num_heads # 多头数量


        # 定义Q、K、V的线性变换
        self.W_q = nn.Linear(d_model, d_model)
        self.W_k = nn.Linear(d_model, d_model)
        self.W_v = nn.Linear(d_model, d_model)


        # 定义输出线性变换
        self.W_o = nn.Linear(d_model, d_model)


    def forward(self, x):
        # 获取输入的批次大小和序列长度
        batch_size, seq_len, d_model = x.size()


        # 通过线性变换得到Q、K、V
        q = self.W_q(x)
        k = self.W_k(x)
        v = self.W_v(x)


        #分成多头:将Q、K、V进行维度变换
        q = q.view(batch_size * self.num_heads, seq_len, d_model // self.num_heads)
        k = k.view(batch_size * self.num_heads, seq_len, d_model // self.num_heads)
        v = v.view(batch_size * self.num_heads, seq_len, d_model // self.num_heads)


        # 计算注意力得分
        scores = torch.bmm(q, k.transpose(1, 2))  # 批次矩阵乘法
        scores = scores / (d_model ** 0.5)  # 缩放注意力权重


        # 应用softmax激活函数获取注意力权重
        attention_weights = torch.softmax(scores, dim=-1)


        # 对V加权求和
        weighted_sum = torch.matmul(attention_weights, v)


        # 合并头:将多头注意力结果恢复原来的形状
        weighted_sum = weighted_sum.view(batch_size, seq_len, d_model)


        # 应用输出线性变换
        output = self.W_o(weighted_sum)


        return output


if __name__ == '__main__':


    # 测试代码
    batch_size = 16
    seq_len = 50
    d_model = 512
    num_heads = 8


    # 创建多头自注意力层
    self_attention = MultiheadSelfAttention(d_model, num_heads)


    # 创建输入张量
    x = torch.randn(batch_size, seq_len, d_model)


    # 使用多头自注意力层进行前向传播
    output = self_attention(x)
    print(output.size())  # 输出结果的形状

自注意力机制的优点在于:

- 能够动态地学习每个位置与其他位置的依赖关系,无需固定窗口大小。

- 能够捕捉序列中的长程依赖关系,适用于处理序列数据的任务。

- 具有并行计算的能力

2. 编码器-解码器结构(Seq2Seq):

Transformer 模型采用了编码器-解码器(Encoder-Decoder)结构,其中编码器用于将输入序列编码为上下文感知的表示,解码器用于生成目标序列,这种结构也称位序列到序列的结构-Seq2Seq(Sequence-to-Sequence)。

在基于Transformer的编解码结构出现之前,也有基于RNN和LSTM的Seq2Seq的编解码结构网络,它在编码部分和解码部分所使用的是RNN或LSTM模块,和基于Transformer的编解码结构相比,RNN和LSTM模块在参数量和注意力机制这一块是区别最大的,Transformer由于全连接的模块设计,加上对数据集全领域的注意力施加,使得其在参数量和效果上远远高于使用RNN和LSTM模块的Seq2Seq编解码结构。下面简要介绍一下Seq2Seq的结构。

Seq2Seq,全称为Sequence-to-Sequence,是一种用于序列到序列(Sequence-to-Sequence)学习的模型架构。它主要用于处理输入序列和输出序列之间的映射关系,广泛应用于机器翻译、文本摘要、对话系统等任务。

Seq2Seq模型由两个主要组件组成:编码器(Encoder)和解码器(Decoder)。

编码器(Encoder):编码器将输入序列(如源语言句子)编码为固定长度的向量,通常称为上下文向量(Context Vector)或编码向量(Encoding Vector)。它可以使用循环神经网络(如LSTM或GRU)或Transformer等结构来处理输入序列,并将序列信息压缩为固定维度的上下文向量。

解码器(Decoder):解码器接收编码器生成的上下文向量,并逐步生成输出序列(如目标语言句子)。解码器同样可以使用循环神经网络或Transformer结构,但它通常是使用逐步生成的方式,每个时间步生成一个词或符号,直到达到结束标记或达到最大长度。

Seq2Seq模型的训练过程通常使用教师强制(Teacher Forcing)的方式。在训练过程中,解码器的输入是已知的目标序列,以便更好地进行学习和优化。而在实际应用中,解码器则会根据之前生成的符号来生成下一个符号。

一些常见的 Seq2Seq模型包括:

基于循环神经网络的 Seq2Seq:使用循环神经网络作为编码器和解码器的基础模型,如基于LSTM或GRU的 Seq2Seq模型。

基于 Transformer 的 Seq2Seq:将 Transformer 结构应用于 Seq2Seq 模型,通过自注意力机制处理序列信息。这种模型通常在机器翻译等任务中表现出色,其中代表就是 Google 提出的 Transformer 模型。

带有注意力机制的 Seq2Seq:引入注意力机制(Attention Mechanism)来改善 Seq2Seq 模型的性能,使解码器能够更好地关注输入序列的不同部分,更准确地生成输出序列。

Seq2Seq 模型在自然语言处理领域具有重要的地位,其灵活性和强大的建模能力使其成为许多序列到序列学习任务的首选模型。

下面我们着重介绍基于Transformer模块的编码器和解码器的基本原理和组成部分:

2.1. 编码器(Encoder):

2.1.1. 输入嵌入(Input Embedding):将输入序列中的每个单词或标记映射为实数向量表示,以便模型能够理解和处理。

2.1.2. 位置编码(Positional Encoding):将位置信息嵌入到输入表示中,用于区分不同位置的单词或标记,并处理序列的顺序关系。

2.1.3. 自注意力层(Self-Attention Layer):通过自注意力机制,对输入序列中不同位置之间的相关性进行建模,以获取每个位置的上下文信息。

2.1.4. 前馈神经网络层(Feed-Forward Neural Network Layer):对自注意力层的输出进行非线性变换和映射,以提供更丰富的特征表示。

2.1.5. 堆叠多个层:编码器通常由多个自注意力层和前馈神经网络层堆叠而成,通过堆叠多层来逐渐提取和整合更丰富的上下文信息。

2.2. 解码器(Decoder):

2.2. 1. 目标嵌入(Target Embedding):将目标序列中的每个单词或标记映射为实数向量表示。

2.2. 2. 位置编码(Positional Encoding):与编码器相同的位置编码技术,将位置信息嵌入到目标表示中。

2.2. 3. 自注意力层(Self-Attention Layer):类似于编码器中的自注意力层,用于捕捉目标序列中的上下文相关性。

2.2. 4. 编码器-解码器注意力层(Encoder-Decoder Attention Layer):通过对输入序列和解码器自注意力层的输出进行注意力计算,将编码器的上下文信息引入到解码器中,帮助生成准确的目标序列。

2.2. 5. 前馈神经网络层(Feed-Forward Neural Network Layer):对解码器自注意力层和编码器-解码器注意力层的输出进行非线性变换和映射。

2.2. 6. 堆叠多个层:与编码器类似,解码器通常由多个自注意力层、编码器-解码器注意力层和前馈神经网络层堆叠而成。

2.3. 编码器和解码器之间的连接:

在编码器和解码器之间,还存在连接的机制来促进信息的流动和梯度的传播:

2.3.1. 编码器的输出作为解码器的输入,使得解码器能够获取输入序列的上下文信息。

2.3.2. 在解码器中,引入了一个额外的注意力层,称为解码器自注意力层(Decoder Self-Attention Layer),它用于建模目标序列内部的依赖关系。该自注意力层帮助解码器关注目标序列中不同位置的相关性,并生成具有上下文感知的表示。

动图封面

编码器-解码器结构的优点在于:

- 能够处理变长序列输入和输出,适用于机器翻译、文本摘要、语音识别等任务。

- 编码器和解码器的堆叠层允许模型学习复杂的特征表示和上下文关系,提高模型的表达能力。

- 自注意力机制允许模型根据任务需要自动地关注不同位置的信息,从而提高模型在长程依赖建模和序列建模方面的能力。

与 Word2Vec 和 GloVe 等传统词向量模型相比,Transformer 模型在处理序列数据方面具有以下优势:

- 能够建模全局依赖关系,不受窗口大小的限制,从而更好地捕捉长程依赖。

- 通过自注意力机制,能够动态地学习序列中不同位置之间的关联程度,而不是固定的词语间关系。

- 具备并行计算的能力,加快训练和推理速度。

Transformer模型采用了编码器-解码器结构,编码器用于将输入序列编码为上下文感知的表示,解码器用于生成目标序列。编码器和解码器都由多个层组成,包括自注意力层、前馈神经网络层等。编码器和解码器之间通过注意力连接来促进信息的流动。这种结构具有较好的建模能力和并行计算能力,适用于处理序列数据的各种任务。相较于传统词向量模型,Transformer 模型能够更全面、准确地捕捉序列中的上下文信息和依赖关系。

下面是使用PyTorch实现Transformer模型中的编解码结构的编码器部分代码,并对每行代码进行注释说明:

import torch
import torch.nn as nn


class EncoderLayer(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, dropout):
        super(EncoderLayer, self).__init__()


        # 多头自注意力机制
        self.self_attention = nn.MultiheadAttention(d_model, num_heads, dropout=dropout)


        # 前馈神经网络
        self.feed_forward = nn.Sequential(
            nn.Linear(d_model, d_ff),
            nn.ReLU(),
            nn.Linear(d_ff, d_model)
        )


        # Layer Normalization
        self.layernorm1 = nn.LayerNorm(d_model)
        self.layernorm2 = nn.LayerNorm(d_model)


        # Dropout
        self.dropout = nn.Dropout(dropout)


    def forward(self, x):
        # 多头自注意力机制
        attn_output, _ = self.self_attention(x, x, x)
        attn_output = self.dropout(attn_output)
        out1 = self.layernorm1(x + attn_output)


        # 前馈神经网络
        ffn_output = self.feed_forward(out1)
        ffn_output = self.dropout(ffn_output)
        out2 = self.layernorm2(out1 + ffn_output)


        return out2




class TransformerEncoder(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, num_layers, dropout):
        super(TransformerEncoder, self).__init__()


        # 编码器层
        self.layers = nn.ModuleList([
            EncoderLayer(d_model, num_heads, d_ff, dropout) for _ in range(num_layers)
        ])


    def forward(self, x):
        for layer in self.layers:
            x = layer(x)
        return x




if __name__ == '__main__':


    # 测试代码
    d_model = 512  # 输入维度
    num_heads = 8  # 注意力头数
    d_ff = 2048  # 前馈神经网络的隐藏层维度
    num_layers = 6  # 编码器层数
    dropout = 0.1
    batch_size = 16
    seq_len = 50


    # 创建Transformer编码器
    encoder = TransformerEncoder(d_model, num_heads, d_ff, num_layers, dropout)


    # 创建输入张量
    x = torch.randn(batch_size, seq_len, d_model)


    # 将输入张量传递给Transformer编码器进行编码
    output = encoder(x)


    print(output.size())  # 输出结果的形状

这段代码实现了Transformer模型中的编解码结构中的编码器部分。编码器由多个编码器层组成,每个编码器层包含多头自注意力机制和前馈神经网络。编码器的作用是对输入序列进行编码,以捕捉序列中的语义信息。

代码中的 `EncoderLayer` 类定义了编码器层的结构。在 `forward` 方法中,首先通过多头自注意力机制对输入进行交互,然后使用前馈神经网络对交互结果进行非线性变换,最后应用残差连接和层归一化操作。

`TransformerEncoder` 类定义了整个编码器的结构。在 `forward` 方法中,通过遍历所有编码器层将输入传递给编码器层进行编码。

测试代码中,创建了一个随机的输入张量 `x`。然后将输入张量传递给Transformer编码器进行编码。最后输出结果的形状。

下面这段代码是使用PyTorch实现Transformer模型中编解码结构的解码器代码,并对每行代码进行了注释说明:

import torch
import torch.nn as nn


class DecoderLayer(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, dropout):
        super(DecoderLayer, self).__init__()


        # 多头自注意力机制(解码器自注意力)
        self.self_attention = nn.MultiheadAttention(d_model, num_heads, dropout=dropout)


        # 编码器-解码器注意力
        self.enc_dec_attention = nn.MultiheadAttention(d_model, num_heads, dropout=dropout)


        # 前馈神经网络
        self.feed_forward = nn.Sequential(
            nn.Linear(d_model, d_ff),
            nn.ReLU(),
            nn.Linear(d_ff, d_model)
        )


        # Layer Normalization
        self.layernorm1 = nn.LayerNorm(d_model)
        self.layernorm2 = nn.LayerNorm(d_model)
        self.layernorm3 = nn.LayerNorm(d_model)


        # Dropout
        self.dropout = nn.Dropout(dropout)


    def forward(self, x, enc_output):
        # 解码器自注意力
        self_attn_output, _ = self.self_attention(x, x, x)
        self_attn_output = self.dropout(self_attn_output)
        out1 = self.layernorm1(x + self_attn_output)


        # 编码器-解码器注意力
        enc_dec_attn_output, _ = self.enc_dec_attention(out1, enc_output, enc_output)
        enc_dec_attn_output = self.dropout(enc_dec_attn_output)
        out2 = self.layernorm2(out1 + enc_dec_attn_output)


        # 前馈神经网络
        ffn_output = self.feed_forward(out2)
        ffn_output = self.dropout(ffn_output)
        out3 = self.layernorm3(out2 + ffn_output)


        return out3




class TransformerDecoder(nn.Module):
    def __init__(self, d_model, num_heads, d_ff, num_layers, dropout):
        super(TransformerDecoder, self).__init__()


        # 解码器层
        self.layers = nn.ModuleList([
            DecoderLayer(d_model, num_heads, d_ff, dropout) for _ in range(num_layers)
        ])


    def forward(self, x, enc_output):
        for layer in self.layers:
            x = layer(x, enc_output)
        return x




if __name__ == '__main__':


    # 测试代码
    d_model = 512  # 输入维度
    num_heads = 8  # 注意力头数
    d_ff = 2048  # 前馈神经网络的隐藏层维度
    num_layers = 6  # 解码器层数
    dropout = 0.1
    batch_size = 16
    seq_len = 50


    # 创建Transformer解码器
    decoder = TransformerDecoder(d_model, num_heads, d_ff, num_layers, dropout)


    # 创建输入张量
    x = torch.randn(batch_size, seq_len, d_model)


    # 创建编码器输出张量
    enc_output = torch.randn(batch_size, seq_len, d_model)


    # 将输入张量传递给Transformer解码器进行解码
    output = decoder(x, enc_output)


    print(output.size())  # 输出结果的形状

以上这段代码实现了Transformer模型编解码结构中的解码器部分。整个解码器由多个解码器层组成,每个解码器层包含解码器自注意力机制、编码器-解码器注意力机制和前馈神经网络。解码器的作用是将编码器的输出和自身的输入进行交互,生成最终的解码结果。

代码中的 `DecoderLayer` 类定义了解码器层的结构。在 `forward` 方法中,首先通过解码器自注意力机制对输入进行交互,然后使用编码器-解码器注意力机制和前馈神经网络对交互结果进行非线性变换,最后应用残差连接和层归一化操作。

`TransformerDecoder` 类定义了整个解码器的结构。在 `forward` 方法中,通过遍历所有解码器层将输入传递给解码器层进行解码。

测试代码中,创建了一个随机的输入张量 `x` 和编码器输出张量 `enc_output`。然后将输入张量传递给Transformer解码器进行解码。最后输出结果的形状。

3.位置编码(Positional Encoding):

Transformer 模型中的位置编码(Positional Encoding)是一种技术,用于将输入序列中的位置信息嵌入到词嵌入向量中,以帮助模型理解序列中不同位置之间的顺序关系。位置编码在编码器和解码器的每个层中都被添加到词嵌入向量中。

位置编码的基本思想是通过为每个位置分配一个独特的向量表示,以编码其相对位置。在 Transformer 模型中,使用了一种特殊的位置编码方式,即使用正弦和余弦函数来生成位置编码矩阵。

具体来说,位置编码矩阵的维度与词嵌入向量的维度相同。对于序列中的每个位置和每个维度,位置编码矩阵中的元素值由以下公式计算得出:

PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

其中,pos表示序列中的位置,i表示位置编码矩阵中的维度索引,d_model表示词嵌入向量的维度。通过这种方式,位置编码矩阵中的每个元素都代表了序列中特定位置和维度的位置编码值。

在输入序列中的每个词嵌入向量上,会与位置编码矩阵中对应位置的值相加,以将位置信息与词向量融合在一起。这样,模型在处理输入序列时能够区分不同位置的单词或标记,并准确捕捉序列中的顺序关系。

位置编码的优点在于能够为模型提供关于输入序列中不同位置的有序信息,有助于理解序列的顺序关系。通过位置编码的引入,Transformer 模型不仅仅关注词嵌入向量本身,还能够对序列的顺序进行建模,提高了模型的表达能力。

尽管位置编码看似起到了非常大的作用,但是要注意位置编码并不提供关于具体单词的语义信息,它仅仅关注位置的相对关系。在模型训练的过程中,位置编码会随着学习过程进行调整和更新,以更好地适应不同任务和数据的需求。

可见,位置编码是 将输入序列中的位置信息嵌入到词嵌入向量中。通过正弦和余弦函数生成位置编码矩阵,并将其与词嵌入向量相加,以捕捉序列中的顺序关系。位置编码能够为模型提供更全面、准确的上下文感知表示,有助于模型理解序列中不同位置之间的关系,并更好地捕捉长程依赖关系。相较于传统的序列模型,位置编码使得 Transformer 在处理序列数据时更具优势。

此外,位置编码与词嵌入向量的融合是逐元素相加的方式,因此位置编码并不引入额外的参数,不会增加模型的复杂度或训练难度。它是一种简单而有效的方式,能够提升模型对序列中位置信息的建模能力。

不过位置编码对于序列的长度是固定的,无法自适应不同长度的序列。对于较长的序列,位置编码可能无法很好地捕捉到较远位置的关系,这可能需要通过增加更多的层或使用其他技术进行处理。

下面是使用PyTorch实现Transformer模型中位置编码的代码,并对每行代码进行了注释说明:

import torch
import torch.nn as nn
import math


class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len):
        super(PositionalEncoding, self).__init__()


        self.d_model = d_model


        # 创建位置编码矩阵
        pe = torch.zeros(max_len, d_model)


        position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
        div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))


        # 计算位置编码值
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)


        # 添加位置编码权重作为模型的可学习参数
        self.register_buffer('pe', pe.unsqueeze(0))


    def forward(self, x):
        # 将位置编码加到输入张量中
        x = x + self.pe[:, :x.size(1)]
        return x


if __name__ == '__main__':


    # 测试代码
    d_model = 512
    max_len = 100
    batch_size = 16
    seq_len = 50


    # 创建位置编码层
    pos_encoding = PositionalEncoding(d_model, max_len)


    # 创建输入张量
    x = torch.randn(batch_size, seq_len, d_model)


    # 将输入张量传递给位置编码层进行位置编码
    output = pos_encoding(x)


    print(output.size())  # 输出结果的形状

这段代码实现了Transformer模型中的位置编码。位置编码层将输入张量中每个位置的表示与位置编码矩阵相加,以增加模型对序列中位置信息的建模能力。位置编码的数学公式为

PE(pos, 2i) = sin(pos / 10000^(2i/d_model))

PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))

这段代码中的 `PositionalEncoding` 类定义了位置编码的模块。在 `__init__` 方法中,创建了一个大小为 `(max_len, d_model)` 的位置编码矩阵,并将其作为可学习参数加入模型。在 `forward` 方法中,我们将位置编码矩阵与输入张量相加,以实现位置编码的功能。

测试代码中,创建了一个随机的输入张量 `x`,然后将其传递给位置编码层进行位置编码。最后输出结果的形状。

请注意,这里的代码仅实现了位置编码部分,而不涉及Transformer模型的完整实现。如果需要构建完整的Transformer模型,还需要将自注意力机制、前馈神经网络等组件联合起来使用。

相较于 ELMo 模型,Transformer 模型在一些应用中具有以下优势:

1. 并行计算性能:ELMo 模型是基于循环神经网络 (RNN) 的模型,它需要按序处理输入序列,导致难以进行并行计算。而 Transformer 模型通过自注意力机制实现了并行计算,可以充分利用硬件资源,加速训练和推理的速度。

2. 上下文无关编码:ELMo 模型通过将上下文信息编码到固定维度的向量中,提供了上下文相关的词嵌入表示。然而,在某些任务中,上下文无关的编码可能更适合,例如在句法分析和词义消歧等任务中,使用固定的上下文无关表示更加合适。在这些任务中,Transformer 模型中的位置编码提供了每个位置的位置信息,使得每个词的表示更加一致且与位置无关。

3. 长程依赖建模:Transformer 模型通过自注意力机制能够更好地建模输入序列中的长程依赖关系。相较之下,ELMo 模型是基于双向循环神经网络的,它在处理长序列时可能受到梯度消失或梯度爆炸的问题,并且对于远距离的依赖关系的建模能力相对较弱。

4. 多任务学习能力:Transformer 模型的架构和机制使得它适用于多任务学习。通过在编码器和解码器中引入不同的任务特定层或标签,可以将 Transformer 用于处理多个相关任务,并共享底层的表示学习。这使得 Transformer 在同时处理多个任务时更加灵活和高效。

需要注意的是,ELMo 模型和 Transformer 模型在不同的应用场景中可能具有不同的优势。ELMo 模型在某些任务中仍然表现出色,特别是在需要建模词语的上下文相关性和语义变化的任务中。在选择模型时,需要综合考虑任务的特点、数据集的性质以及模型的优势与限制。

关于AIGC文本生成内容方面的模型——Transformer 的介绍就到此结束,下一篇文章将继续介绍基于Transformer 模型改进的BERT模型,从原理技术和相关应用进行介绍分析。本系列文章内容只是介绍了模型的皮毛,如果想要深耕这个领域,需要从基础开始学习相关原理,然后进行项目实操,才能达到企业用人的基本要求。

关于AIGC在图像领域、自然语言处理的知识技能学习,这里有一个零基础的完整学习路线提供给大家,下图是工信部教考中心《人工智能算法工程师》(初级、中级、高级)三个级别证书的课程大纲,可以根据自己的实际情况选择学习初级、中级或者高级。

--初级《人工智能算法工程师》证书课程大纲


--中级《人工智能算法工程师》证书课程大纲


--高级《人工智能算法工程师》证书课程大纲


该系列课程通过在工信部教考中心组织的学习和考试,可获得由工信部教考中心颁发的工业和信息化职业能力证书——《人工智能算法工程师》,持有该证书者将被纳入到“工业和信息化技术技能人才数据库”,证书可在官网查询。优秀学员将有机会参加工信部教考中心或课程项目方组织的主题会议、课程沙龙等活动,并享受就业服务指导及相关优秀企业推荐就业等服务,是普通人目前进入人工智能行业的高效途径之一。目前该证书报名机构为成都深度智谷科技有限公司,有意者可以到其官网咨询报名。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

职责链模式:如何实现可灵活扩展算法的敏感信息过滤框架?

今天,我们主要讲解职责链模式的原理和实现。除此之外,我还会利用职责链模式,带你实现一个可以灵活扩展算法的敏感词过滤框架。下一节课,我们会更加贴近实战,通过剖析Servlet Filter、Spring Interceptor来看&#xff0…

K12351 生日日期

题解目录 K12351 生日日期题目描述输入格式输出格式解题思路解题思路2(未编写)示例代码 其他题解:思维拓展题目描述正确答案 K12351 生日日期 题目描述 小科的生日是YY年MM月DD日,他想知道自己出生第10000天纪念的日期&#xff…

如何在PADS Logic中查找器件

PADS Logic提供类似于Windows的查找功能,可以进行器件的查找。 (1)在Logic设计界面中,将菜单显示中的“选择工具栏”进行打开,如图1所示,会弹出对应的“选择工具栏”的分栏菜单选项,如图2所示。…

一文带你了解Spring中存入Bean和获取Bean的方式

0. Spring中的五大注解 上图中就是五大类注解对应的层,通过源码可以看到其他四个注解都基于Conponent 1. 存入 Bean Spring既然是一个包含众多工具方法的IoC容器,它是一个控制反转的容器,所以就需要将Bean对象存入到容器中,需要…

Vue中值的传递(父传子,子传父,子父同步)

1.父组件->子组件传递数据 ①父组件通过 v-bind: 属性绑定的形式,把数据传递给子组件 如果不需要动态绑定,则可以直接写number“张三” ②子组件中,通过props接收父组件传递过来的数据 2.子组件->父组件传递数据 1.在子组件中&#xf…

举例说明基于线性回归的单层神经网络网络(以梯度下降算法来求解权重的过程)...

我们将通过一个简单的例子来说明基于线性回归的单层神经网络,以及如何使用梯度下降算法来求解权重。 假设我们有以下数据集,表示学生的学习时间(小时)与他们的考试分数: 学习时间(X)&#xff1a…

使用NVIDIA FX Composer验证多纹理合成效果

最近项目上有一个需求,需要将4张带透明通道纹理合成为一张,并且每张纹理指定一个全局透明度。由于纹理过多,合成效果无法保证,为了减少项目的风险,领导希望我先快速验证一下我们讨论的方法是否能完成项目的要求。因此我…

Mybatis-Plus(二)--Mybatis-Plus方法大全

通用CRUD大全(Mybatis-Plus为我们提供了哪些操作) 还有在mybatis中遇到列名和属性名不一致等等的情况,在mybatis中xml中声明解决,在mybatis-plus中也都有对应的解决。 1.插入操作 //插入一条记录 //参数entity是实体对象 int ins…

基于单片机的智能点滴速度输液液体检测

目 录 摘 要...................................................................................................................... I ABSTRACT.......................................................................................................... II 第…

【机器学习】吴恩达课程1-Introduction

一、机器学习 1. 定义 计算机程序从经验E中学习,解决某一任务T,进行某一性能P,通过P测定在T上的表现因经验E而提高。 2. 例子 跳棋程序 E:程序自身下的上万盘棋局 T:下跳棋 P:与新对手下跳棋时赢的概…

离线数据仓库

一、数据仓库 1.数据仓库的概念 1)数据仓库的特点: 面向主题的:对数据进行整合、分析和归类的抽象集成的:将不同数据源的数据(业务数据、外部系统数据、埋点日志)经过统一编码、规范命名、字段类型转换等操作,整合到仓库相对稳定的:根据业务场景实时更新、一般会被长…

C语言-ubuntu下的命令

目录 linux命令 【1】打开关闭终端 【2】终端 【3】ls命令 【4】cd 切换路径 【5】新建 【6】删除 【7】复制 【8】移动 【9】常用快捷键 【10】vi编辑器 【11】简单编程步骤 任务: linux命令 【1】打开关闭终端 打开终端: 1. 直接点击 …

代码随香录day21

235. 二叉搜索树的最近公共祖先 本题思路: 还是要利用二叉搜索树的特性,中序遍历为有序数组。如果pq两个节点都小于root,那么最近公共祖肯定是在他的左子树,如果都大于那么,肯定就在右子树。然后直接return root 代码…

Sentinel的线程隔离和熔断降级

上一节整理了Sentinel的限流,限流可以降低微服务的负载,避免因为高并发而故障,进而传递给其他相关服务而引发服务雪崩。以上仅为避免服务故障,而当某个服务真正故障时,如何处理才能防止服务雪崩? ⇒ Sentin…

Azure Kinect DK 在设备管理器找不到此设备

参考 Azure Kinect DK 在设备管理器找不到此设备_Thomas_yx的博客-CSDN博客 type-c------------------type-c 接电脑,数据传输 圆------------------usb 电脑线

Spark(29):Spark内存管理

目录 0. 相关文章链接 1. 堆内和堆外内存规划 1.1. 堆内内存 1.2. 堆外内存 2. 内存空间分配 2.1. 静态内存管理 2.2. 统一内存管理 3. 存储内存管理 3.1. RDD 的持久化机制 3.2. RDD的缓存过程 3.3. 淘汰与落盘 4. 执行内存管理 4.1. Shuffle Write 4.2. Shuffl…

【STM32】使用HAL库对ULN2003控制28BYJ-48步进电机

步进电机是将电脉冲信号转变为角位移或线位移,通过控制施加在电机线圈上的电脉冲顺序、频率和数量,可以控制步进电机的转向、速度和旋转角度。 配合以直线运动执行机构(螺纹丝杆)或齿轮箱装置,更可以实现更加复杂、精密的线性运动控制要求。…

HTTP进化史:从HTTP1的简单到HTTP3的强大

文章目录 📈I. HTTP1⚡A. 基本特点⚡B. 特点⚡C. 优缺点 📈II. HTTP2⚡A. 基本特点⚡B. 特点⚡C. 优缺点 📈III. HTTP3⚡A. 基本特点⚡B. 特点⚡C. 优缺点 📈IV. 总结📈附录:「简历必备」前后端实战项目&am…

【动手学深度学习】pytorch-参数管理

pytorch-参数管理 概述 我们的目标是找到使损失函数最小化的模型参数值。 经过训练后,我们将需要使用这些参数来做出未来的预测。 此外,有时我们希望提取参数,以便在其他环境中复用它们, 将模型保存下来,以便它可以在…

回归预测 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多输入单输出回归预测

回归预测 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-CNN鲸鱼算法优化卷积神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 回归预测 | MATLAB实现WOA-CNN鲸鱼算法优化卷积…