论文地址:
补充:这篇论文提供了cuda代码。
整体思路以及计算方式
整体思路是利用卷积的方式进行序列建模,看完之后感觉非常赞,这里详细理一下计算思路。
步骤一,simple conv1d,序列建模的方式。
以一维序列x0,…,xn−1为例,利用部分和(kernel值为1的卷积)的形式得到输出:
oi=j=αil∑αirxj 其中αil,αir为oi对应的边界值,注意上式的计算复杂度太高,但是可以构造前缀和降低计算复杂度:
{S0=0Si=Si−1+xi,1≤i≤n. 那么:
oi=Sair−Sail−1 那么现在的问题就是如何计算αir,αir,这在步骤二中可以解决。
步骤二,确定上界和下界。
首先构造可学习的参数:
a~i{l,r}=σ(f{l,r}(xi))∈[0,1] 然后利用下式计算边界:
ailair=i−a~il⋅lmax=i+a~ir⋅rmax 其中lmax,rmax是超参。现在的一个问题是,ail,air不一定是整数,但是我们只能计算整数下标的Sk,k∈Z,这一点利用插值即可解决:
Sail−1Sair=γl⋅S⌊ail⌋−1+(1−γl)⋅S⌈ail⌉−1=(1−γr)⋅S⌊air⌋+γr⋅S⌈air⌉ 步骤三:归一化和鲁棒性。
这里作者为了让算法work,增加了归一化和dropout:
o~i=oi⋅(lmax+rmax+11) 步骤四:
之前讨论的的都是一维的情形,然后作者将其推广到d维度时候发现性能一般,这里感觉主要问题是映射a~i{l,r}=σ(f{l,r}(xi))∈[0,1]不太稳定,为了缓解这点,作者将d维拆成h×(d/h),每d/h个特征共享一个αi{l,r},并且由这d/h共同确定。
时间复杂度
因为是查找表,所以时间复杂度是O(nd)。
代码
简评
非常赞的一个思路,其作用机理优点类似于window attention,其中window范围由输入确定。