首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[算法前沿]--004-transformer的前世今生

[算法前沿]--004-transformer的前世今生

作者头像
AI拉呱
发布于 2023-04-28 11:17:53
发布于 2023-04-28 11:17:53
66000
代码可运行
举报
运行总次数:0
代码可运行

1.transformer介绍

  1. Transformer被认为是一种新型的深度前馈人工神经网络架构,它利用了自注意机制,可以处理输入序列项之间的长期相关性。
  2. 在大量领域中采用,如自然语言处理(NLP)、计算机视觉(CV)、,音频和语音处理、化学和生命科学;他们可以在前面提到的学科中实现SOTA性能。
  3. TransformerX库存储库

1.1 注意力机制

  1. 注意力是一种处理能力有限的认知资源分配方案
  2. 它同时生成源标记(单词)的翻译,1)这些相关位置的上下文向量和2)先前生成的单词。
  3. 注意力的特性 1.软 2.硬 3.局部 4.全局
  4. 输入特征的形式
    1. Item-wise 2. Location-wise
  5. 输入表示 1.Co-attention 2. Self-attention 3. Distinctive attention 4. Hierarchical attention
  6. 输出表示
    1. 多头 2.单输出 3.多维

1.2 Transformer架构

  1. 基本Transformer架构由两个主要构建块组成,即编码器和解码器块.(与序列到序列模型类似,Transformer使用编码器-解码器架构)
  2. 编码器从输入表示序列 (𝒙₁ , …, 𝒙ₙ) 生成嵌入向量𝒁 = (𝒛₁ , …, 𝒛ₙ),并将其传递给解码器以生成输出序列 (𝒚₁ , …, 𝒚ₘ). 在每一步生成输出之前,𝒁 向量被送入解码器,因此该模型是自回归的。

1.2.1编码器

  1. 编码器只是多个组件或层的堆栈-𝑵 在原始论文中是6。它们本身是两个子层,即多头自注意块和简单FC FFN(全连接的前馈网络)。
  2. 为了实现更深入的模型,研究人员通过包裹两个子层,然后进行层归一化,并实现残差连接。因此,每个子层的输出都是LayerNorm( 𝒙 + Sublayer( 𝒙 )) ,Sublayer(* 𝒙 *)*是在其内部实现的函数。所有子层以及嵌入的输出维度为𝒅 _model=512。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import tensorflow as tf

from transformerx.layers.positional_encoding import SinePositionalEncoding
from transformerx.layers.transformer_encoder_block import TransformerEncoderBlock


class TransformerEncoder(tf.keras.layers.Layer):
    def __init__(self,vocab_size,depth,norm_shape,ffn_num_hiddens,
        num_heads,
        n_blocks,
        dropout,
        bias=False,
    ):
        super().__init__()
        self.depth = depth
        self.n_blocks = n_blocks
        self.embedding = tf.keras.layers.Embedding(vocab_size, depth)
        self.pos_encoding = SinePositionalEncoding(depth, dropout)
        self.blocks = [
            TransformerEncoderBlock(
                depth,
                norm_shape,
                ffn_num_hiddens,
                num_heads,
                dropout,
                bias,
            )
            for _ in range(self.n_blocks)
        ]

    def call(self, X, valid_lens, **kwargs):
     X = self.pos_encoding(
            self.embedding(X) * tf.math.sqrt(tf.cast(self.depth, dtype=tf.float32)),
            **kwargs,
        )
        self.attention_weights = [None] * len(self.blocks)
        for i, blk in enumerate(self.blocks):
            X = blk(X, valid_lens, **kwargs)
            self.attention_weights[i] = blk.attention.attention.attention_weights
        return X

1.2.2解码器

  1. 除了编码器中使用的子层之外,解码器对编码器组件的输出应用多头注意。与编码器一样,残差连接连接到子层,然后进行层规范化。保证对该位置的预测𝒊 可以仅依赖于先前已知的位置,对自注意子层应用另一种修改以防止位置伴随着将输出嵌入偏移一个位置而注意其他位置。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import tensorflow as tf

