[Linformer]论文实现:Linformer: Self-Attention with Linear Complexity

2023-12-15 10:20

本文主要是介绍[Linformer]论文实现:Linformer: Self-Attention with Linear Complexity,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、完整代码
    • 二、论文解读
      • 2.1 介绍
      • 2.2 Self-Attention is Low Rank
      • 2.3 模型架构
      • 2.4 结果
    • 三、整体总结

论文:Linformer: Self-Attention with Linear Complexity
作者:Sinong Wang, Belinda Z. Li, Madian Khabsa, Han Fang, Hao Ma
时间:2020

模型结构较于简单,证明有点难,有时间可以做一下文章的证明分析;

一、完整代码

这里我们使用python代码进行实现

# 完整代码在这里
# 模型结构较于简单,有时间再弄

二、论文解读

2.1 介绍

这是一篇介绍transformer的优化模型的论文,其对普通的transformer模型进行了优化,把时间复杂度和空间复杂度都从 O ( n 2 ) O(n^2) O(n2)降低为了 O ( n ) O(n) O(n);论文推出的模型叫Linformer,其主要思想利用到了两个思想,一个是the distributional Johnson–Lindenstrauss lemma, the Eckart–Young–Mirsky Theorem;这两个思想一同证实了利用降维去构造一个低秩矩阵来降低复杂度的可行性;

为什么要改进transformer模型:计算量太大,价格昂贵,操作复杂度为 O ( n 2 ) O(n^2) O(n2);部署困难,并不容易进行推理;

目前的其他降维方法Sparse transformer利用Sparse matrixReformer利用locally-sensitive hashing (LSH),并且只有序列长度大于2048的时候才有用;

不同模型架构方法对比如下:

相比于图中的模型,Linformer在复杂度和操作上是最佳的;

在这里提一下Transformer的自注意力机制,这都是非常基础了;

提高transformer的效率有很多种办法,下面简单介绍几种:

Mixed Precision:使用半精度或混合精度表示,即采用量化的方式加快计算;

Knowledge Distillation:和DistillBERT一样,利用学生模型去学习教师模型的分布预测;

Sparse Attention:只计算对角线部分的注意力权重;

该技术通过在上下文映射矩阵P中添加稀疏性来提高自我注意的效率。例如,sparse transformer只计算矩阵P的对角线附近的Pij(而不是所有的Pij)。同时,block-wise self-attentionP划分为多个块,只计算所选块内的Pij。然而,这些技术也遭受了很大的性能下降,同时只有有限的额外加速,即下降2%,加速20%。

LSH Attention:操作复杂,有效果但是有限制;

Locally-sensitive hashing(LSH)注意在计算点积注意时采用了多轮哈希方案,在理论上将自注意复杂度降低到O(n log(n))。然而,在实践中,它们的复杂度项有一个很大的常数1282,并且只有当序列长度非常长时,它才比普通的变压器更有效。

Improving Optimizer Efficiency:没注意过,不出名;

Microbatching将一批分成小的微批(可以放入内存),然后通过梯度积累分别向前和向后运行。Gradient checkpointing仅通过缓存一个图层子集的激活来节省内存。在从最新的检查点进行反向传播期间,将重新计算未缓存的激活。这两种技术都可以利用时间来换取内存,而且都不能加快推理的速度。

2.2 Self-Attention is Low Rank

如标题,这节主要证明了self-attention其实是一个低秩矩阵;

作者使用了两个预训练的transformer模型,RoBERTa-baseRoBERTa-large,前者是12层的模型,后者是24层的模型;

作者通过对每一层的特征值进行分解,然后做图如下,纵坐标代表归一化的累积特征值,由于序列长度是512维的,所以一个有512个特征值;

通过观察发现,当取前面128个较大的特征值时,累积特征值已经到达了95%,通过主成分可以直到,前面128个较大的特征值可以表示整体的95%的信息,所以我们可以对其使用奇异值分解的方式降低维度从而达到降低复杂度的目的;

下图是不同层次的累积贡献度的谱分布,如下:

从上图中我们可以发现:高层的谱分布比下层更倾斜,这意味着在高层,更多的信息集中在最大奇异值,导致了P的秩相较于底层较低;

这里利用两个思想,一个是the distributional Johnson–Lindenstrauss lemma, the Eckart–Young–Mirsky Theorem;前者证明出现高维矩阵是低秩矩阵这种现象是正常的,后者表示奇异值分解在相同的维度下获得低秩矩阵的绝大部分信息;而奇异值分解是相当需要计算量的,高维矩阵分解操作起来很复杂,这里论文中使用投影的方式解决了这一问题;

2.3 模型架构

直接看下面这张图,就知道作者做了什么处理:

Linear层得到了 Q , K , V Q,K,V Q,K,V后,为了降低 K , V K,V K,V的维度,其使用了投影到低维的方式,具体公式如下:

之前 Q W , K W , V W QW,KW,VW QW,KW,VW都是一个n·d_model的矩阵,在这里有 E i , F i E_i,F_i Ei,Fi都是一个k·n的矩阵,有前面的softmax变成了一个 n·k的矩阵,后者是一个k·d的矩阵,这里的空间复杂度为 O ( k n + 2 k d ) O(kn + 2kd) O(kn+2kd),把平方项降低为一次项;如果我们可以选择一个非常小的投影维数k,即kn,那么我们就可以显著地减少内存和空间消耗;

从下图,我们可以发现设置的k越小,推理速度越快;

这和预期一致;

继续优化可以采用方法

Parameter sharing between projections:即共享投影层的参数,

  • 头之间共享:在每一层中的投影矩阵 E , F E,F E,F中,我们共享两个投影矩阵 E i E_i Ei F i F_i Fi,确保在每一个头 i i i中,有 E i = E , F i = F E_i=E,F_i=F Ei=E,Fi=F
  • K , V K,V K,V之间共享:在每一层中的投影矩阵 E , F E,F E,F中,我们共享两个投影矩阵 E i E_i Ei F i F_i Fi并化为一个矩阵,确保在每一个头 i i i中,有 E i = F i = E E_i=F_i=E Ei=Fi=E
  • 层与层之间共享:在所有的层中,对于所有的头部,对于所有的键和值,都使用一个投影矩阵 E E E

Nonuniform projected dimension:不均匀投影,意思是结合不同层的低秩矩阵的秩,如上文我们可以得到高层的秩要比底层的秩要小,所以我们可以在高层设置较小的k在低层设置较大的k

General projections: 我们可以采用其他的机制来缩小维度,而不是利用一个简单的投影的方式,例如均值池化,最大池化,卷积等等方式来缩小维度代替简单投影;

2.4 结果

论文中的结果可视化如下:

接下来对结果做一些解释:

a,b两图作者做了ppl曲线来判断模型的效果,在 n = 512 n=512 n=512时,随着k的增加,模型越来越贴近standard transformer曲线,有的模型甚至超过了;在 n = 1024 n=1024 n=1024时,表现了相同的趋势,但是同时可以发现,效果是非常贴近于标准模型的;

c图中,使用了三种参数共享策略来检验模型结果,可以发现参数共享并不会产生较大的影响,所以我们可以在模型中使用参数贡献,在保存相同的效果下,减少模型的参数;

d图中随着序列长度的增加,投影维数保持不变,收敛后的最终ppl仍然保持大致相同。而且不同曲线之间的间隔大小似乎相等,说明这是线性的;

下游任务模型效果,可以发现模型效果有些甚至超过了BERTDistillBERT

从模型 n = 1024 , k = 256 n = 1024,k = 256 n=1024k=256和模型 n = 512 , k = 256 n = 512,k = 256 n=512k=256效果一致可以看出来,模型的效果由预测维度k而不是比率n/k决定;

这是推理时间效果和空间复杂度效果的对比,可以看到Linformer可以在保持效果的情况下,大大优化时间和空间复杂度;

三、整体总结

这是一篇介绍transformer的优化模型的论文,其对普通的transformer模型进行了优化,把时间复杂度和空间复杂度都从 O ( n 2 ) O(n^2) O(n2)降低为了 O ( n ) O(n) O(n);论文推出的模型叫Linformer,其主要思想利用到了两个思想,一个是the distributional Johnson–Lindenstrauss lemma, the Eckart–Young–Mirsky Theorem;这两个思想一同证实了利用降维去构造一个低秩矩阵来降低复杂度的可行性;

这篇关于[Linformer]论文实现:Linformer: Self-Attention with Linear Complexity的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/496106

相关文章

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

Spring Security 单点登录与自动登录机制的实现原理

《SpringSecurity单点登录与自动登录机制的实现原理》本文探讨SpringSecurity实现单点登录(SSO)与自动登录机制,涵盖JWT跨系统认证、RememberMe持久化Token... 目录一、核心概念解析1.1 单点登录(SSO)1.2 自动登录(Remember Me)二、代码分析三、

PyCharm中配置PyQt的实现步骤

《PyCharm中配置PyQt的实现步骤》PyCharm是JetBrains推出的一款强大的PythonIDE,结合PyQt可以进行pythion高效开发桌面GUI应用程序,本文就来介绍一下PyCha... 目录1. 安装China编程PyQt1.PyQt 核心组件2. 基础 PyQt 应用程序结构3. 使用 Q

Python实现批量提取BLF文件时间戳

《Python实现批量提取BLF文件时间戳》BLF(BinaryLoggingFormat)作为Vector公司推出的CAN总线数据记录格式,被广泛用于存储车辆通信数据,本文将使用Python轻松提取... 目录一、为什么需要批量处理 BLF 文件二、核心代码解析:从文件遍历到数据导出1. 环境准备与依赖库