深度学习基础-经典模型总结

深度学习经典模型总结

卷积神经网络

介绍下转置卷积

转置卷积(Transpose Convolution),一些地方也称为”反卷积”,在深度学习中表示为卷积的一个逆向过程,可以根据卷积核大小和输出的大小,恢复卷积前的图像尺寸,而不是恢复原始值。

举例说明一下转置卷积的定义形式:

卷积操作及转置卷积的定义

对于一个输入大小为 3 × \times × 3 的图像,卷积核大小为 2 × 2 2 \times 2 2 ×2 :

深度学习基础-经典模型总结
深度学习基础-经典模型总结
计算 输出矩阵 Y Y Y 的具体实现方法为矩阵乘法。

1)首先,将卷积核表示为 稀疏矩阵 C C C :

深度学习基础-经典模型总结
其中, 每一行向量表示在一个位置的卷积操作,0填充表示卷积核未覆盖到的区域

2)然后,将输入 X X X 展开为 列向量

深度学习基础-经典模型总结
则卷积操作可以表示为:
深度学习基础-经典模型总结
其中, 输出向量 y y y 的大小为 4 × 1 4 \times 1 4 ×1 的列向量, 改写为矩阵即为 2 × 2 2 \times 2 2 ×2 。

经过以上演示,可以看出, 转置卷积貌似是将y = C x y = Cx y =C x 中的输入输出做了互换

深度学习基础-经典模型总结
其中,C T C^T C T 表示矩阵转置,此时大小为 9 × 4 9 \times 4 9 ×4 。
即由 4 × 1 4 \times 1 4 ×1 的输入 y y y ,经过转置卷积,得到输出大小为 9 × 1 9 \times 1 9 ×1 的列向量。 注意,此时的x , y x,y x ,y 数值上已经和原来不同,只是在形状上一致。

转置卷积的具体应用

普通卷积主要用来做特征提取,倾向于压缩特征图尺寸。转置卷积主要用于对特征图进行扩张或上采样。转置卷积的代表性的应用场景如下:

  • 通过反卷积可以用来做上采样,可视化卷积的特征学习内容,用于模型可视化
  • 语义分割任务:由于需要提取输入图像的高层语义信息,网络的特征图尺寸一般会先缩小,进行聚合;此外,这类任务一般需要输出与原始图像大小一致的像素级分割结果,因而需要扩张前面得到的具有更高语义信息的特征图,这就用到了转置卷积
  • 一些物体检测、关键点检测任务,需要输出与原图像大小一致的热图
  • 图像的自编码器、变分自编码器、GNN网络等。比如用GANs生成图片,其中的generator和discriminator均采用深度学习,generator生成图片过程中采用的就是反卷积操作(当然discriminator采用卷积对generator生成的图片判别真伪)。

参考文章

; 循环神经网络

介绍下RNN

为什么需要RNN(循环神经网络)

前馈神经网络(如DNN、CNN等)可以看作一个复杂的函数,每次输入都是独立的,即网络的输出只依赖当前的输入。它们只能单独的去处理一个个的输入, 前一个输入和后一个输入是完全没有关系的。但是,某些任务需要能够更好的处理序列的信息,即前面的输入和后面的输入是有关系的。

比如,当我们在理解一句话意思时,孤立的理解这句话的每个词是不够的,我们需要处理这些词连接起来的整个序列; 当我们处理视频的时候,我们也不能只单独的去分析每一帧,而要分析这些帧连接起来的整个序列。

以nlp的一个最简单词性标注任务来说,将我 吃 苹果 三个单词标注词性为 我/nn 吃/v 苹果/nn。

那么这个 任务的输入就是:我 吃 苹果 (已经分词好的句子)
这个 任务的输出是:我/nn 吃/v 苹果/nn(词性标注好的句子)

所以为了解决一些这样类似的问题,能够更好的处理序列的信息,RNN就诞生了。

RNN结构

首先看一个简单的循环神经网络如,它由输入层、一个隐藏层和一个输出层组成:

深度学习基础-经典模型总结
这个图是一个比较抽象的图。可以这样来理解,如果把上面有W的那个带箭头的圈去掉,它就变成了最普通的 全连接神经网络。x是一个向量,它表示 输入层的值(这里面没有画出来表示神经元节点的圆圈);s是一个向量,它表示 隐藏层的值(这里隐藏层面画了一个节点,你也可以想象这一层其实是多个节点,节点数与向量s的维度相同);

U是输入层到隐藏层的 权重矩阵,o也是一个向量,它表示 输出层的值;V是隐藏层到输出层的 权重矩阵

那么,现在我们来看看W是什么。循环神经网络的隐藏层的值s不仅仅取决于当前这次的输入x,还取决于上一次隐藏层的值s。权重矩阵 W就是隐藏层上一次的值作为这一次的输入的权重。

我们给出这个抽象图对应的具体图:

深度学习基础-经典模型总结
我们从上图就能够很清楚的看到,上一时刻的隐藏层是如何影响当前时刻的隐藏层的。

如果我们把上面的图展开,循环神经网络也可以画成下面这个样子:

深度学习基础-经典模型总结
现在看上去就比较清楚了,这个网络在 t t t 时刻接收到输入 x t x_t x t ​ 之后,隐藏层的值是 s t s_t s t ​ ,输出值是 o t o_t o t ​ 。关键一点是, s t s_t s t ​ 的值不仅仅取决于 x t x_t x t ​ ,还取决于 s t − 1 s_{t-1}s t −1 ​ 。我们可以用下面的公式来表示循环神经网络的计算方法:
深度学习基础-经典模型总结
参考文章

; 介绍下LSTM

为了改善RNN的长程依赖问题,一种非常好的解决方案是 引入门控机制来控制信息的积累速度,包括有选择的加入新的信息,并有选择的遗忘之前积累的信息。LSTM(Long Short-Term Memory Network,上短期记忆网络)是RNN的一个变体,可以有效解决传统RNN网络的梯度爆炸和梯度消失问题。

LSTM网络结构图(循环单元结构)

深度学习基础-经典模型总结
计算过程:
  • 1)首先利用上一时刻的外部状态h t − 1 \pmb{h}{t-1}h h h t −1 ​ 和当前时刻的输入x t \pmb{x}_t x x x t ​,计算出三个门,以及候选状态c ~ t \tilde{\pmb{c}}{t}c c c ~t ​;
  • 2)结合遗忘门f t \pmb{f}_t f ​f ​​f t ​ 和输入门i t \pmb{i}_t i i i t ​ 来更新记忆单元c t \pmb{c}_t c c c t ​;
  • 3)结合输出门o t \pmb{o}_t o o o t ​,将内部状态的信息传递给外部状态h t \pmb{h}_t h h h t ​。

LSTM原理公式推导

LSTM的主要改进在以下两个方面,即新的内部状态和门控机制。

1. 新的内部状态