from transformerx.layers.positional_encoding import SinePositionalEncoding
from transformerx.layers.transformer_decoder_block import TransformerDecoderBlock


class TransformerDecoder(tf.keras.layers.Layer):
    def __init__(self,vocab_size,depth,norm_shape,ffn_num_hiddens,num_heads,n_blocks,dropout,):
        super().__init__()
        self.depth = depth
        self.n_blocks = n_blocks
        self.embedding = tf.keras.layers.Embedding(vocab_size, depth)
        self.pos_encoding = SinePositionalEncoding(depth, dropout)
        self.blocks = [
            TransformerDecoderBlock(
                depth,
                norm_shape,
                ffn_num_hiddens,
                num_heads,
                dropout,
                i,
            )
            for i in range(n_blocks)
        ]
        self.dense = tf.keras.layers.Dense(vocab_size)

    def init_state(self, enc_outputs, enc_valid_lens):
        return [enc_outputs, enc_valid_lens, [None] * self.n_blocks]

    def call(self, X, state, **kwargs):
         X = self.pos_encoding(
            self.embedding(X) * tf.math.sqrt(tf.cast(self.depth, dtype=tf.float32)),
            **kwargs,
        )
        # 2 attention layers in decoder
        self._attention_weights = [[None] * len(self.blocks) for _ in range(2)]
        for i, blk in enumerate(self.blocks):
            X, state = blk(X, state, **kwargs)
            # Decoder self-attention weights
            self._attention_weights[0][i] = blk.attention1.attention.attention_weights
            # Encoder-decoder attention weights
            self._attention_weights[1][i] = blk.attention2.attention.attention_weights
        return self.dense(X), state

    @property
    def attention_weights(self):
        return self._attention_weights

2. Transformer中的模块

2.1 注意模块

该Transformer将信息检索中的查询键值(QKV)概念与注意力机制相结合

  1. 缩放的点积注意
  2. 多头注意力

2.1.1 缩放点积注意事项

矩阵𝑨 在等式1中,通常称为注意力矩阵。他们使用点积注意力而不是加法注意力(使用具有单个隐藏层的前馈网络来计算兼容性函数)的原因是,由于矩阵乘法优化技术,速度和空间效率更快。

尽管如此,对于较大值的𝐷𝑘 这将softmax函数的梯度推到极小的梯度。为了抑制softmax函数的梯度消失问题,将键和查询的点积除以𝐷𝑘, 由于这个事实,它被称为缩放点积。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os

import numpy as np
import tensorflow as tf

from transformerx.utils import masked_softmax


