在 FFN 层中,有几个常见的激活函数,这次我们尝试梳理它们。

GLU 变体公式

激活{FFNGLU(x,W,V,W2)=(σ(xW)xV)W2FFNBilinear(x,W,V,W2)=(xWxV)W2FFNReGLU(x,W,V,W2)=(max(0,xW)xV)W2FFNGEGLU(x,W,V,W2)=(GELU(xW)xV)W2FFNSwiGLU(x,W,V,W2)=(Swish1(xW)xV)W2 公式{ReGLU(x,W,V,b,c)=max(0,xW+b)(xV+c)GEGLU(x,W,V,b,c)=GELU(xW+b)(xV+c)SwiGLU(x,W,V,b,c,β)=Swishβ(xW+b)(xV+c) 基础{ReLU(x)=max(x,0)GeLU(x)=0.5x[1+erf(x2)]sigmoid(x)=11+extanh(x)=exexex+exerf(x)=2π0xet2dtSwish(x)=xsigmoid(x)SwiGLU(x1,x2)=x2Swish(x1)GeGLU(x1,x2)=x2GeLU(x1)

图片来源:论文 GLU Variants Improve Transformer

说明: 表示逐元素相乘; σ 为 sigmoid 激活;基础组中的 x 0 为向量(故加粗)。

为什么需要激活函数

在神经网络中,我们对神经元进行线性变换 z=Wx+b 后,通过激活函数 a=f(z) 作为下一层函数的输入,反映该函数是否被激活。

激活函数赋予了神经网络非线性,如果没有激活函数,神经网络就是多个线性换堆叠,对于一个两层的网络 z2=W2(W1x+b1)+b2 来说

其可以写成 z2=W1W2x+W2b1+b2=Wx+b 这仍然是一个线性变换。

什么函数可以作为激活函数

在解答这个问题之前,我们看看激活函数参与了什么过程:

1.它参与了神经网络的非线性变换
2.它参与了反向传播

因此,它必须是一个非线性函数(条件 1 ),他必须可导(或者仅在有限点不可导)。

此外,它最好计算的效率高,梯度性质较好,输出范围适当,且足够平滑。

很遗憾,下面的条件很难一起满足。

在接下来的内容中,我们根据是否存在 来区分门控函数与非门控函数,因为门控函数定义为

y=zg(a)

其中:

  • a :用来计算“门”的那一路输入;
  • g(a) :门控信号;
  • z :真正要通过的信息;
  • :逐元素相乘。

非门控函数

RELU

最简单的函数,其输出范围 [0,+] ,当 x=0 时,函数不可导,需要定义其导数为 0 或者 1

当输入长期小于 0 ,该函数可能不再激活 ,称为 Dead ReLU 问题

ReLU.png

函数如图所示

LeakyReLU

为了解决ReLU在负半轴导数为0的情况,我们对其在负半轴做一下修改

LeakyReLU(x)={xif x>0αxif x0

其中 α 是一个极小的正数(例如 0.01

图就不放了。

sigmoid

其易于求导,设 sigmoid 函数为 σ(x) 则导数为 σ(x)=σ(x)(1σ(x))

x 很大或者很小时,函数导数 σ(x) 接近 0 ,此时 x 无论变化多少,函数变化不大,反向传播时参数更新极小甚至不更新,发生梯度饱和。

函数范围变成 (0,1)

Sigmoid.png

tanh

其导数为 tanh(x)=1tanh2(x) ,输出范围变成了 (1,1) 但是计算量高于 ReLU 函数。

Tanh.png

门控函数

GeLU

GeLU 输入和门控都取决于 x ,所以也可以认为不是门控函数。

表示逐元素相乘, erf函数定义如下

erf(z)=2π0zet2dt

其与正态分布损失函数有关

0.5[1+erf(x2)]=Φ(x)=P(Zx)

其中 ZN(0,1) ,因此GeLU 还可以写作 GeLU(x)=xΦ(x) ,其函数图像如图所示。

GeLU.png

Swish与SiLU

Swish 与 SiLU 输入和门控都取决于 x ,所以也可以认为不是门控函数。

Swish(x)=xsigmoid(βx)

β=1 时,称为 SiLU ,更通常地,如果说明 Swish 但没有指明 β ,则可以默认指的是 β=1 的情况

Swish.png

GeGLU 与 SwiGLU

将 GeLU 右边的门控函数套娃成 GeLU,即得到 GeGLU

将 GeLU 右边的门控函数套娃成 Swish,即得到 SwiGLU

GeGLU.png

SwiGLU.png

由于就是直接将 GeLU 套娃,对函数本身没有什么好说的,我们回到 FFN 层来区别三者

GeLU,GeGLU,SwiGLU in FFN

在 FFN 层中,三者公式如下,其中 GeGLU,SwiGLU 需要额外一个可学习的权重矩阵

GELU FFN:

FFNGELU(x)=GELU(xW1)W2

GeGLU FFN:

FFNGeGLU(x)=[(xWin)GELU(xWgate)]Wout

SwiGLU FFN:

FFNSwiGLU(x)=[(xWin)Swish(xWgate)]Wout

顺带一说,对于一个长度为 len*d1 的输入,首先经过三个 d1*d1 的注意力矩阵,经过缩放,残差链接与 LN 后,进入FFN层,此时会先遇到一个维度为 d1*d2 的升维矩阵 W1 ,如果需要引入非自身门控,则还需要一个维度与之相符的矩阵 W2 ,接着需要一个降维矩阵 W3

一般来说 d2=4d1 ,则不考虑门控的FFN层参数为注意力层的 38 ,如果考虑门控就变成 4 倍了,为了保证和原来无门控的时候差不多,需要将维度 d2 变成原来 23 倍。

!!! note 注意
主流的大模型几乎清一色使用SwiGLU,FFN层无门控模型已经实质上不存在了,因此 d2=4d1 并需要让门控模型保持总参数不变这个基础也不存在了,且对于MoE 模型 ,该规则也不一定适用。

近似计算

以上函数可以近似计算,这里在面试中不太重要,因此先不更新。