LSTM网络引入一个新的 内部状态(internal state)c t ∈ R D \pmb{c_t} \in \mathbb{R}^D c t ​​c t ​​​c t ​∈R D 专门进行线性的循环信息传递,同时(非线性地)输出信息给隐藏层的外部状态 h t ∈ R D \pmb{h_t} \in \mathbb{R}^D h t ​​h t ​​​h t ​∈R D。内部状态 c t \pmb{c_t}c t ​​c t ​​​c t ​ 通过以下公式计算:
c t = f t ⊙ c t − 1 + i t ⊙ c ~ t h t = o t ⊙ t a n h ( c t ) \begin{aligned} \pmb{c}t&=\pmb{f}_t \odot \pmb{c}{t-1} + \pmb{i}_t \odot \pmb{\tilde{c}_t } \ \pmb{h}_t&=\pmb{o}_t \odot tanh(\pmb{c}_t) \end{aligned}c c c t ​h h h t ​​=f ​f ​​f t ​⊙c c c t −1 ​+i i i t ​⊙c ~t ​​c ~t ​​​c ~t ​=o o o t ​⊙t a n h (c c c t ​)​

其中,f t ∈ [ 0 , 1 ] D \pmb{f}t \in [0,1]^D f ​f ​​f t ​∈[0 ,1 ]D、i t ∈ [ 0 , 1 ] D \pmb{i}_t \in [0,1]^D i i i t ​∈[0 ,1 ]D、o t ∈ [ 0 , 1 ] D \pmb{o}_t \in [0,1]^D o o o t ​∈[0 ,1 ]D 为三个门(gate)来控制信息传递的路径;⊙ \odot ⊙ 为向量元素乘积;c t − 1 \pmb{c}{t-1}c c c t −1 ​ 为上一时刻的记忆单元;c ~ t ∈ R D \tilde{\pmb{c}}{t} \in \mathbb{R}^D c c c ~t ​∈R D 是通过非线性函数得到的 候选状态
c ~ t = t a n h ( W c x t + U c h t − 1 + b c ) \tilde{\pmb{c}}
{t}=tanh(\pmb{W}c\pmb{x}_t+\pmb{U}_c\pmb{h}{t-1}+\pmb{b}_c)c c c ~t ​=t a n h (W W W c ​x x x t ​+U U U c ​h h h t −1 ​+b b b c ​)

在每个时刻 t t t,LSTM 网络的内部状态 c t \pmb{c}{t}c c c t ​ 记录了到当前时刻为止的历史信息。这里说明一下:公式当中的 W ∗ , U ∗ , b ∗ \pmb{W}{},\pmb{U}_{},\pmb{b}_{*}W W W ∗​,U U U ∗​,b b b ∗​ 是可学习的网络参数,其中 ∗ ∈ i , f , o , c * \in {i,f,o,c}∗∈i ,f ,o ,c。

2. 门控机制

在数字电路中, (gate)为一个二值变量 {0,1},0代表关闭状态,不许任务信息通过;1代表开放状态,允许所有信息通过。

LSTM网络引入 门控机制(Gating Mechanism)来控制信息传递的路径。三个门的作用为:

  • 遗忘门f t \pmb{f}t f ​f ​​f t ​ 控制上一时刻的内部状态c t − 1 \pmb{c}{t-1}c c c t −1 ​ 需要遗忘多少信息;
  • 输入门i t \pmb{i}t i i i t ​ 控制当前时刻的候选状态c ~ t \tilde{\pmb{c}}{t}c c c ~t ​ 有多少信息需要保存;
  • 输出门o t \pmb{o}_t o o o t ​ 控制当前时刻的内部状态c t \pmb{c}_t c c c t ​ 有多少信息需要输出给外部状态h t \pmb{h}_t h h h t ​

举例
1)当 f t = 0 , i t = 1 \pmb{f}t=\pmb{0},\pmb{i}_t=\pmb{1}f ​f ​​f t ​=0 0 0 ,i i i t ​=1 1 1 时,记忆单元将历史信息清空,并将候选状态向量 c ~ t \tilde{\pmb{c}}{t}c c c ~t ​ 写入。但此时记忆单元 c t \pmb{c}_t c c c t ​ 依然和上一时刻的历史信息有关。
2)当 f t = 1 , i t = 0 \pmb{f}_t=\pmb{1},\pmb{i}_t=\pmb{0}f ​f ​​f t ​=1 1 1 ,i i i t ​=0 0 0,记忆单元将复制上一时刻的内部,不写入新的信息。

LSTM中的”门”是一种”软”门,取值在(0,1)之间,表示以一定的比例允许信息通过。三个门的计算方式为:
i t = σ ( W i x t + U i h t − 1 + b i ) f t = σ ( W f x t + U f h t − 1 + b f ) o t = σ ( W o x t + U o h t − 1 + b o ) \begin{aligned} \pmb{i_t}&=\sigma(\pmb{W}i\pmb{x}_t+\pmb{U}_i\pmb{h}{t-1}+\pmb{b}i) \ \pmb{f_t}&=\sigma(\pmb{W}_f\pmb{x}_t+\pmb{U}_f\pmb{h}{t-1}+\pmb{b}f) \ \pmb{o_t}&=\sigma(\pmb{W}_o\pmb{x}_t+\pmb{U}_o\pmb{h}{t-1}+\pmb{b}_o) \ \end{aligned}i t ​​i t ​​​i t ​f t ​​f t ​​​f t ​o t ​​o t ​​​o t ​​=σ(W W W i ​x x x t ​+U U U i ​h h h t −1 ​+b b b i ​)=σ(W W W f ​x x x t ​+U U U f ​h h h t −1 ​+b b b f ​)=σ(W W W o ​x x x t ​+U U U o ​h h h t −1 ​+b b b o ​)​

其中,s i g m a ( ⋅ ) sigma(\cdot)s i g m a (⋅)为 Logistic 函数,其输出区间为 (0,1),x t \pmb{x_t}x t ​​x t ​​​x t ​ 为当前时刻的输入,h t − 1 \pmb{h_{t-1}}h t −1 ​​h t −1 ​​​h t −1 ​ 为上一时刻的外部状态。

参考文章

一个LSTM cell的时间复杂度是多少

参数计算

简单来说,就是公式中 W \pmb{W}W W W 和 b \pmb{b}b b b 包含的参数数量。

W \pmb{W}W W W 的话,就是输入维度乘输出维度,b \pmb{b}b b b 的参数量就是加上输出维度。

上面的公式中,W \pmb{W}W W W 有四个:W i \pmb{W}_i W W W i ​、W f \pmb{W}_f W W W f ​、W o \pmb{W}_o W W W o ​、W c \pmb{W}_c W W W c ​。同样,b \pmb{b}b b b 也有四个:b i \pmb{b}_i b b b i ​、b f \pmb{b}_f b b b f ​、b o \pmb{b}_o b b b o ​、b c \pmb{b}_c b b b c ​

我们假设输入x t \pmb{x}_t x x x t ​ 这个向量的维度是512,LSTM的隐层数是256,根据这个来实际计算一下参数量。

