注意力Transformer

注意力

注意力分为两步:

  1. 计算注意力分布 α \alpha α
    在这里插入图片描述
  • 其实就是,打分函数进行打分,然后softmax进行归一化
  1. 根据 α \alpha α来计算输入信息的加权平均(软注意力)
    • 其选择的信息是所有输入向量在注意力下的分布

在这里插入图片描述

  • 打分函数
    在这里插入图片描述
  • 只关注某一个输入向量, 叫作硬性注意力( Hard Attention)
    在这里插入图片描述
  • 本质上,从所有输入向量里面选一个向量(最具代表性)

键值对注意力

在这里插入图片描述

  • Q-V 和 Q-KV结构对比
    在这里插入图片描述
  • 机器翻译的例子
    在这里插入图片描述
  • CNN中的注意力
    在这里插入图片描述
    在这里插入图片描述

各种注意力的定义

在这里插入图片描述
多头注意力:

与其只使用单独一个注意力汇聚, 我们可以用独立学习得到的h组不同的 线性投影(linear projections)来变换查询、键和值。然后,这h组变换后的查询、键和值将并行地送到注意力汇聚中。 最后,将这h个注意力汇聚的输出拼接在一起, 并且通过另一个可以学习的线性投影进行变换, 以产生最终输出。这称为多头注意力。

  • 对于h个注意力汇聚输出,每一个注意力汇聚都被称作一个头(head)。

自注意力:在深度学习中,经常使用卷积神经网络(CNN)或循环神经网络(RNN)对序列进行编码。

有了注意力机制之后,我们将词元序列输入注意力池化中, 以便同一组词元同时充当查询、键和值。 具体来说,每个查询都会关注所有的键-值对并生成一个注意力输出。 由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention)

位置编码:

  • 在处理词元序列时,循环神经网络是逐个的重复地处理词元的, 而自注意力则因为并行计算而放弃了顺序操作。
  • 为了使用序列的顺序信息,通过在输入表示中添加 位置编码(positional encoding)来注入绝对的或相对的位置信息
  • 位置编码可以通过学习得到也可以直接固定得到。

在位置嵌入矩阵P中, 行代表词元在序列中的位置列代表位置编码的不同维度

  • Layer Normalization
  • 残差连接
  • Masked mutil-head attetion
    • mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。
    • 其中,padding mask 在所 有的 scaled dot-product attention 里面都需要用到
    • sequence mask 只有在 decoder的 self-attention 里面用到,sequence mask 是为了使得 decoder 不能看见未来的信息。

Transformer

在这里插入图片描述
在这里插入图片描述

  • 细节详解

克服的问题:

  1. RNNs的序列模型,串行编码具有天然的顺序属性,但是不能并行
  2. CNN可以并行,但是是局部连接,且无顺序属性
  • 解决:用CNN去代替RNN,让CNN有重合部分达到连续的效果

在这里插入图片描述
在这里插入图片描述

self-attendtion

  • 把一个输入的向量拆成3个特征图,qkv是三个不同的权重矩阵
    在这里插入图片描述
    在这里插入图片描述
  • 记住这句核心话,拿着每个query去对每个key做attendtion运算
    在这里插入图片描述
  • α \alpha α权重要归一化
    在这里插入图片描述
  • 计算得到QKV矩阵
    在这里插入图片描述
    在这里插入图片描述

Demo to understand

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Transformer Encoder

  • 位置编码
  • 层归一化
  • 直连边
  • 逐位的FNN
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 当使用神经网络来处理一个变长的向量序列时,我们通常可以使用卷积网络循环网络进行编码来得到一个相同长度的输出向量序列。
    在这里插入图片描述
  • 如何建立非局部(Non-local)的依赖关系 -> 自注意力模型

在这里插入图片描述


Code

在这里插入图片描述