class DotProductAttention(tf.keras.layers.Layer):
    def __init__(
        self,
        dropout_rate: float = 0,
        scaled: bool = True,
        normalize: bool = False,
        kernel_initializer: str = "ones",
        kernel_regularizer: str = None,
        **kwargs
    ):
        super().__init__(**kwargs)
        self.dropout_rate = dropout_rate
        self.dropout = tf.keras.layers.Dropout(self.dropout_rate)
        self.scaled = scaled
        self.normalize = normalize
        self.attention_weights = None
        self.kernel_initializer = kernel_initializer
        self.kernel_regularizer = kernel_regularizer

    def build(self, input_shape):
        super().build(input_shape)

    # Shape of queries: (batch_size, no. of queries, d)
    # Shape of keys: (batch_size, no. of key-value pairs, d)
    # Shape of values: (batch_size, no. of key-value pairs, value dimension)
    # Shape of attention_mask: (batch_size,) or (batch_size, no. of queries)
    def call(
        self,
        queries: tf.Tensor,
        keys: tf.Tensor,
        values: tf.Tensor,
        attention_mask: tf.Tensor = None,
        causal_mask: bool = None,
        training=None,
        **kwargs
    ) -> tf.Tensor:
        scores = tf.matmul(queries, keys, transpose_b=True)
        if self.scaled:
            # self.scale = self.add_weight(
            #     name="scale",
            #     shape=(scores.shape),
            #     initializer=self.kernel_initializer,
            #     regularizer=self.kernel_regularizer,
            #     trainable=True,
            # )
            depth = queries.shape[-1]
            # print(self.scale, scores.shape)
            # self.scale = tf.broadcast_to(scores.shape)
            # self.scale = tf.broadcast_to(
            #     tf.expand_dims(tf.expand_dims(self.scale, -1), -1), scores.shape
            # )
            scores = (
                scores
                / tf.math.sqrt(tf.cast(depth, dtype=tf.float32))
                # * self.scale
            )

        # apply causal mask
        if causal_mask:
            seq_len = tf.shape(queries)[2]
            heads = tf.shape(queries)[1]
            causal_mask = tf.ones((heads, seq_len)) * -1e9
            causal_mask = tf.linalg.LinearOperatorLowerTriangular(
                causal_mask
            ).to_dense()
            causal_mask = tf.expand_dims(causal_mask, axis=0)  # add batch dimension
            scores += tf.broadcast_to(
                tf.expand_dims(causal_mask, -1), scores.shape
            )  # broadcast across batch dimension

        self.attention_weights = masked_softmax(scores, attention_mask)
        # self.attention_weights = tf.nn.softmax(scores, axis=-1, mask=attention_mask)
        scores = tf.matmul(self.dropout(self.attention_weights, **kwargs), values)
        if self.normalize:
            depth = tf.cast(tf.shape(keys)[-1], tf.float32)
            scores /= tf.sqrt(depth)
        return scores

    def get_attention_weights(self):
        return self.attention_weights

2.1.2 多头注意

  • 引入多个注意力头而不是单个注意力函数,Transformer 将 𝐷𝑚 维的原始查询、键和值线性投影到 𝐷𝑘、𝐷𝑘 和 𝐷𝑣 维度,分别使用不同的线性投影 h次;通过它,可以并行计算这些投影上的注意力函数(等式 1),产生 𝐷𝑣 维输出值。然后该模型将它们连接起来并生成 𝐷𝑚 维表示。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import tensorflow as tf
from einops import rearrange

from transformerx.layers.dot_product_attention import DotProductAttention


class MultiHeadAttention(tf.keras.layers.Layer):
    def __init__(
        self,
        d_model: int = 512,
        num_heads: int = 8,
        dropout_rate: float = 0,
        bias: bool = False,
        attention: str = "scaled_dotproduct",
        **kwargs,
    ):
        super(MultiHeadAttention, self).__init__(**kwargs)
        self.d_model = d_model
        self.num_heads = num_heads
        self.dropout_rate = dropout_rate
        self.bias = bias
        if attention == "scaled_dotproduct" or attention == None:
            self.attention = DotProductAttention(self.dropout_rate, scaled=True)
        elif attention == "dotproduct":
            self.attention = DotProductAttention(self.dropout_rate, scaled=False)
        self.W_q = tf.keras.layers.Dense(self.d_model, use_bias=self.bias)
        self.W_k = tf.keras.layers.Dense(self.d_model, use_bias=self.bias)
        self.W_v = tf.keras.layers.Dense(self.d_model, use_bias=self.bias)
        self.W_o = tf.keras.layers.Dense(self.d_model, use_bias=self.bias)

    def split_heads(self, X: tf.Tensor) -> tf.Tensor:
        # x = tf.reshape(x, shape=(x.shape[0], x.shape[1], self.num_heads, -1))
        X = rearrange(X, "b l (h dk) -> b l h dk", h=self.num_heads)
        # x = tf.transpose(x, perm=(0, 2, 1, 3))
        X = rearrange(X, "b l h dk -> b h l dk")
        # return tf.reshape(x, shape=(-1, x.shape[2], x.shape[3]))
        # X = rearrange(X, "b h l dk -> (b h) l dk")
        return X

    def inverse_transpose_qkv(self, X: tf.Tensor) -> tf.Tensor:

        # transpose back to original shape: (batch_size, seq_len, num_heads, head_dim)
        X = rearrange(X, "b h l d -> b l h d")

        # concatenate num_heads dimension with head_dim dimension:
        X = rearrange(X, "b l h d -> b l (h d)")
        return X

    def call(
        self,
        queries: tf.Tensor,
        values: tf.Tensor,
        keys: tf.Tensor,
        attention_mask: tf.Tensor = None,
        causal_mask: bool = False,
        **kwargs,
    ) -> tf.Tensor:
        
        queries = self.split_heads(self.W_q(queries))
        keys = self.split_heads(self.W_k(keys))
        values = self.split_heads(self.W_v(values))

        if attention_mask is not None:
            # On axis 0, copy the first item (scalar or vector) for num_heads
            # times, then copy the next item, and so on
            attention_mask = tf.repeat(attention_mask, repeats=self.num_heads, axis=0)

        # Shape of output: (batch_size * num_heads, no. of queries,
        # depth / num_heads)
        output = self.attention(
            queries, keys, values, attention_mask, causal_mask, **kwargs
        )

        # Shape of output_concat: (batch_size, no. of queries, depth)
        output_concat = self.inverse_transpose_qkv(output)
        return self.W_o(output_concat)