首先是输入 [h t − 1 \pmb{h}_{t-1}h h h t −1 ​,x t \pmb{x}_t x x x t ​],这个前面说过,是两个向量连接起来,因此维度相加: 256 + 512 = 768 256 + 512 = 768 2 5 6 +5 1 2 =7 6 8。
因为隐层是256,所以输出就是256维。W \pmb{W}W W W 的参数量就是768 × 256 = 196608 768 \times 256 = 196608 7 6 8 ×2 5 6 =1 9 6 6 0 8,b \pmb{b}b b b 的参数是256。
所以最终的参数量就是:( 768 × 256 + 256 ) × 4 = 787456 (768 \times 256 + 256 ) \times 4 = 787456 (7 6 8 ×2 5 6 +2 5 6 )×4 =7 8 7 4 5 6。

另外,PyTorch 中的 LSTM 实现稍有不同,其公式如下:

深度学习基础-经典模型总结
上面的 g t g_t g t ​ 其实就是 C t ~ \tilde{\pmb{C}t}C C C t ​~​,其他符号基本是一致的。可以看到,PyTorch 中,x t \pmb{x}_t x x x t ​ 与 h t − 1 \pmb{h}{t-1}h h h t −1 ​ 并没有拼接在一起,而是各自做了对应的运算,这其实就是使用了 分块矩阵的技巧进行计算,结果理论上是一样的,不过这里有些不同的就是加了两个bias,因此计算偏置的参数需要乘2。

参考文章

; 介绍下GRU

GRU网络结构图(循环单元结构)

深度学习基础-经典模型总结
GRU原理公式推导

GRU(Gated Recurrent Unit,门控循环网络)是一种比 LSTM 网络更加简单的循环神经网络。

GRU网络同样引入 门控机制来控制信息更新的方式。和 LSTM 不同的是,GRU 不引入额外的记忆单元,GRU引入一个 更新门(Update Gate)来控制当前状态需要从历史状态中保留多少信息(不经过非线性变换),以及需要从候选状态中接受多少新信息,也就是 控制当前隐藏状态单元是否需要被新的隐藏单元更新,公式为:
h t = z t ⊙ h t − 1 + ( 1 − z t ) ⊙ g ( x t , h t − 1 ; θ ) \pmb{h}t = \pmb{z}_t \odot \pmb{h}{t-1} + (1-\pmb{z}t) \odot g(\pmb{x}_t,\pmb{h}{t-1};\theta)h h h t ​=z z z t ​⊙h h h t −1 ​+(1 −z z z t ​)⊙g (x x x t ​,h h h t −1 ​;θ)
其中,z t ∈ [ 0 , 1 ] D \pmb{z}t \in [0,1]^D z z z t ​∈[0 ,1 ]D 为更新门:
z t = σ ( W z x t + U z h t − 1 + b z ) \pmb{z}_t = \sigma(\pmb{W}_z\pmb{x}_t + \pmb{U}_z\pmb{h}
{t-1} + \pmb{b}_z)z z z t ​=σ(W W W z ​x x x t ​+U U U z ​h h h t −1 ​+b b b z ​)

在 LSTM 网络中,输入门和遗忘门是 互补关系,具有一定的 冗余性。GRU网络直接 使用一个门来控制输入和遗忘之间的平衡。当 z t = 0 \pmb{z}t = 0 z z z t ​=0 时,当前状态 h t \pmb{h}_t h h h t ​ 和前一时刻的状态 h t − 1 \pmb{h}{t-1}h h h t −1 ​ 之间为非线性函数关系;当 z t = 1 \pmb{z}t = 1 z z z t ​=1 时, h t \pmb{h}_t h h h t ​ 和 h t − 1 \pmb{h}{t-1}h h h t −1 ​ 之间为线性函数关系。

在GRU网络中,函数 g ( x t , h t − 1 ; θ ) g(\pmb{x}t,\pmb{h}{t-1};\theta)g (x x x t ​,h h h t −1 ​;θ) 的定义为:
h ~ t = t a n h ( W t x t + U t ( r t ⊙ h t − 1 ) + b h ) \tilde{\pmb{h}}{t} = tanh(\pmb{W}_t\pmb{x}_t + \pmb{U}_t(\pmb{r}_t \odot \pmb{h}{t-1}) + \pmb{b}_h)h h h ~t ​=t a n h (W W W t ​x x x t ​+U U U t ​(r r r t ​⊙h h h t −1 ​)+b b b h ​)

其中, h ~ t \tilde{\pmb{h}}{t}h h h ~t ​ 表示当前时刻的候选状态,r t ∈ [ 0 , 1 ] D \pmb{r}_t \in [0,1]^D r r r t ​∈[0 ,1 ]D 为 重置门(Reset Gate),用来控制 候选状态 h ~ t \tilde{\pmb{h}}{t}h h h ~t ​ 的计算是否依赖上一时刻的状态 h t − 1 \pmb{h}{t-1}h h h t −1 ​,也就是说 决定先前的隐藏状态单元是否被忽略,公式为:
r t = σ ( W t x t + U t h t − 1 + b r ) \pmb{r}_t = \sigma(\pmb{W}_t\pmb{x}_t + \pmb{U}_t\pmb{h}
{t-1} + \pmb{b}_r)r r r t ​=σ(W W W t ​x x x t ​+U U U t ​h h h t −1 ​+b b b r ​)

举例
1)当 r t = 0 \pmb{r}t = 0 r r r t ​=0 时,候选状态 h ~ t = t a n h ( W c x t + b ) \tilde{\pmb{h}}{t} = tanh(\pmb{W}c\pmb{x}_t + \pmb{b})h h h ~t ​=t a n h (W W W c ​x x x t ​+b b b ) 只和当前输入 x t \pmb{x}_t x x x t ​ 有关,和历史状态无关;
2)当 r t = 1 \pmb{r}_t = 1 r r r t ​=1 时,候选状态 h ~ t = t a n h ( W h x t + U h h t − 1 + b h ) \tilde{\pmb{h}}
{t} = tanh(\pmb{W}h\pmb{x}_t + \pmb{U}_h\pmb{h}{t-1}+ \pmb{b}h)h h h ~t ​=t a n h (W W W h ​x x x t ​+U U U h ​h h h t −1 ​+b b b h ​) 和当前输入 x t \pmb{x}_t x x x t ​ 以及历史状态 h t − 1 \pmb{h}{t-1}h h h t −1 ​ 相关, 和 RNN 一致

综上,GRU网络的状态更新方式为:
h t = z t ⊙ h t − 1 + ( 1 − z t ) ⊙ h ~ t \pmb{h}t = \pmb{z}_t \odot \pmb{h}{t-1} + (1-\pmb{z}t) \odot \tilde{\pmb{h}}{t}h h h t ​=z z z t ​⊙h h h t −1 ​+(1 −z z z t ​)⊙h h h ~t ​