class PositionalEncoding(nn.Module):
    """
    compute sinusoid encoding.
    """
    def __init__(self, d_model, max_len, device):
        """
        constructor of sinusoid encoding class

        :param d_model: dimension of model
        :param max_len: max sequence length
        :param device: hardware device setting
        """
        super(PositionalEncoding, self).__init__()

        # same size with input matrix (for adding with input matrix)
        self.encoding = torch.zeros(max_len, d_model, device=device)
        self.encoding.requires_grad = False  # we don't need to compute gradient

        pos = torch.arange(0, max_len, device=device)
        pos = pos.float().unsqueeze(dim=1)
        # 1D => 2D unsqueeze to represent word's position

        _2i = torch.arange(0, d_model, step=2, device=device).float()
        # 'i' means index of d_model (e.g. embedding size = 50, 'i' = [0,50])
        # "step=2" means 'i' multiplied with two (same with 2 * i)

        self.encoding[:, 0::2] = torch.sin(pos / (10000 ** (_2i / d_model)))
        self.encoding[:, 1::2] = torch.cos(pos / (10000 ** (_2i / d_model)))
        # compute positional encoding to consider positional information of words

    def forward(self, x):
        # self.encoding
        # [max_len = 512, d_model = 512]

        batch_size, seq_len = x.size()
        # [batch_size = 128, seq_len = 30]

        return self.encoding[:seq_len, :]
        # [seq_len = 30, d_model = 512]
        # it will add with tok_emb : [128, 30, 512]         

在这里插入图片描述

class MultiHeadAttention(nn.Module):

    def __init__(self, d_model, n_head):
        super(MultiHeadAttention, self).__init__()
        self.n_head = n_head
        self.attention = ScaleDotProductAttention()
        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_concat = nn.Linear(d_model, d_model)

    def forward(self, q, k, v, mask=None):
        # 1. dot product with weight matrices
        q, k, v = self.w_q(q), self.w_k(k), self.w_v(v)

        # 2. split tensor by number of heads
        q, k, v = self.split(q), self.split(k), self.split(v)

        # 3. do scale dot product to compute similarity
        out, attention = self.attention(q, k, v, mask=mask)
        
        # 4. concat and pass to linear layer
        out = self.concat(out)
        out = self.w_concat(out)

        # 5. visualize attention map
        # TODO : we should implement visualization

        return out

    def split(self, tensor):
        """
        split tensor by number of head

        :param tensor: [batch_size, length, d_model]
        :return: [batch_size, head, length, d_tensor]
        """
        batch_size, length, d_model = tensor.size()

        d_tensor = d_model // self.n_head
        tensor = tensor.view(batch_size, length, self.n_head, d_tensor).transpose(1, 2)
        # it is similar with group convolution (split by number of heads)

        return tensor

    def concat(self, tensor):
        """
        inverse function of self.split(tensor : torch.Tensor)

        :param tensor: [batch_size, head, length, d_tensor]
        :return: [batch_size, length, d_model]
        """
        batch_size, head, length, d_tensor = tensor.size()
        d_model = head * d_tensor

        tensor = tensor.transpose(1, 2).contiguous().view(batch_size, length, d_model)
        return tensor

在这里插入图片描述

class ScaleDotProductAttention(nn.Module):
    """
    compute scale dot product attention

    Query : given sentence that we focused on (decoder)
    Key : every sentence to check relationship with Qeury(encoder)
    Value : every sentence same with Key (encoder)
    """

    def __init__(self):
        super(ScaleDotProductAttention, self).__init__()
        self.softmax = nn.Softmax(dim=-1)

    def forward(self, q, k, v, mask=None, e=1e-12):
        # input is 4 dimension tensor
        # [batch_size, head, length, d_tensor]
        batch_size, head, length, d_tensor = k.size()

        # 1. dot product Query with Key^T to compute similarity
        k_t = k.transpose(2, 3)  # transpose
        score = (q @ k_t) / math.sqrt(d_tensor)  # scaled dot product

        # 2. apply masking (opt)
        if mask is not None:
            score = score.masked_fill(mask == 0, -10000)

        # 3. pass them softmax to make [0, 1] range
        score = self.softmax(score)

        # 4. multiply with Value
        v = score @ v

        return v, score

在这里插入图片描述

