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

news2024/9/23 5:23:35
在上一篇文章中,我们一口气介绍了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在图像领域、自然语言处理的知识技能学习,这里有一个零基础的完整学习路线提供给大家,下图是工信部教考中心《人工智能算法工程师》(初级、中级、高级)三个级别证书的课程大纲,可以根据自己的实际情况选择学习初级、中级或者高级。

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


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


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


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

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

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

相关文章

electron+vue3全家桶+vite项目搭建【23】url唤醒应用,并传递参数

文章目录 引入实现效果实现步骤测试代码 引入 demo项目地址 很多场景下我们都希望通过url快速唤醒应用,例如百度网盘,在网页中唤醒应用,并传递下载链接,在electron中要实现这样的效果,就需要针对不同的平台做对应的处…

SpringMVC【SpringMVC拦截器、 SpringMVC跨域请求、SSM整合】(七)-全面详解(学习总结---从入门到深化)

目录 SpringMVC拦截器_拦截器过滤敏感词案例 SpringMVC跨域请求_同源策略 SpringMVC跨域请求_跨域请求 SpringMVC跨域请求_控制器接收跨域请求 SSM整合_需求分析 SSM整合_创建父工程 SSM整合_创建dao子工程 SSM整合_创建service子工程 SSM整合_创建controller子工程 …

Gradle和Aritifactory,实现上传Apk并发送消息到钉钉

Gradle和Aritifactory 本文链接:https://blog.csdn.net/feather_wch/article/details/131746580 文章目录 Gradle和AritifactoryGradle基本介绍Gradle插件开发流程本地仓库artifactory搭建添加仓库使用本地仓库gradle插件仓库引入 插件buildSrc开发步骤xxxPluginPg…

【力扣周赛】第 354 场周赛

文章目录 Q1:6889. 特殊元素平方和思路——简单模拟题竞赛时代码 Q2:6929. 数组的最大美丽值思路——差分数组,计算每个数字可能出现的次数竞赛时代码 Q3:6927. 合法分割的最小下标思路——投票法求出现次数超过半数的元素 模拟竞…

dede tag彩色随机大小的样式修改方法

dede tag彩色随机大小的样式修改方法,打开include/common.func.php 在最下面添加以下代码: //TAG彩色 jinmengqiang.cn function getTagStyle() { $minFontSize8; //最小字体大小,可根据需要自行更改 $maxFontSize18; //最大字体大小,可根据需要自行更改…

(中等)剑指Offer II 062.实现前缀树 Java

Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段: 指向子节点的指针数组children,对于本题而言,数组长度为26,即小写英文字母的数量。此时children[0]对应着小写字母a&#xff0…

数据结构(王道)——队列

一、队列的定义 三个重要名词:队头、队尾、空队列。 二、队列的基本操作 队列总结: 三、队列的顺序表实现 基本操作: 静态创建队列顺序表 队列顺序表的初始化操作: 入队操作: 入队操作优化: 最优版入队操作…

Navicat-Cracker NavicatCrackerDlg.cpp:332 -3已解决Navicat 162版本注册问题的详细分析与解决方案

博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客👦🏻 《java 面试题大全》 🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭 《MYSQL从入门到精通》数据库是开发者必会基础之…

一零六五、零基础入门数据挖掘-心跳信号分类预测(阿里云天池赛)

目录 赛制官方链接 赛题简介 赛制说明 长期赛(2021年7月~) 正式赛(3月12日 - 5月12日) 大赛组织 赛题背景 赛题数据 评测标准 结果提交 代码实现 赛制官方链接 零基础入门数据挖掘-心跳信号分类预测_学习赛_…

哈希表以及用js封装一个哈希表

最近在学数据结构和算法,正好将学习的东西记录下来,我是跟着一个b站博主学习的,是使用js来进行讲解的,待会也会在文章后面附上视频链接地址,大家想学习的可以去看看 本文主要讲解哈希表,其他数据结构后续学…

轻松入门Python量化交易(三)

大家好,我们接第二部分继续分析金融数据。 配对图和相关矩阵 证券中的相关性分析为我们提供了有趣的投资策略。市场中一个广为人知的策略叫做“Long-Short”,即买入一家公司的证券,同时卖出另一家公司的证券,相信这两个资产在市…

《微服务架构设计模式》第八章 外部API模式

内容总结自《微服务架构设计模式》 外部API模式 一、API设计难题二、API Gateway 模式1、简介2、所有者模式3、好处和弊端4、设计问题5、实现一个API Gateway 三、使用GraphQL 实现API Gateway四、总结 一、API设计难题 1、移动客户端的API设计难题 在此设计中,移动…

动态规划(二) —— 打家劫舍系列问题总结

前言 除了背包系列问题,打家劫舍系列问题同样也是动态规划的经典题目。在这篇文章中荔枝将会把打家劫舍系列问题做一下总结,再仔细体会动态规划的思想,希望能帮到有需要的小伙伴~~~ 文章目录 前言 一、Leecode198.打家劫舍 1.1 分析 1.2 …

C2C、B2B、B2C、O2O电商定义区别

如今是电子商务高度发展的时代,大多数传统企业商家都开始采取转型战略帮助企业发展,商业模式的选择是转型的关键点,下面小编向你详细介绍一下B2B、B2C、C2C、O2O这些商务模式,帮助你快速理解它们。 BBusiness,即企业;…

Servlet实现文件下载的功能

download.html <% page contentType"text/html;charsetUTF-8" language"java" %> <html> <head><title>文件下载</title><base href"<%request.getContextPath()"/"%>>"> </head>…

前端基本功 用 React Hooks + Antd 实现一个 Todo-List

背景 使用 React Hooks 以及组件库 Antd 来实现一个可以 增删 标记是否完成 的 todo-list 思路 要实现一个 todo-list 首先想到用 useState 维护一个状态数组来保存当前 list &#xff0c;还要用一个状态维护添加框中的内容 const [todos, setTodos] useState(initialValu…

OpenCv图像基本变换

目录 一、图像翻转 二、图像旋转 三、仿射变换之平移 四、仿射变换之获取变换矩阵 五、仿射变换之透视变换 一、图像翻转 图像翻转不等同于旋转&#xff0c;类似于一些视频的拍摄&#xff0c;拍摄后实际是左右颠倒的&#xff0c;通过图像翻转可进行还原 案例代码如下: …

第十四章:Context Encoding for Semantic Segmentation ——语义分割的上下文编码

0.摘要 近期的研究在使用全卷积网络&#xff08;FCN&#xff09;框架改善像素级标注的空间分辨率方面取得了显著进展&#xff0c;通过采用扩张/空洞卷积、利用多尺度特征和细化边界等方法。本文通过引入上下文编码模块来探索全局上下文信息对语义分割的影响&#xff0c;该模块捕…

springMVC的开发步骤-15

第一步你用到前端核心控制器&#xff0c;你应该有他&#xff0c;因此导包&#xff1a; 第二步:配servlet 第三步&#xff1a;配控制器&#xff0c;用来调用视图 结束之后我要干嘛&#xff1f;这个springMvC,我能否将这个pojo放到容器内部当中&#xff0c;能否通过bean标签进行配…

Linux 系统编程-开发环境(三)

目录 16 vim 16.1 vi简介 16.1.1 命令行模式 16.1.2 文本输入模式 16.1.3 末行模式 16.2 vim基础操作 16.3 vim分屏操作 16.4 vim打造IDE 16.4.1 简洁版IDE 17 gcc 18 toolchain 19 静态库和共享库 19.1 静态库 19.2 共享库 19.2.1 基础班使 19.2.2 就业班使用…