可以看出:
1)当 z t = 0 , r = 1 \pmb{z}t = \pmb{0}, \pmb{r} = \pmb{1}z z z t ​=0 0 0 ,r r r =1 1 1 时,GRU网络 退化为RNN
2)当 z t = 0 , r = 0 \pmb{z}_t = \pmb{0}, \pmb{r} = \pmb{0}z z z t ​=0 0 0 ,r r r =0 0 0 时,当前状态 h t \pmb{h}_t h h h t ​ 只和当前输入 x t \pmb{x}_t x x x t ​ 相关,和历史状态 h t − 1 \pmb{h}
{t-1}h h h t −1 ​ 无关;
3)当 z t = 1 \pmb{z}t = 1 z z z t ​=1 时,当前状态 h t = h t − 1 \pmb{h}_t = \pmb{h}{t-1}h h h t ​=h h h t −1 ​,等于上一时刻状态 h t − 1 \pmb{h}_{t-1}h h h t −1 ​,和当前输入 x t \pmb{x}_t x x x t ​ 无关。

参考文章

  • 神经网络和深度学习

RNN和LSTM的区别

解决了什么问题,为什么解决了梯度消失的问题

LSTM解决了梯度消失问题,但不能解决梯度爆炸问题。梯度把咱需要用另外的技术来处理,技术上相比梯度消失好解决,如梯度截断法。 需要强调的是,无论梯度消失,还是梯度爆炸,都是技术上实现的BUG,而不是理论上的BUG!

LSTM除了在结构上天然的克服了梯度消失问题,更重要的是具有更多的参数来控制模型;通过四倍于RNN的参数量,可以更加精细地预测时间序列变量。LSTM可以通过一套更复杂的结构来说明深度循环神经网络中,哪些历史信息应该被记住,哪些历史信息应该被遗忘,以及是否每个阶段都应该有有效的信息被输出!关于为什么解决了梯度消失,可以参考知乎上的高赞解答。

以上回答参考知乎

参考文章

注意力模型

介绍下Attention

1. 什么是Attention

attention机制:又称为注意力机制,顾名思义,是一种能让模型对重要信息重点关注并充分学习吸收的技术,它不算是一个完整的模型,应当是一种技术,能够作用于任何序列模型中。

2. 相比CNN、LSTM的优势

以机器翻译为例,机器翻译使用seq2seq模型,对于一段文本序列,通常要使用某种机制对该序列进行编码,通过降维等方式将其encode成一个固定长度的向量,用于输入到后面的全连接层。

深度学习基础-经典模型总结
一般我们会使用CNN或者RNN(包括GRU或者LSTM)等模型来对序列数据进行编码,然后采用各种pooling或者对RNN直接取最后一个t时刻的hidden state作为句子的向量输出。这里会有一个问题:

常规的编码方法,无法体现对一个句子序列中不同语素的关注程度,在自然语言中,一个句子中的不同部分是有不同含义和重要性的,比如上面的例子中:I hate this movie.如果做情感分析,明显对hate这个词语应当关注更多。当然是用CNN和RNN能够编码这种信息。但是如果序列长度很长的情况下,这种方法会有一定的瓶颈。

拿CNN举例,具体如下图:图来自“变形金刚”为何强大:从模型到代码全面解析Google Tensor2Tensor系统

深度学习基础-经典模型总结
CNN的核心就是 卷积核能够变相学习n-gram的信息,如果使用hierarchical的卷积核,那么越上层的卷积核越能编码原始距离较远的词组的信息。但是这种编码能力也是有上限的,对于较长的文本,模型效果不会再提升太多。RNN也是同理。

小结

Attention 相比 CNN、LSTM,优势在于 更容易捕获长距离依赖信息。基于卷积或循环网络的序列编码都是一种局部的编码方式,只建模了输入信息的 局部依赖关系。虽然循环网络理论上可以建立长距离依赖关系,但是 由于信息传递容量的限制以及梯度消失问题,实际上也只能建立短距离依赖关系。更多解释可参考“变形金刚”为何强大:从模型到代码全面解析Google Tensor2Tensor系统这篇文章。

3. Attention怎么用

首先讲一下attention最基本最抽象的流程。 以seq2seq模型为例

基本流程:对于一个句子序列 S S S,其由单词序列 [ w 1 , w 2 , . . . , w n ] [w_1,w_2,…,w_n][w 1 ​,w 2 ​,…,w n ​] 构成。

  • 1)应用某种方法将S S S 的每个单词w i w_i w i ​ 编码为一个单独向量v i v_i v i ​。
  • 2)解码时,使用学习到的注意力权重a i a_i a i ​ 对 1 中得到的所有单词向量做加权线性组合∑ i a i v i \sum_i a_iv_i ∑i ​a i ​v i ​.

  • 3)在decoder进行下一个词的预测时,使用 2 中得到的线性组合。

具体构成如下:

我们的最终目标是要能够帮助decoder在生成词语时,有一个不同词语的权重的参考。在训练时,对于decoder我们是有训练目标的,此时将decoder中的信息定义为一个 Query。而encoder中包含了所有可能出现的词语,我们将其作为一个 字典,该字典的 key为所有encoder的序列信息。n个单词相当于当前字典中有n条记录,而字典的 value通常也是所有encoder的序列信息。

上面对应于 第一步,然后是 第二步计算注意力权重,由于我们要让模型自己去学习该对哪些语素重点关注,因此要用我们的学习目标Query来参与这个过程,因此对于Query的每个向量,通过一个函数 a i = F ( Q i , K ) a_i=F(Q_i,K)a i ​=F (Q i ​,K ) ,计算预测 i i i 时刻词时,需要学习的 注意力权重,由于包含 n 个单词,因此, a i a_i a i ​ 应当是一个 n 维的向量,为了后续计算方便,需要将该向量进行 softmax归一化,让向量的每一维元素都是一个概率值。

深度学习基础-经典模型总结
最后对Value vectors进行 加权线性组合,得到带权重参考的”字典”输出:
深度学习基础-经典模型总结
权重计算函数(注意力打分函数)

眼尖的同学肯定发现这个attention机制比较核心的地方就是如何对Query和key计算注意力权重。下面简单总结几个常用的方法:

1)多层感知机方法(加性模型)

深度学习基础-经典模型总结
主要是先将query和key进行拼接,然后接一个激活函数为tanh的全连接层,然后再与一个网络定义的权重矩阵做乘积。
这种方法据说对于大规模的数据特别有效。

2)Bilinear方法(双线性模型)

深度学习基础-经典模型总结
通过一个权重矩阵直接建立q和k的关系映射,比较直接,且计算速度较快。

3)Dot Product(点积模型)

深度学习基础-经典模型总结
这个方法更直接,连权重矩阵都省了,直接建立q和k的关系映射,优点是计算速度更快了,且不需要参数,降低了模型的复杂度。但是 需要q和k的维度要相同

4)scaled-dot Product(缩放点积模型)

上面的点积方法有一个问题,就是随着向量维度的增加,最后得到的权重也会增加,为了 提升计算效率,防止数据上溢,对其进行scaling。另外,点积模型的值通常有比较大的方差,从而导致Softmax函数的梯度会比较小。

深度学习基础-经典模型总结
说明一下,方法1计算比较复杂,训练成本比较高,硬件机器性能不高时通常采用方法2、3或者4。