2.2 Transformer中的注意事项

  • Transformer论文中采用了三种不同的使用注意力的方法,它们在键、查询和值被输入注意力函数的方式方面是不同的。

2.2.1 自注意

  • 所有键、查询和值向量来自相同的序列,在Transformer的情况下,编码器的前一步输出,允许编码器同时注意其自身前一层中的所有位置,即。𝑸 = 𝑲 = 𝑽 = 𝑿 (以前的编码器输出)。

2.2.2 掩蔽的自注意(自回归或因果注意)

  • 尽管有编码器层,但在解码器的自注意中,查询被限制在它们之前的键值对位置以及它们的当前位置,以便保持自回归特性。这可以通过屏蔽无效位置并将其设置为负无限来实现,即𝑨 𝒊𝒋 = −∞ 如果𝒊 < 𝒋.

2.2.3 交叉注意

  • 这种类型的注意力从先前的解码器层获得其查询,而键和值是从编码器产量获得的。这基本上是在序列到序列模型中的编码器-解码器注意机制中使用的注意。换句话说,交叉注意力将两个不同的嵌入序列相结合,这些维度从一个序列中导出其查询,从另一个序列导出其键和值。
  • 假设S1和S2是两个嵌入序列,交叉注意力从S1获得其键和值,从S2获得其查询,然后计算注意力得分并生成长度为S2的结果序列。在Transformer的情况下,键和值是从编码器和前一步解码器输出的查询中导出的。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于ResNet和Transformer的场景文本识别
