Martins P., Marinho Z. and Martins A. \(\infty\)-former: Infinite Memory Transformer. arXiv preprint arXiv:2109.00301, 2021.

在transformer中引入一种长期记忆机制.

主要内容

假设\(X \in \mathbb{R}^{L \times d}\), 即每一行\(x_i\)代表一个token对应的特征.

Attention需要进行如下的步骤:

\[Q = XW^Q, K = X W^K, V = XW^V, \\
Z = \mathrm{softmax}(\frac{QK^T}{\sqrt{d}})V.
\]

为了符号简易起见, 我们不考虑multi-head的情形, 下面的思想可以直接应用之.

我们知道, 可以通过径向基函数来逼近任意的连续函数:

\[\sum_{k} b_k \psi_k (t) \rightarrow f(t).
\]

现在, 我们令\(t_i = \frac{i}{L}\), 即对\(L\)个tokens冠以时序, \(X\)的每一列都可以看成一个特殊的\(f_j(t)\)的位于\(t_i, i=0,1,\cdots, L-1\)处的值.

给定\(N\)个基函数\(\psi_k (t), k=0,1,\cdots, N-1\), 我们要通过求解系数\(\bm{b}_j = [b_{j0}, b_{j1},\cdots b_{j,N-1}]^T\)来逼近\(f_j\)(\(X\)的第\(j\)列).

设\(\Psi \in \mathbb{R}^{N \times L}, \Psi_{ki}=\psi_{k}(t_i)\), \(B \in \mathbb{R}^{d \times N}, B_{jk} = b_{jk}\).

作者通过岭回归来求解系数\(b\):

\[B = \arg \min_{B} \|B \Psi - X^T\|_F^2 + \lambda \|B\|_F^2,
\]

其显示表达式为:

\[B = X^T\Psi^T(\Psi\Psi^T + \lambda I)^{-1}.
\]

\[X^T \approx B\Psi \rightarrow x_i \approx B \psi (t_i).
\]

现在我们用\(\tilde{X} := \Psi^T B^T\)来代替\(X\), 则

\[K = \tilde{X} W^K = \Psi^TB^TW^K, \tilde{V} = \tilde{X}W^V = \Psi^TB^TW^V.
\]

注意, 我们并不对\(Q\)进行替换, 因为这个只是用作长期的记录用, Q每次重新计算.

对于每个\(q_i\), 我们构建一个其关于\(t\)的密度函数\(p_i(t)\), 文中假设其满足高斯分布:

\[\mathcal{N}(t; \mu_i; \sigma_i^2).
\]

\(\mu_i, \sigma_i^2\)分别通过如下估计:

\[\mu_i = \mathrm{sigmoid} (w_{\mu}^T K q_i)
=\mathrm{sigmoid} (w_{\mu}^T B^TW^K q_i), \\
\sigma^2_i = \mathrm{softplus} (w_{\sigma}^T K q_i)
=\mathrm{softplus} (w_{\sigma}^T B^TW^K q_i). \\
\]

注意最后令\(w^T\Psi^T = w^T\)既然\(\Psi\)是事先确定的.

我们知道

\[\mathrm{softmax}(\frac{Kq_i}{\sqrt{d}})
\]

实际上求解的是一个离散化的\(p_i(t)\), 即\(q_i\)和\(k_j\)的相合程度, 而

\[\mathrm{softmax}(\frac{Kq_i}{\sqrt{d}})^TV
\]

实际上就是求解期望

\[\mathbb{E}_{p_i}[v(t)].
\]

现在我们近似了一个连续的\(p_i(t)\), 也可以通过这种方式得到最后的\(z_i\):

\[\mathbb{E}_{p_i}[v(t)]
=\mathbb{E}_{p_i}[\psi^T(t)B^TW^V]
=\mathbb{E}_{p_i}[\psi^T(t)]B^TW^V.
\]

当我们取\(\psi\)为高斯径向基函数的时候, 上述是由显示解的.

现在来剖析一下, 好在哪里?

原本的\(K\)是\(L\times d\)的, 现在由于我们只需要计算\(B^TW\), 故实际上只有\(N \times d\), 我们可以选取很大的\(L\)但是选择较小的\(N\)来避免较高的复杂度.

如何扩展?

难不成每一次都要重新计算\(B\)? 倘若真的是这样就谈不上是长期记忆了.