4. 总结一下

注意力机制的计算可以分为两步:

4.1 在所有输入信息上计算注意力分布

用 X = [ x 1 , . . . , x N ] ∈ R D × N \pmb{X}=[\pmb{x}_1,…,\pmb{x}_N] \in \mathbb{R}^{D \times N}X X X =[x x x 1 ​,…,x x x N ​]∈R D ×N 表示 N N N 组输入信息,其中 D D D 维向量 x n ∈ R D , n ∈ [ 0 , N ] x_n \in \mathbb{R}^D, n \in [0,N]x n ​∈R D ,n ∈[0 ,N ] 表示一组输入信息。为了节省计算资源,不需要将所有信息都输入神经网络,只需要从 X X X 中选择一些和任务相关的信息。

为了从 N N N 个输入向量 [ x 1 , . . . , x N ] [\pmb{x}_1,…,\pmb{x}_N][x x x 1 ​,…,x x x N ​] 中选择出和某个特定任务相关的信息,我们需要引入一个和任务相关的表示,称为 查询向量(Query Vector),并通过一个打分函数来计算每个 输入向量查询向量之间的相关性。

给定一个和任务相关的查询向量 q \pmb{q}q ​q ​​q,我们用 注意力变量 z ∈ [ 1 , N ] z \in [1,N]z ∈[1 ,N ] 来表示被选择信息的索引位置,即 z = n z = n z =n 表示选择了第 n n n 个输入向量。为了计算方便,我们采用一种”软性”的信息选择机制。首先计算在给定 x \pmb{x}x x x 和 X \pmb{X}X X X 下,选择第 i i i 个输入向量的概率 α n \alpha_n αn ​。
α n = p ( z = n ∣ X , q ) = s o f t m a x ( s ( x n , q ) ) = e x p ( s ( x n , q ) ) ∑ j = 1 N e x p ( s ( x j , q ) ) \begin{aligned} \alpha_n &= p(z=n|\pmb{X},\pmb{q}) \ &= softmax(s(\pmb{x}n,\pmb{q})) \ &=\frac{exp(s(\pmb{x}_n,\pmb{q}))}{\sum{j=1}^N exp(s(\pmb{x_j},\pmb{q}))} \end{aligned}αn ​​=p (z =n ∣X X X ,q ​q ​​q )=s o f t m a x (s (x x x n ​,q ​q ​​q ))=∑j =1 N ​e x p (s (x j ​​x j ​​​x j ​,q ​q ​​q ))e x p (s (x x x n ​,q ​q ​​q ))​​

其中,α n \alpha_n αn ​ 称为 注意力分布,s ( x , q ) s(\pmb{x},\pmb{q})s (x x x ,q ​q ​​q )为 注意力打分函数

4.2 根据注意力分布来计算输入信息的加权平均

注意力分布 α n \alpha_n αn ​ 可以解释为在给定任务相关的查询 q q q 时,第 n 个输入向量受关注的程度。我们采用一种”软性”的信息选择机制对输入信息进行汇总,即
a t t ( X , q ) = ∑ n = 1 N α n x n = E z ∼ p ( z ∣ X , q ) [ x z ] \begin{aligned} att(\pmb{X},\pmb{q}) &= \sum_{n=1}^N \alpha_n \pmb{x}n \ &= \mathbb{E}{z \thicksim p(z|\pmb{X},\pmb{q})} [\pmb{x}_z] \end{aligned}a t t (X X X ,q ​q ​​q )​=n =1 ∑N ​αn ​x x x n ​=E z ∼p (z ∣X X X ,q ​q ​​q )​[x x x z ​]​

其中,第二个等号对应公式称为 软性注意力机制

参考文章

; 介绍下Self attention

关于attention有很多应用,在非seq2seq任务中,比如文本分类,或者其他分类问题,会通过self attention来使用attention。这个 方法思想很简单,而且计算成本相对来说不高,强烈推荐。具体来说就是:

Query和Key,value都是相同的,即输入的句子序列信息(可以是词向量lookup后的序列信息,也可以先用cnn或者rnn进行一次序列编码后得到的处理过的序列信息)。后面的步骤与上述的都是一样的:

1)首先建立句子序列中的每个词 q i q_i q i ​ 与句子其他词k的注意力权重 a i a_i a i ​;

2)然后将注意力权重向量进行softmax归一化,并与句子序列的所有时刻的信息(词向量或者rnn hidden state)进行线性加权。

深度学习基础-经典模型总结
这种方法中, 句子中的每个词都能与句子中任意距离的其他词建立一个敏感的关系,可以说在一定程度上提升了之前所说的CNN和RNN对于长距离语义依赖建模能力的上限。下图同样来自:“变形金刚”为何强大:从模型到代码全面解析Google Tensor2Tensor系统

参考文章

介绍下Multi head attention

multi-head attention 是另一种很有效的attention使用方法。这个是在Attention is all you need这篇论文中被使用。图例如下:

深度学习基础-经典模型总结
公式化表示如下:
深度学习基础-经典模型总结
解释一下,与原来的self-attention的核心原理其实是差不多的,但是由于 self attention只从一个角度去学习关注点,可能会有点偏颇。所以,设计 h h h 种不同的 ( W i Q , W i K , W i V ) (W_i^Q,W_i^K,W_i^V)(W i Q ​,W i K ​,W i V ​) 权重矩阵对,然后做基本的attention操作前,将query,key和value分别用上述权重对做 线性变换,然后再计算得到 h h h 个 不同角度的attention权重 h e a d i head_i h e a d i ​,将这些 h e a d i head_i h e a d i ​ 按列拼接后,再与一个新的权重矩阵 W o W^o W o 做 线性变换,得到最终的 attention 输出。

这里要重点说一个问题,就是关于multihead 的每个权重矩阵的维度。做 self attention 时,若使用 Bilineard 方式,也有一个权重矩阵W,这个权重矩阵维度一般是与Q、K、V的维度是一样的(通常做法,也有不一样的,但是维度不会低)。但是做 multihead 时,如果对每个权重矩阵的维度还是设为原始维度,那么计算的成本将会蹭蹭得往上涨。如果硬件性能不太行,极有可能会报 OOM 问题。所以通常的做法是:设三种权重矩阵 ( W i Q , W i K , W i V ) (W_i^Q,W_i^K,W_i^V)(W i Q ​,W i K ​,W i V ​) 的维度分别为 ( d q , d k , d v ) (d^q,d^k,d_v)(d q ,d k ,d v ​),原始维度为 d d d,那么
d q = d k = d v = d / h d^q=d^k=d^v=d/h d q =d k =d v =d /h

参考文章

; 预训练语言模型

介绍下Transformer

1. Transformer的整体结构

首先介绍 Transformer 的整体结构,下图是 Transformer 用于中英文翻译的整体结构:

深度学习基础-经典模型总结
可以看到 Transformer 由 Encoder 和 Decoder 两个部分组成,Encoder 和 Decoder 都包含 6 个 block。有关Transformer 的工作流程介绍以及 Encoder 和 Decoder 结构的解读可参考 Transformer模型详解(图解最完整版) 这篇文章。