class LayerNorm(nn.Module):
    def __init__(self, d_model, eps=1e-12):
        super(LayerNorm, self).__init__()
        self.gamma = nn.Parameter(torch.ones(d_model))
        self.beta = nn.Parameter(torch.zeros(d_model))
        self.eps = eps

    def forward(self, x):
        mean = x.mean(-1, keepdim=True)
        var = x.var(-1, unbiased=False, keepdim=True)
        # '-1' means last dimension. 

        out = (x - mean) / torch.sqrt(var + self.eps)
        out = self.gamma * out + self.beta
        return out

在这里插入图片描述

class PositionwiseFeedForward(nn.Module):

    def __init__(self, d_model, hidden, drop_prob=0.1):
        super(PositionwiseFeedForward, self).__init__()
        self.linear1 = nn.Linear(d_model, hidden)
        self.linear2 = nn.Linear(hidden, d_model)
        self.relu = nn.ReLU()
        self.dropout = nn.Dropout(p=drop_prob)

    def forward(self, x):
        x = self.linear1(x)
        x = self.relu(x)
        x = self.dropout(x)
        x = self.linear2(x)
        return x

在这里插入图片描述

class EncoderLayer(nn.Module):

    def __init__(self, d_model, ffn_hidden, n_head, drop_prob):
        super(EncoderLayer, self).__init__()
        self.attention = MultiHeadAttention(d_model=d_model, n_head=n_head)
        self.norm1 = LayerNorm(d_model=d_model)
        self.dropout1 = nn.Dropout(p=drop_prob)

        self.ffn = PositionwiseFeedForward(d_model=d_model, hidden=ffn_hidden, drop_prob=drop_prob)
        self.norm2 = LayerNorm(d_model=d_model)
        self.dropout2 = nn.Dropout(p=drop_prob)

    def forward(self, x, src_mask):
        # 1. compute self attention
        _x = x
        x = self.attention(q=x, k=x, v=x, mask=src_mask)
        
        # 2. add and norm
        x = self.dropout1(x)
        x = self.norm1(x + _x)
        
        # 3. positionwise feed forward network
        _x = x
        x = self.ffn(x)
      
        # 4. add and norm
        x = self.dropout2(x)
        x = self.norm2(x + _x)
        return x
class Encoder(nn.Module):

    def __init__(self, enc_voc_size, max_len, d_model, ffn_hidden, n_head, n_layers, drop_prob, device):
        super().__init__()
        self.emb = TransformerEmbedding(d_model=d_model,
                                        max_len=max_len,
                                        vocab_size=enc_voc_size,
                                        drop_prob=drop_prob,
                                        device=device)

        self.layers = nn.ModuleList([EncoderLayer(d_model=d_model,
                                                  ffn_hidden=ffn_hidden,
                                                  n_head=n_head,
                                                  drop_prob=drop_prob)
                                     for _ in range(n_layers)])

    def forward(self, x, src_mask):
        x = self.emb(x)

        for layer in self.layers:
            x = layer(x, src_mask)

        return x
class DecoderLayer(nn.Module):

    def __init__(self, d_model, ffn_hidden, n_head, drop_prob):
        super(DecoderLayer, self).__init__()
        self.self_attention = MultiHeadAttention(d_model=d_model, n_head=n_head)
        self.norm1 = LayerNorm(d_model=d_model)
        self.dropout1 = nn.Dropout(p=drop_prob)

        self.enc_dec_attention = MultiHeadAttention(d_model=d_model, n_head=n_head)
        self.norm2 = LayerNorm(d_model=d_model)
        self.dropout2 = nn.Dropout(p=drop_prob)

        self.ffn = PositionwiseFeedForward(d_model=d_model, hidden=ffn_hidden, drop_prob=drop_prob)
        self.norm3 = LayerNorm(d_model=d_model)
        self.dropout3 = nn.Dropout(p=drop_prob)

    def forward(self, dec, enc, trg_mask, src_mask):    
        # 1. compute self attention
        _x = dec
        x = self.self_attention(q=dec, k=dec, v=dec, mask=trg_mask)
        
        # 2. add and norm
        x = self.dropout1(x)
        x = self.norm1(x + _x)

        if enc is not None:
            # 3. compute encoder - decoder attention
            _x = x
            x = self.enc_dec_attention(q=x, k=enc, v=enc, mask=src_mask)
            
            # 4. add and norm
            x = self.dropout2(x)
            x = self.norm2(x + _x)

        # 5. positionwise feed forward network
        _x = x
        x = self.ffn(x)
        
        # 6. add and norm
        x = self.dropout3(x)
        x = self.norm3(x + _x)
        return x