对于自然场景的文字识别我们会遇到了许多不规则裁剪的图像,其中包含文本表示。虽然已经引入了许多复杂的想法来从图像中提取确切的文本。例如光学字符识别 (OCR)、基于 RNN 的 seq2seq 注意方法都是被认为是从结构图像中提取序列信息的传统方法,但许多研究人员发现,很难处理不规则图像和训练时间使他们更加昂贵。基于 RNN 的 seq2seq 注意力方法需要输入的序列表示,这些输入因输入而异,因此很难训练数百万张图像。大多数时间模型无法预测文本或字符,因为我们正在处理自然场景图像。
deephub
2021/07/23
1K0
基于ResNet和Transformer的场景文本识别
使用Python实现深度学习模型:Transformer模型
Transformer模型自提出以来,已经成为深度学习领域,尤其是自然语言处理(NLP)中的一种革命性模型。与传统的循环神经网络(RNN)和长短期记忆网络(LSTM)不同,Transformer完全依赖于注意力机制来捕捉序列中的依赖关系。这使得它能够更高效地处理长序列数据。在本文中,我们将详细介绍Transformer模型的基本原理,并使用Python和TensorFlow/Keras实现一个简单的Transformer模型。
Echo_Wish
2024/06/08
1.3K0
使用Python实现深度学习模型:Transformer模型
解析Transformer模型
Google于2017年提出了《Attention is all you need》,抛弃了传统的RNN结构,「设计了一种Attention机制,通过堆叠Encoder-Decoder结构」,得到了一个Transformer模型,在机器翻译任务中「取得了BLEU值的新高」。在后续很多模型也基于Transformer进行改进,也得到了很多表现不错的NLP模型,前段时间,相关工作也引申到了CV中的目标检测,可参考FAIR的DETR模型
BBuf
2020/10/10
1.1K0
CNN、Transformer、MLP架构的经验性分析
ViT的兴起挑战了CNN的地位,随之而来的是MLP系列方法。三种架构各有特点,为了公平地比较几种架构,本文提出了统一化的框架SPACH来对比,得到了具有一定insight的结论。论文来自微软的A Battle of Network Structures: An Empirical Study of CNN, Transformer, and MLP
BBuf
2021/12/27
1.2K0
CNN、Transformer、MLP架构的经验性分析
Transformer的基本原理
Seq2Seq[1]框架最初是在神经机器翻译(Neural Machine Translation,NMT)领域中提出,用于将一种语言(sequence)翻译成另一种语言(sequence)。其结构如下图所示:
felixzhao
2022/09/26
1.3K0
transformer多头注意力的不同框架实现(tensorflow+pytorch)
现在来解释一下,为什么 num_heads 的值需要能够被 embed_dim 整除。这是为了把词的隐向量长度平分到每一组,这样多组注意力也能够放到一个矩阵里,从而并行计算多头注意力。
西西嘛呦
2020/11/24
3.3K0
transformer多头注意力的不同框架实现(tensorflow+pytorch)
Transformers 4.37 中文文档(九十四)
SpeechEncoderDecoderModel 可用于使用任何预训练语音自编码模型作为编码器(例如 Wav2Vec2,Hubert)和任何预训练自回归模型作为解码器初始化语音到文本模型。
ApacheCN_飞龙
2024/06/26
4040
Transformers 4.37 中文文档(九十四)
【现代深度学习技术】注意力机制07:Transformer
深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重要的技术特征是具有自动提取特征的能力。神经网络算法、算力和数据是开展深度学习的三要素。深度学习在计算机视觉、自然语言处理、多模态数据分析、科学探索等领域都取得了很多成果。本专栏介绍基于PyTorch的深度学习算法实现。 【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/PyTorch_deep_learning。
Francek Chen
2025/05/21
2630
【现代深度学习技术】注意力机制07:Transformer
preprint版本 | 何凯明大神新作MAE | CVPR2022最佳论文候选
本文证明了蒙面自动编码器(MAE)是一种可扩展的计算机视觉自监督学习器。我们的MAE方法很简单:我们屏蔽输入图像的随机补丁并重建丢失的像素。
机器学习炼丹术
2021/12/06
1.3K0
preprint版本 | 何凯明大神新作MAE | CVPR2022最佳论文候选
Transformers 4.37 中文文档(八十八)
LayoutLM 模型是由 Yiheng Xu,Minghao Li,Lei Cui,Shaohan Huang,Furu Wei 和 Ming Zhou 在论文LayoutLM: Pre-training of Text and Layout for Document Image Understanding中提出的。这是一种简单但有效的文本和布局预训练方法,用于文档图像理解和信息提取任务,如表单理解和收据理解。它在几个下游任务上取得了最先进的结果:
ApacheCN_飞龙
2024/06/26
5040
Transformers 4.37 中文文档(四十二)
M2M100 模型是由 Angela Fan、Shruti Bhosale、Holger Schwenk、Zhiyi Ma、Ahmed El-Kishky、Siddharth Goyal、Mandeep Baines、Onur Celebi、Guillaume Wenzek、Vishrav Chaudhary、Naman Goyal、Tom Birch、Vitaliy Liptchinsky、Sergey Edunov、Edouard Grave、Michael Auli、Armand Joulin 在 Beyond English-Centric Multilingual Machine Translation 中提出的。
ApacheCN_飞龙
2024/06/26
4720
Transformers 4.37 中文文档(四十二)
可视化VIT中的注意力
来源:DeepHub IMBA 本文约4000字,建议阅读8分钟 本文为你介绍ViT模型。 2022年, Vision Transformer (ViT)成为卷积神经网络(cnn)的有力竞争对手,
数据派THU
2023/04/18
1.2K0
可视化VIT中的注意力
Transformers 4.37 中文文档(七十五)
CLAP 模型由 Yusong Wu,Ke Chen,Tianyu Zhang,Yuchen Hui,Taylor Berg-Kirkpatrick,Shlomo Dubnov 在大规模对比语言音频预训练与特征融合和关键词到标题增强中提出。
ApacheCN_飞龙
2024/06/26
4500
Transformers 4.37 中文文档(三十二)
本页面提供了 Meta AI 基础人工智能研究团队的 Transformer 蛋白质语言模型的代码和预训练权重,提供了最先进的 ESMFold 和 ESM-2,以及之前发布的 ESM-1b 和 ESM-1v。Transformer 蛋白质语言模型是由 Alexander Rives、Joshua Meier、Tom Sercu、Siddharth Goyal、Zeming Lin、Jason Liu、Demi Guo、Myle Ott、C. Lawrence Zitnick、Jerry Ma 和 Rob Fergus 在论文Biological structure and function emerge from scaling unsupervised learning to 250 million protein sequences中引入的。该论文的第一个版本于 2019 年预印。
ApacheCN_飞龙
2024/06/26
7800
Transformers 4.37 中文文档(三十二)
Transformers 4.37 中文文档(六十一)
X-MOD 模型是由 Jonas Pfeiffer、Naman Goyal、Xi Lin、Xian Li、James Cross、Sebastian Riedel 和 Mikel Artetxe 在Lifting the Curse of Multilinguality by Pre-training Modular Transformers中提出的。X-MOD 扩展了多语言掩码语言模型,如 XLM-R,在预训练期间包含特定于语言的模块化组件(语言适配器)。在微调中,每个 Transformer 层中的语言适配器被冻结。
ApacheCN_飞龙
2024/06/26
4280
Transformers 4.37 中文文档(五十五)
如果您在运行此模型时遇到任何问题,请重新安装支持此模型的最后一个版本:v4.30.0。您可以通过运行以下命令来执行:pip install -U transformers==4.30.0。
ApacheCN_飞龙
2024/06/26
4020
Transformer聊天机器人教程
在这篇文章中,我们将演示如何构建Transformer聊天机器人。 本文聚焦于:使用TensorFlow Dataset并使用tf.data创建输入管道来使用Cornell Movie-Dialogs Corpus,使用Model子类化实现MultiHeadAttention,使用Functional API实现Transformer。
昱良
2019/05/29
2.5K0
Transformer聊天机器人教程
Transformers 4.37 中文文档(三十九)
Jukebox 模型在 Jukebox: A generative model for music 中由 Prafulla Dhariwal, Heewoo Jun, Christine Payne, Jong Wook Kim, Alec Radford, Ilya Sutskever 提出。它引入了一个生成音乐模型,可以生成可以根据艺术家、流派和歌词进行条件化的一分钟长样本。
ApacheCN_飞龙
2024/06/26
2030
Transformers 4.37 中文文档(五十四)
REALM 模型是由 Kelvin Guu、Kenton Lee、Zora Tung、Panupong Pasupat 和 Ming-Wei Chang 在REALM: Retrieval-Augmented Language Model Pre-Training中提出的。这是一个检索增强语言模型,首先从文本知识语料库中检索文档,然后利用检索到的文档来处理问答任务。
ApacheCN_飞龙
2024/06/26
3420
Transformers 4.37 中文文档(六十)
T5v1.1 是由 Colin Raffel 等人在google-research/text-to-text-transfer-transformer存储库中发布的。这是原始 T5 模型的改进版本。这个模型是由patrickvonplaten贡献的。原始代码可以在这里找到。
ApacheCN_飞龙
2024/06/26
4260
相关推荐
基于ResNet和Transformer的场景文本识别
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档