Encoder 和 Decoder 各自的内部构造如下所示:

深度学习基础-经典模型总结
上图 左侧方框部分是 Transformer 的 Encoder block 结构,可以看到是由 Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm 组成的。

右侧方框部分(标红)为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:

  • 包含两个 Multi-Head Attention 层。
  • 第一个 Multi-Head Attention 层采用了 Masked 操作。
  • 第二个 Multi-Head Attention 层的 K, V矩阵使用 Encoder 的 编码信息矩阵C进行计算,而 Q使用上一个 Decoder block 的输出计算。
  • 最后有一个 Softmax 层计算下一个翻译单词的概率。

2. Transformer的输入

Transformer 中单词的输入表示 x 由 单词 Embedding位置 Embedding (Positional Encoding) 相加得到。

深度学习基础-经典模型总结
2.1 单词 Embedding

单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。

2.2 位置编码(Positional Encoding)

为什么要有位置编码?

self-attention机制建模序列的方式,既不是RNN的时序观点,也不是CNN的结构化观点,而是一种词袋(bag of words)的观点。进一步阐述的话,应该说该机制视一个序列为扁平的结构,因为 不论看上去距离多远的词,在self-attention机制中都为1。这样的建模方式,实际上会 丢失词之间的相对距离关系。举个例子就是,”牛 吃了 草”、”草 吃了 牛”,”吃了 牛 草”三个句子建模出来的每个词对应的表示,会是一致的。

为了缓解这个问题,Transformer中 将词在句子中所处的位置映射成vector,补充到其embedding中去。该思路并不是第一次被提出,CNN模型其实也存在同样的难以建模相对位置(时序信息)的缺陷,Facebook提出了位置编码的方法。一种直接的方式是,直接对绝对位置信息建模到embedding里面,即将词 W i W_i W i ​ 的 i i i 映射成一个向量,加到其embedding中去。这种方式的缺点是只能建模有限长度的序列。Transformer文章中 提出了一种非常新颖的时序信息建模方式,就是 利用三角函数的周期性,来建模词之间的相对位置关系。具体的方式是将绝对位置作为三角函数中的变量做计算,具体公式如下:

深度学习基础-经典模型总结
其中,位置 Embedding 用 PE 表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。在 Transformer 中采用了后者。

该公式的设计非常先验,尤其是分母部分,不太好解释。从笔者个人的观点来看,一方面 三角函数有很好的周期性,也就是隔一定的距离,因变量的值会重复出现,这种特性可以用来 建模相对距离;另一方面,三角函数的值域是[-1,1],可以很好的提供embedding元素的值。

3. Self-Attention(自注意力机制)

自注意力机制在 Encoder部分 和 Decoder 部分中都有体现,再看下 Transformer 的内部结构图:

深度学习基础-经典模型总结
其中,左侧为 Encoder block,右侧为 Decoder block。红色圈中的部分为 Multi-Head Attention,是由多个 Self-Attention 组成的。可以看到 Encoder block 包含一个 Multi-Head Attention,而 Decoder block 包含两个 Multi-Head Attention (其中有一个用到 Masked)。Multi-Head Attention 上方还包括一个 Add & Norm 层,Add 表示残差连接 (Residual Connection) 用于防止网络退化,Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化。

3.1 Multi-Head Attention(多头自注意力)

需要说明的是,Transformer里面的self-attention机制是一种新的变种,体现在两点,一方面是加了一个 缩放因子(scaling factor),另一方面是引入了 多头机制(multi-head attention)。

缩放因子体现在Attention的计算公式中多了一个向量的维度作为分母,目的是想 避免维度过大导致的点乘结果过大,进入softmax函数的饱和域,引起梯度过小。Transformer中的self-attention计算公式如下:

深度学习基础-经典模型总结
多头机制是指,引入多组的参数矩阵来分别对Q、K、V进行 线性变换求self-attention的结果,然后将所有的结果拼接起来作为最后的self-attention输出。公式如下:
深度学习基础-经典模型总结
这种方式使得 模型具有多套比较独立的attention参数,理论上可以增强模型的能力。

3.2 Add & Norm

Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:

深度学习基础-经典模型总结
其中 X 表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。

Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到:

深度学习基础-经典模型总结
Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会 将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛

3.3 Feed Forward

在进行了Attention操作之后,Encoder 和 Decoder 中的每一层都包含了一个全连接前向网络,对每个 position 的向量分别进行相同的操作,包括两个线性变换和一个ReLU激活输出,对应公式如下:

深度学习基础-经典模型总结
Feed Forward 层其实是一个包含两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数。X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致,但每一层的参数不同。

小结

  • Transformer 与 RNN 不同,可以比较好地并行训练。
  • Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
  • Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。
  • Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。

参考文章

; Transformer中Encoder和Decoder的输入分别是什么

Encoder部分:输入参数有4个,分别是x代表目标数据的嵌入表示,memory是编码器层的输出,src_mask源数据的掩码张量,以及tgt_mask目标数据的掩码张量;
Decoder部分:输入参数有4个,分别是来自上一层的输入x,来自编码器层的语义存储变量memory,以及src_mask源数据掩码张量和tgt_mask目标数据掩码张量。

具体结合代码分析一遍最好~

参考文章

自注意力机制中的QKV的作用是什么

QKV指的是什么?

Q:表示词的查询向量;
K:键向量,表示被查询信息与其他信息的相关性的向量;
V:值向量,表示被查询信息的向量

简单来说一句话:Q是最适合查找目标的,K是最适合接收查找的,V就是内容,这 三者不一定要一致,所以网络这么设置了三个向量,然后学习出最适合的Q, K, V,以此增强网络的能力。

主要要理解Q,K的意义,可以类比搜索的过程:

假设我们想查一篇文章,我们不会直接把文章的内容打上去,而是会在搜索框输入该文章的 关键字,如果我们搜不到,我们往往会再换一个关键字,直到搜到为止,那么可以让我们搜到的关键字就是 最适合查找目标文章的关键字。这个 最适合查找目标文章的关键字就是Q

那么搜索引擎拿到我们输入的关键字Q之后,就会把Q和库里面的文章对比,当然搜索引擎为了节省资源加快对比速度,提前把库里面的文章进行了处理提取了 关键信息,关键信息有很多,那么那个关键信息能够使得搜索命中率高,那个就是 最适合接收查找的关键信息,这个 最适合接收查找的关键信息就是K

使用Q和K计算了相似度之后得到score,这就是相似度评分,之后有了相似度评分,就可以把内容V加权回去了。由于计算Q、K、V的矩阵是 可学习的,因此网络可以自己学习出要怎么样安排Q、K、V。

以上回答参考知乎~

Transformer中Encoder与Decoder的QKV矩阵如何产生

利用三个神经网络,对同一输入X进行三次不同变换,产生Q,K,V。使用同一输入 X 做变换,这也就是自注意力机制当中”自”的体现。