class Decoder(nn.Module):
    def __init__(self, dec_voc_size, max_len, d_model, ffn_hidden, n_head, n_layers, drop_prob, device):
        super().__init__()
        self.emb = TransformerEmbedding(d_model=d_model,
                                        drop_prob=drop_prob,
                                        max_len=max_len,
                                        vocab_size=dec_voc_size,
                                        device=device)

        self.layers = nn.ModuleList([DecoderLayer(d_model=d_model,
                                                  ffn_hidden=ffn_hidden,
                                                  n_head=n_head,
                                                  drop_prob=drop_prob)
                                     for _ in range(n_layers)])

        self.linear = nn.Linear(d_model, dec_voc_size)

    def forward(self, trg, src, trg_mask, src_mask):
        trg = self.emb(trg)

        for layer in self.layers:
            trg = layer(trg, src, trg_mask, src_mask)

        # pass to LM head
        output = self.linear(trg)
        return output

ViT & Swin Transformer

在这里插入图片描述
在这里插入图片描述

  • ViT 与 NLP的不同
    在这里插入图片描述
    在这里插入图片描述
  • 4 stage的切分,这是在干嘛呢?
    • 感受野在不断的扩大,局部到全局,使Transfomer有层级结构
      在这里插入图片描述
      在这里插入图片描述

Shifted Window

在这里插入图片描述

  • 旋转取代滑动

在这里插入图片描述

  • shift + mask 取代 padding + mask
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

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

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

相关文章

Docker 设置国内镜像源

Docker 镜像加速 国内从 DockerHub 拉取镜像有时会遇到网络问题,此时可以配置国内的镜像加速来下载。Docker 官方和国内很多云服务商都提供了国内加速器服务,例如如下: 科大镜像:https://docker.mirrors.ustc.edu.cn/网易&#…

ATA-4014高压功率放大器驱动超声马达测试应用

ATA-4014 高压功率放大器简介 ATA-4014是一款理想的可放大交、直流信号的单通道高压功率放大器。最大输出160Vp-p(80Vp)电压,452Wp功率,可以驱动高压功率型负载。电压增益数控可调,一键保存常用设置,为您提…

抽象轻松js

重复声明 经过了这么久,对声明变量应该差不多了解了,再加上之前了解的作用域 我们现在开始如果科学的使用重复声明 先复习一边(遍)作用域 var的作用域是全局 let、const的作用域是花括号 了解这点,那么科学使用重复声明就是合理使用作用…

C++11之atomic原子操作

atomic介绍 多线程间是通过互斥锁与条件变量来保证共享数据的同步的,互斥锁主要是针对过程加锁来实现对共享资源的排他性访问。很多时候,对共享资源的访问主要是对某一数据结构的读写操作,如果数据结构本身就带有排他性访问的特性&#xff0c…

如何用chatGPT赚钱?

赚钱思路 1)初级-账号 对于新事物的出现,很多人对此都是抱着一个看热闹的态度,大家对于这个东西的整体认知水平是很低的! 所以这个时候的思路就是快速去抢占市场,去各个平台发一些和ChatGPT相关的视频和文章去抢占市…

css、js(vue)进行textarea自适应高度(超详细说明)