作者采取了一种比较巧的方法, 实际上, 现在的\(B\psi(t)\)可以看成是一个\(d\)维的向量函数.

我们首先将其进行压缩至\([0, \tau], \tau \in (0, 1)\):

\[B\psi(t /\tau),
\]

如此一来, 整个函数的能量集中在\([0, \tau]\)中, 我们可以用剩下的\((\tau, 1]\)来放置新的\(X\).

我们首先从\([0, \tau]\)中采样\(M\)个点\(t_0, \cdots, t_{M-1}\), 并得到:

\[X_{past} = [x_0, \cdots, x_{M-1}]^T \in \mathbb{R}^{M \times d}, x_m=\psi^T(t_m/\tau)B^T.
\]

加上新的\(X_{new}\), 我们有

\[X = [X_{past}^T, X_{new}^T]^T \in \mathbb{R}^{(M + L) \times d},
\]

对\(X\)按照上面的逻辑重新估计\(B\)即可更新记忆.

关于如何采样这\(M\)个点, 作者提了一种sticky memories的方法, 将其与密度函数联系在一起, 便不细讲了.

实验细节

在看这篇论文的时候, 困扰我的就是这个径向基函数是怎么选的?

举一个作者在Language Modeling中的例子便可:

选取150个高斯径向基函数\(\mathcal{N}(t;\mu, \sigma^2)\), 其中

\(\mu\)从\([0, 1]\)中均匀采样, \(\sigma \in \{0.01, 0.05\}\).

还有用KL散度防止一般化就不讲了. 感觉本文有趣的点就是压缩这个地方, 还有对\(\Psi\)的处理.

随机推荐

  1. day09 orm查询优化相关

    day09 orm查询优化相关 今日内容概要 orm字段相关补充 orm查询优化相关 orm事务操作 图书管理系统练习 今日内容详细 orm事务操作 """ 事务:ACI ...

  2. 复制virtualbox虚拟硬盘

    D:\VirtualBox\VBoxManage.exe clonevdi F:\virtualbox\rac1\rac1.vdi F:\virtualbox\rac2\rac2.vdi 虚拟机软件安 ...

  3. OSGI与Spring结合开发web工程

    简介: 作为一个新的事实上的工业标准,OSGi 已经受到了广泛的关注, 其面向服务(接口)的基本思想和动态模块部署的能力, 是企业级应用长期以来一直追求的目标.Spring 是一个著名的 轻量级 J2 ...

  4. 最基础的SSM框架整合篇

    一.简单理解 Spring.Spring MVC和MyBatis的整合主要原理就是将我们在单独使用Spring MVC和MyBatis过程中需要自己实例化的类都交由Ioc容器来管理,过程分为两步: 第 ...

  5. 【MySQL】查询不在表中的数据

    1.方法一(仅适用单个字段):使用 not in ,比较容易理解,缺点是效率低 如:select A.ID from A where A.ID not in (select ID from B): 2 ...

  6. 机器学习——sklearn中的API

    import matplotlib.pyplot as pltfrom sklearn.svm import SVCfrom sklearn.model_selection import Strati ...

  7. Log4j 被曝核弹级漏洞,开发者炸锅了!

    大家好,我是鱼皮,开门见山,知名的开源项目 Apache Log4j 出事了! 2021 年 12 月 9 日,该项目被曝存在 严重安全漏洞 ,攻击者只需要向目标机传入一段特殊代码,就能触发漏洞,自由 ...

  8. JavaOOP对象和封装

    对象: 前言: 在程序员眼中,世界万物皆为对象.世界上有两种人,一种是懂二进制的人,一种就是不懂二进制的人. 面向对象设计的过程就是抽象的过程. 步骤: 第一步:发现类 第二步:发现类的属性 第三步: ...

  9. 车载以太网第二弹|测试之实锤 -DoIP测试开发实践

    前言 车载以太网测试之实锤系列,之前我们已经从环境设备组成.被测对象组成再到测试过程和测试结果分析,分享了完整的PMA测试 .IOP测试 .TC8中的TCP/IP协议一致性测试 .也分享了1000BA ...

  10. Java值引用和对象引用区别Demo

    转自:http://blog.csdn.net/gundsoul/article/details/4927404 以前就知道JAVA对象分对象引用和值引用,并且还知道8种基础数据类型,即引用时是值引用 ...