深度学习基础-经典模型总结
Transformer中QKV矩阵是否可以设置成同一个

确切的说,Q和K不能设置为同一个,K和V的值是可以一样的。回顾下注意力公式:

深度学习基础-经典模型总结
想要回答这个问题,我们首先要明白, 为什么要计算Q和K的点乘
  • 先从点乘的物理意义说, 两个向量的点乘表示两个向量的相似度
  • Q,K,V物理意义上是一样的,都表示同一个句子中不同token组成的矩阵。矩阵中的每一行,是表示一个token的word embedding向量。假设一个句子”Hello, how are you?”长度是6,embedding维度是300,那么Q,K,V都是(6, 300)的矩阵。

简单的说,K和Q的点乘是为了计算一个句子中每个token相对于句子中其他token的相似度,这个相似度可以理解为attention score, 关注度得分。比如说 “Hello, how are you?”这句话,当前token为”Hello”的时候,我们可以知道”Hello”对于” , “, “how”, “are”, “you”, “?”这几个token对应的关注度是多少。有了这个attetnion score,可以知道处理到”Hello”的时候,模型在关注句子中的哪些token。

深度学习基础-经典模型总结
这个attention score是一个(6, 6)的矩阵。 每一行代表每个token相对于其他token的关注度。比如说上图中的第一行,代表的是Hello这个单词相对于本句话中的其他单词的关注度。 添加softmax只是为了对关注度进行归一化

虽然有了attention score矩阵,但是这个矩阵是经过各种计算后得到的,已经很难表示原来的句子了。然而V还代表着原来的句子,所以我们拿这个attention score矩阵与V相乘,得到的是一个加权后结果。也就是说,原本V里的各个单词只用word embedding表示,相互之间没什么关系。但是经过与attention score相乘后,V中每个token的向量(即一个单词的word embedding向量),在300维的每个维度上(每一列)上,都会对其他token做出调整(关注度不同)。与V相乘这一步,相当于 提纯,让每个单词关注该关注的部分。

好了,该解释为什么不把K和Q用同一个值了。

经过上面的解释,我们知道K和Q的点乘是为了得到一个attention score 矩阵,用来对V进行提纯。 K和Q使用了不同的W_k, W_Q来计算,可以理解为是在不同空间上的投影。正因为有了这种不同空间的投影, 增加了表达能力,这样计算得到的attention score矩阵的 泛化能力更高。这里解释下我理解的泛化能力,因为K和Q使用了不同的W_k, W_Q来计算,得到的也是两个完全不同的矩阵,所以表达能力更强。

但是如果不用Q,直接拿K和K点乘的话,你会发现attention score 矩阵是一个 对称矩阵。因为是同样一个矩阵,都投影到了同样一个空间,所以 泛化能力很差。这样的矩阵导致对V进行提纯的时候,效果也不会好。推荐看一下这篇文章,对Q,K,V进行了很详细的讲解。

以上回答参考知乎~

; Transformer中计算Attention除于根号d的作用

回顾下注意力公式:

深度学习基础-经典模型总结
为什么比较大的输入会使得softmax的梯度变得很小?

对于一个输入向量 x ∈ R d \pmb{x} \in \mathbb{R}^d x x x ∈R d,softmax函数将其映射/归一化到一个分布 y ^ ∈ R d \hat{\pmb{y}} \in \mathbb{R}^d y ​y ​​y ^​∈R d 。在这个过程中,softmax先用一个自然底数 e e e 将输入中的 元素间差距先”拉大”,然后归一化为一个分布。假设某个输入 x \pmb{x}x x x 中最大的的元素下标是 k k k , 如果输入的数量级变大(每个元素都很大),那么y ^ k \hat{y}_k y ^​k ​ 会非常接近1。可以推导出, 在输入的数量级很大时,梯度会消失为0,造成参数更新困难。具体参考transformer中的attention为什么scaled?高赞解答。

维度与点积大小的关系是怎么样的,为什么使用维度的根号来放缩?

针对为什么维度会影响点积的大小,在论文的脚注中其实给出了一点解释:

深度学习基础-经典模型总结
假设向量 q \pmb{q}q ​q ​​q 和 k \pmb{k}k k k 的各个分量是互相独立的随机变量,均值是0,方差是1,那么点积 q ⋅ k \pmb{q} \cdot \pmb{k}q ​q ​​q ⋅k k k 的均值是0,方差是 d k d_k d k ​ 。证明过程参考transformer中的attention为什么scaled?高赞解答,不难。

方差越大也就说明,点积的数量级越大(以越大的概率取大值)。那么一个自然的做法就是把方差稳定到1,做法是将点积除以 d k \sqrt{d_k}d k ​​,这样有:

深度学习基础-经典模型总结
将方差控制为1,也就有效地控制了前面提到的梯度消失的问题

以上,来自知乎高赞回答~

参考文章

; 介绍下BERT

1. BERT模型

BERT的全称是Bidirectional Encoder Representation from Transformers,即 双向Transformer的Encoder,因为decoder是不能获要预测的信息的。模型的主要创新点都在pre-train方法上,即用了Masked LM和Next Sentence Prediction两种方法分别捕捉词语和句子级别的representation。

BERT是谷歌发布的基于双向 Transformer的大规模预训练语言模型,该预训练模型能高效抽取文本信息并应用于各种NLP任务,并刷新了 11 项 NLP 任务的当前最优性能记录。BERT的全称是基于Transformer的双向编码器表征,其中”双向”表示模型在处理某一个词时,它能同时利用前面的词和后面的词两部分信息。

1.1 模型结构

Transformer结构是BERT模型的构成元素,BERT模型的结构如下图最左:

深度学习基础-经典模型总结
对比OpenAI GPT(Generative pre-trained transformer),BERT是双向的Transformer block连接;就像单向RNN和双向RNN的区别,直觉上来讲效果会好一些。

对比ELMo,虽然都是”双向”,但 目标函数其实是不同的。ELMo是分别以 p ( w i ∣ w 1 , . . . , w i − 1 ) p(w_i|w_1,…,w_{i-1})p (w i ​∣w 1 ​,…,w i −1 ​) 和 p ( w i ∣ w i + 1 , . . . , w n ) p(w_i|w_{i+1},…,w_n)p (w i ​∣w i +1 ​,…,w n ​) 作为目标函数,独立训练这两个representation然后拼接,而BERT则是以 p ( w i ∣ w 1 , . . . , w i − 1 , w i + 1 , . . . , w n ) p(w_i|w_1,…,w_{i-1},w_{i+1},…,w_n)p (w i ​∣w 1 ​,…,w i −1 ​,w i +1 ​,…,w n ​) 作为目标函数训练LM。

1.2 Embedding

这里的Embedding由 三种Embedding求和而成:

深度学习基础-经典模型总结
其中:

Token Embeddings是词向量,第一个单词是CLS标志,可以用于之后的分类任务
Segment Embeddings用来区别两种句子,因为预训练不光做LM还要做以两个句子为输入的分类任务
Position Embeddings和之前文章中的Transformer不一样, 不是三角函数而是学习出来的