文章目录 需求——如下图一、纯css 的自适应高度(有问题,不推荐)1.css代码2. html代码3. 代码截图说明4. 效果和会出现的问题 二、js 的自适应高度0.思路1.代码1. css代码2. html代码3. js代码 2.代码说明3.注意点导致的问题(0&am…

GP05丨多因子IC对冲

量化策略开发,高质量社群,交易思路分享等相关内容 大家好,今天我们分享股票社群第5期量化策略——多因子IC对冲。 在前几期中,我们分享了GP01多因子、ETF轮动策略及Plus版本、网格等等。本期我们继续分享多因子策略。 策略背景与…

【P32】JMeter While 控制器(While Controller)

文章目录 一、While 控制器(While Controller)参数说明二、测试计划设计2.1、变量2.2、函数2.2.1、groovy脚本2.2.2、jex13脚本2.2.3、js脚本 一、While 控制器(While Controller)参数说明 可以对部分逻辑按变量条件进行循环迭代…

CentOS7编译安装Python3.10(含OpenSSL1.1.1安装),创建虚拟环境,运行Django项目(含sqlite版本报错)

文章目录 1、CentOS安装OpenSSL1.1.1(前置环境)2、CentOS安装 Python 3.103、创建虚拟环境4、运行Django项目 1、CentOS安装OpenSSL1.1.1(前置环境) 编译安装Python3.10时需要openssl1.1.1 查看当前版本 & 删除openssl1.0 …

代码随想录算法训练营第三十九天 | 力扣 62.不同路径, 63. 不同路径 II

62.不同路径 题目 62. 不同路径 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多…

C++数据结构:二叉树之一(数组存储)

文章目录 前言一、二叉树的基本定义二、二叉树的基本性质三、二叉树的存储(数组)总结原创文章,未经许可,禁止转载 前言 树是一种非线性数据结构,它由若干个节点和边组成。每个节点都有一个值,而边则表示节…

day17 - 用形状包围图像

在进行图像轮廓提取时,有的情况下不需要我们提取出精确的轮廓,只要提取出一个接近于轮廓的近似多边形,就可以满足后续的操作。 本期我们来学习如何通过设置参数来找出图像的近似多边形。 完成本期内容,你可以: 了解…

算法基础学习笔记——⑨C++STL使用技巧

✨博主:命运之光 ✨专栏:算法基础学习 目录 ✨CSTL简介 ✨CSTL使用技巧 前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持! ✨CSTL简介 vector变长数组,倍增的思想//系统为…

STM32单片机(三)第一节:GPIO输出

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要…

驱动开发:内核读写内存浮点数

如前所述,在前几章内容中笔者简单介绍了内存读写的基本实现方式,这其中包括了CR3切换读写,MDL映射读写,内存拷贝读写,本章将在如前所述的读写函数进一步封装,并以此来实现驱动读写内存浮点数的目的。内存浮…

MyBatis操作数据库表和动态SQL的使用

目录 1.MyBatis开发环境的搭建和测试 2.MyBatis基本操作 2.0 准备工作 2.1 新增操作 2.2 删除、修改、查询操作 2.3 #{param} 和 ${param}的使用和区别 2.4 实体对象属性和数据库字段名称不同时如何映射? 3. MyBatis多表查询 3.0 准备工作 3.1 一对一的表…

ELK企业级日志分析系统

ELK概述 为什么要使用 ELK 日志主要包括系统日志、应用程序日志和安全日志。系统运维和开发人员可以通过日志了解服务器软硬件信息、检查配置过程中的错误及错误发生的原因。经常分析日志可以了解服务器的负荷,性能安全性,从而及时采取措施纠正错误。 往…

切比雪夫不等式,大数定律及极限定理。

一.切比雪夫不等式 1.定理 若随机变量X的期望EX和方差DX存在,则对任意ε > 0,有   P{ |X - EX| > ε } < DX/ε2 或 P{ |X - EX| < ε } > 1 - DX/ε2 2.解析定理 ①该定理对 X 服从什么分布不做要求&#xff0c;仅EX DX存在即可。 ②“| |” 由于X某次…

软件测试炸了,作为从业者,你做好准备了吗?

软件测试行业已经发生很大变化&#xff0c;你跟上变化了吗&#xff1f; 岗位少不可怕&#xff0c;要求越来越高也不可怕&#xff0c;可怕的是&#xff0c;软件测试行业已经发生巨变&#xff0c;而你却原地踏步&#xff01;目前一线大厂更多倾向于招收测试开发&#xff0c;或者…

自学网络安全(黑客),一般人我劝你还是算了吧

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习 我在之前的回答中&#xff0c;我都一再强调不要以编程为基础再开始学习网络安全&#xff0c;一般来说&#xff0c;学习编程不但学习周期长&#xff0c;而且…