1.3 Pre-training Task 1#: Masked LM

第一步预训练的目标就是做语言模型,从上文模型结构中看到了这个模型的不同,即bidirectional。 关于为什么要如此的bidirectional,作者在reddit上做了解释,意思就是如果使用预训练模型处理其他任务,那人们想要的肯定不止某个词左边的信息,而是左右两边的信息。而考虑到这点的模型ELMo只是将left-to-right和right-to-left分别训练拼接起来。直觉上来讲我们其实想要一个deeply bidirectional的模型,但是普通的LM又无法做到,因为在训练时可能会” 穿越“(关于这点我不是很认同,之后会发文章讲一下如何做bidirectional LM)。所以作者用了一个加mask的trick。

在训练过程中作者随机mask 15%的token,而不是把像cbow一样把每个词都预测一遍。 最终的损失函数只计算被mask掉那个token

Mask如何做也是有技巧的,如果一直用标记[MASK]代替(在实际预测时是碰不到这个标记的)会影响模型,所以随机mask的时候10%的单词会被替代成其他单词,10%的单词不替换,剩下80%才被替换为[MASK]。具体为什么这么分配,作者没有说。。。 要注意的是Masked LM预训练阶段模型是不知道真正被mask的是哪个词,所以模型每个词都要关注

因为序列长度太大(512)会影响训练速度,所以90%的steps都用seq_len=128训练,余下的10%步数训练512长度的输入。

1.4 Pre-training Task 2#: Next Sentence Prediction

因为涉及到QA和NLI之类的任务,增加了第二个预训练任务,目的是让模型理解两个句子之间的联系。训练的输入是句子A和B,B有一半的几率是A的下一句,输入这两个句子,模型预测B是不是A的下一句。预训练的时候可以达到97-98%的准确度。

注意:作者特意说了语料的选取很关键,要选用document-level的而不是sentence-level的,这样可以具备抽象连续长序列特征的能力。

1.5 Fine-tunning

分类:对于sequence-level的分类任务,BERT直接取第一个[CLS]token的final hidden state C ∈ R H C \in \mathbb{R}^H C ∈R H ,加一层权重 W ∈ R K × H W \in \mathbb{R}^{K \times H}W ∈R K ×H 后softmax预测lable proba:

深度学习基础-经典模型总结
其他预测任务需要进行一些调整,如图:
深度学习基础-经典模型总结
可以调整的参数和取值范围有:
  • Batch size: 16, 32
  • Learning rate (Adam): 5e-5, 3e-5, 2e-5
  • Number of epochs: 3, 4

因为大部分参数都和预训练时一样,精调会快一些,所以作者推荐多试一些参数。

2. 优缺点

2.1 优点

BERT是截至2018年10月的最新state of the art模型,通过预训练和精调横扫了11项NLP任务,这首先就是最大的优点了。而且它还用的是Transformer,也就是相对rnn更加高效、能捕捉更长距离的依赖。对比起之前的预训练模型,它捕捉到的是真正意义上的bidirectional context信息。

2.2 缺点

作者在文中主要提到的就是MLM预训练时的mask问题:

  • [MASK]标记在实际预测中不会出现,训练时用过多[MASK]影响模型表现
  • 每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token)

3. 总结

一遍读下来,感觉用到的都是现有的东西,可没想到效果会这么好,而别人又没想到。不过文章中没有具体解释的很多点可以看出这样出色的结果也是通过不断地实验得出的,而且训练的数据也比差不多结构的OpenAI GPT多,所以数据、模型结构,都是不可或缺的东西。

参考文章

; 介绍BERT中的两种预训练任务

针对句子语义相似度的任务

深度学习基础-经典模型总结
实际操作时,上述最后一句话之后还会加一个[SEP] token,语义相似度任务将两个句子按照上述方式输入即可,之后与论文中的分类任务一样,将[CLS] token位置对应的输出,接上softmax做分类即可(实际上GLUE任务中就有很多语义相似度的数据集)。

针对多标签分类的任务

多标签分类任务,即MultiLabel,指的是一个样本可能同时属于多个类,即有多个标签。以商品为例,一件L尺寸的棉服,则该样本就有至少两个标签——型号:L,类型:冬装。

对于多标签分类任务,显而易见的朴素做法就是不管样本属于几个类,就给它训练几个分类模型即可,然后再一一判断在该类别中,其属于那个子类别,但是这样做未免太暴力了,而多标签分类任务,其实是可以 只用一个模型来解决的。

利用BERT模型解决多标签分类问题时,其输入与普通单标签分类问题一致,得到其embedding表示之后(也就是BERT输出层的embedding),有几个label就连接到几个全连接层(也可以称为projection layer),然后再分别接上softmax分类层,这样的话会得到​ l o s s 1 , . . . , l o s s n loss_1,…,loss_n l o s s 1 ​,…,l o s s n ​ ,最后再将所有的loss相加起来即可。这种做法就 相当于将n个分类模型的特征提取层参数共享,得到一个共享的表示(其维度可以视任务而定,由于是多标签分类任务,因此其维度可以适当增大一些),最后再做多标签分类任务。

参考文章

BERT中计算Attention的公式

同 Transformer 的 Attention 计算公式:

深度学习基础-经典模型总结
参考文章

; BERT中LayerNorm的作用,为什么不用BN?

层归一化是和批量归一化非常类似的方法。和BN不同的是, 层归一化是对一个中间层的所有神经元进行归一化。在标准循环神经网络中,循环神经网络的净输入一般会随着时间慢慢变大或变小,从而导致梯度爆炸或消失。而层归一化的循环神经网络可以有效的缓解这种状况。

为什么BN不能直接应用于循环神经网络

1) 批量归一化是对一个中间层的单个神经元进行归一化操作,因此要求小批量样本的数量不能太小,否则难以计算单个神经元的统计信息;
2)此外,如果一个神经元的净输入(z ( l ) z^{(l)}z (l ),即未激活前)的分布在神经网络中是动态变化的,比如RNN网络,那么就无法应用批量归一化。

参考文章

Transformer与BERT的位置编码有什么区别

BERT的位置编码是学习出来的,Transformer是通过正弦函数生成的。

原生的Transformer中使用的是正弦位置编码(Sinusoidal Position Encoding),是绝对位置的函数式编码。由于Transformer中为self-attention,这种正余弦函数由于点乘操作,会有相对位置信息存在,但是没有方向性,且通过权重矩阵的映射之后,这种信息可能消失。或者说,Transformer的位置编码是一个算出来的值,实际上是一个固定值,它只能标记这是某一个位置,并不能标记这个位置有啥用。

BERT中使用的是学习位置嵌入(learned position embedding),是绝对位置的参数式编码,且和相应位置上的词向量进行相加而不是拼接。因为bert的位置编码是可学习的embedding,所以它不仅可以标注这一个位置,还能学习这个位置有什么作用。

Original: https://blog.csdn.net/qq_22247993/article/details/123316791
Author: 城阙
Title: 深度学习基础-经典模型总结

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/528494/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球