DNN神经网络
前向传播算法
假设第
l
−
1
l - 1
l−1层共有m个神经元,则对于第
l
l
l层的第
j
j
j个神经元的输出
a
j
l
a_j^l
ajl:
a
j
l
=
σ
(
z
j
l
)
=
σ
(
∑
k
=
1
m
w
j
k
l
a
k
l
−
1
+
b
j
l
)
a_{j}^{l}=\sigma\left(z_{j}^{l}\right)=\sigma\left(\sum_{k=1}^{m} w_{j k}^{l} a_{k}^{l-1}+b_{j}^{l}\right)
ajl=σ(zjl)=σ(k=1∑mwjklakl−1+bjl)
使用代数一个个表示比较复杂,使用矩阵法则比较简单。第
l
l
l层的输出为:
a
l
=
σ
(
z
l
)
=
σ
(
W
l
a
l
−
1
+
b
l
)
a^{l}=\sigma\left(z^{l}\right)=\sigma\left(W^{l} a^{l-1}+b^{l}\right)
al=σ(zl)=σ(Wlal−1+bl)
反向传播算法(BP)
定义一个损失函数,此处以最常见的均方差来度量损失:
J
(
W
,
b
,
x
,
y
)
=
1
2
∥
y
−
a
L
∥
2
2
=
1
2
∑
j
(
y
j
−
a
j
L
)
2
J(W, b, x, y)=\frac{1}{2}\left\|y - a^{L}\right\|_{2}^{2}=\frac{1}{2} \sum_{j}\left(y_{j}-a_{j}^{L}\right)^{2}
J(W,b,x,y)=21∥∥y−aL∥∥22=21j∑(yj−ajL)2
-
计算最后一层神经网络产生的错误
δ L = ∂ J ( W , b , x , y ) ∂ z L = ∂ J ( W , b , x , y ) ∂ a L ⋅ ∂ a L ∂ z L = ( a L − y ) ⊙ σ ′ ( z L ) \delta^{L}=\frac{\partial J(W, b, x, y)}{\partial z^{L}} = \frac{\partial J(W, b, x, y)}{\partial a^{L}} \cdot \frac{\partial a^{L}}{\partial z^{L}} =\left(a^{L}-y\right) \odot \sigma^{\prime}\left(z^{L}\right) δL=∂zL∂J(W,b,x,y)=∂aL∂J(W,b,x,y)⋅∂zL∂aL=(aL−y)⊙σ′(zL) -
由后往前,计算每一层神经网络产生的错误
δ l = ∂ J ( W , b , x , y ) ∂ z l = ( ∂ z L ∂ z L − 1 ∂ z L − 1 ∂ z L − 2 ⋯ ∂ z l + 1 ∂ z l ) T ∂ J ( W , b , x , y ) ∂ z L \delta^{l}=\frac{\partial J(W, b, x, y)}{\partial z^{l}}=\left(\frac{\partial z^{L}}{\partial z^{L-1}} \frac{\partial z^{L-1}}{\partial z^{L-2}} \cdots \frac{\partial z^{l+1}}{\partial z^{l}}\right)^{T} \frac{\partial J(W, b, x, y)}{\partial z^{L}} δl=∂zl∂J(W,b,x,y)=(∂zL−1∂zL∂zL−2∂zL−1⋯∂zl∂zl+1)T∂zL∂J(W,b,x,y)
∵
∂
z
l
+
1
∂
z
l
=
W
l
+
1
a
l
+
b
l
+
1
∂
z
l
=
W
l
+
1
σ
(
z
l
)
+
b
l
+
1
∂
z
l
=
W
l
+
1
diag
(
σ
′
(
z
l
)
)
\because \frac{\partial z^{l+1}}{\partial z^{l}}=\frac{W^{l+1} a^{l}+b^{l+1}}{\partial z^{l}} = \frac{W^{l+1} \sigma\left(z^{l}\right)+b^{l+1}}{\partial z^{l}} =W^{l+1} \operatorname{diag}\left(\sigma^{\prime}\left(z^{l}\right)\right)
∵∂zl∂zl+1=∂zlWl+1al+bl+1=∂zlWl+1σ(zl)+bl+1=Wl+1diag(σ′(zl))
∴
δ
l
=
∂
J
(
W
,
b
,
x
,
y
)
∂
z
l
=
(
∂
z
l
+
1
∂
z
l
)
T
∂
J
(
W
,
b
,
x
,
y
)
∂
z
l
+
1
=
(
∂
z
l
+
1
∂
z
l
)
T
δ
l
+
1
=
diag
(
σ
′
(
z
l
)
)
(
W
l
+
1
)
T
δ
l
+
1
=
(
W
l
+
1
)
T
δ
l
+
1
⊙
σ
′
(
z
l
)
\therefore \delta^{l}=\frac{\partial J(W, b, x, y)}{\partial z^{l}}=\left(\frac{\partial z^{l+1}}{\partial z^{l}}\right)^{T} \frac{\partial J(W, b, x, y)}{\partial z^{l+1}}=\left(\frac{\partial z^{l+1}}{\partial z^{l}}\right)^{T} \delta^{l+1} \\=\operatorname{diag}\left(\sigma^{\prime}\left(z^{l}\right)\right)\left(W^{l+1}\right)^{T} \delta^{l+1}=\left(W^{l+1}\right)^{T} \delta^{l+1} \odot \sigma^{\prime}\left(z^{l}\right)
∴δl=∂zl∂J(W,b,x,y)=(∂zl∂zl+1)T∂zl+1∂J(W,b,x,y)=(∂zl∂zl+1)Tδl+1=diag(σ′(zl))(Wl+1)Tδl+1=(Wl+1)Tδl+1⊙σ′(zl)
- 计算权重的梯度
∂ J ( W , b , x , y ) ∂ w l = ∂ z l ∂ w l ⋅ ∂ J ( W , b , x , y ) ∂ z l = a l − 1 δ l \frac{\partial J(W, b, x, y)}{\partial w^{l}}= \frac{\partial z^{l}}{\partial w^{l}} \cdot \frac{\partial J(W, b, x, y)}{\partial z^{l}} =a^{l-1} \delta^{l} ∂wl∂J(W,b,x,y)=∂wl∂zl⋅∂zl∂J(W,b,x,y)=al−1δl - 计算偏置的梯度
∂ J ( W , b , x , y ) ∂ b l = ∂ z l ∂ b l ⋅ ∂ J ( W , b , x , y ) ∂ z l = δ l \frac{\partial J(W, b, x, y)}{\partial b^{l}}= \frac{\partial z^{l}}{\partial b^{l}} \cdot \frac{\partial J(W, b, x, y)}{\partial z^{l}} =\delta^{l} ∂bl∂J(W,b,x,y)=∂bl∂zl⋅∂zl∂J(W,b,x,y)=δl
CNN
卷积神经网络哪些部分构成?各部分作用分别是什么?
如果使用全连接前馈网络来处理图像时,会存在以下两个问题:
- 参数太多
- 局部不变性特征: 全连接前馈网络很难提取局部不变特征,一般需要进行数据增强来提高性能。
卷积神经网络一般由卷积层、池化层和全连接层交叉堆叠而成的前馈神经网络,使用反向传播算法进行训练。卷积神经网络有三个结构上的特性: 局部连接,权重共享和子采样。
- 卷积层的作用: 局部连接,权重共享
- 池化层也称为子采样层的作用: 进行特征选择,降低特征数量,并从而减少参数数量。
矩阵的大小
o u t w i d t h = ⌊ ( i n w i d t h + p a d w i d t h − f l i t e r w i d t h + s t r i d e w i d t h ) / s t r i d e w i d t h ⌋ out_{width} = \lfloor (in_{width} + pad_{width} - fliter_{width} + stride_{width}) / stride_{width}\rfloor outwidth=⌊(inwidth+padwidth−fliterwidth+stridewidth)/stridewidth⌋
为什么CNN能够用来做文本分类?
CNN就是一个超级N-Gram,而N-Gram就是考虑局部统计信息的语言模型,CNN相当于在低维向量空间中实现了它。
CNN用于自然语言处理的缺点
无法捕获远距离特征的问题,因为CNN不是通过卷积核覆盖的那个滑动窗口来捕获特征,捕获到的特征基本上都体现在这个滑动窗口中。针对这个问题提出了两种解决方法,一是Dilated 卷积,跳过一些特征,这样就能捕获更长距离的特征。 二是加深深度,在前一层的基础上继续使用卷积捕获特征。两种方式如下图所示
池化层的优点和缺点
优点:
(1) 这个操作可以保证特征位置与旋转不变性,因为不论这个强特征在哪个位置出现,都会不考虑其出现位置而能把它提出来。但对于NLP来说,这个特性其实并不一定是好事,因为在很多NLP的应用场合,特征的出现位置信息是很重要的,比如主语出现位置一般在句子头,宾语一般出现在句子尾等等,这些位置信息其实有时候对于分类任务来说还是很重要的,但是Max Pooling 基本把这些信息抛掉了。
(2) MaxPooling能减少模型参数数量,有利于减少模型过拟合问题。
(3) 对于NLP任务来说,Max Pooling有个额外的好处;在此处,可以把变长的输入X整理成固定长度的输入。因为CNN最后往往会接全联接层,而其神经元个数是需要事先定好的,如果输入是不定长的那么很难设计网络结构。
缺点:
(1) 特征的位置信息在这一步骤完全丢失
(2) 有时候有些强特征会出现多次,比如我们常见的TF.IDF公式,TF就是指某个特征出现的次数,出现次数越多说明这个特征越强,但是因为Max Pooling只保留一个最大值,所以即使某个特征出现多次,现在也只能看到一次,就是说同一特征的强度信息丢失了。
改进
K-Max Pooling 和Chunk-Max Pooling
K-Max Pooling是一种全局取Top K特征的操作方式,而Chunk-Max Pooling则是先分段,在分段内包含特征数据里面取最大值,所以其实是一种局部Top K的特征抽取方式。
CNN的前向传播
输入层到卷积层
a
2
=
σ
(
z
2
)
=
σ
(
a
1
∗
W
2
+
b
2
)
a^2 = \sigma(z^2) = \sigma(a^1*W^2+b^2)
a2=σ(z2)=σ(a1∗W2+b2)
第
l
l
l层卷积,星号代表卷积:
a
l
=
R
e
L
U
(
z
l
)
=
R
e
L
U
(
W
l
∗
a
l
−
1
+
b
l
)
a^l = ReLU(z^l) = ReLU(W^l*a^{l - 1} + b^l)
al=ReLU(zl)=ReLU(Wl∗al−1+bl)
第
l
l
l层池化:
a
l
=
p
o
o
l
(
a
l
−
1
)
a^l = pool(a^{l - 1})
al=pool(al−1)
第
l
l
l层全连接层:
a
l
=
σ
(
z
l
)
=
σ
(
W
l
a
l
−
1
+
b
l
)
a^l = \sigma (z^l) = \sigma(W^la^{l-1} + b^l)
al=σ(zl)=σ(Wlal−1+bl)
输出层:
a
L
=
s
o
f
t
m
a
x
(
z
L
)
=
s
o
f
t
m
a
x
(
W
L
a
L
−
1
+
b
L
)
a^L=softmax(z^L) = softmax(W^La^{L-1} + b^L)
aL=softmax(zL)=softmax(WLaL−1+bL)
CNN的反向传播
参考: https://www.cnblogs.com/pinard/p/6494810.html
从DNN的反向传播算法到CNN,有几个问题需要解决:
- 池化层没有激活函数 ,这个问题比较好解决,当作是线性激活函数即可
- 池化层在前向传播时,对输入进行压缩
- 卷积层是通过张量卷积,或者说若干个矩阵卷积求和而得的当前层的输出
- 对于卷积层,由于 W W W使用的运算是卷积,那么 δ l \delta^l δl推导出改成的所有卷积核的 W , b W,b W,b的方式也不同
(1) 线性激活函数,
σ
(
z
)
=
z
\sigma(z) = z
σ(z)=z,反向传播值为1
(2)已知池化层
δ
l
\delta^l
δl,推导上一隐藏层的
δ
l
−
1
\delta^{l-1}
δl−1:
在求导时需要将
δ
l
\delta^l
δl的所有子矩阵矩阵大小还原成之前的大小,该操作称为upsample
δ
k
l
−
1
=
(
∂
a
k
l
−
1
∂
z
k
l
−
1
)
T
∂
J
(
W
,
b
)
∂
a
k
l
−
1
=
u
psample
(
δ
k
l
)
⊙
σ
′
(
z
k
l
−
1
)
\delta_{k}^{l-1}=\left(\frac{\partial a_{k}^{l-1}}{\partial z_{k}^{l-1}}\right)^{T} \frac{\partial J(W, b)}{\partial a_{k}^{l-1}}=u \text {psample}\left(\delta_{k}^{l}\right) \odot \sigma^{\prime}\left(z_{k}^{l-1}\right)
δkl−1=(∂zkl−1∂akl−1)T∂akl−1∂J(W,b)=upsample(δkl)⊙σ′(zkl−1)
(3)一直卷积层
δ
l
\delta^l
δl,推导上一隐藏层的
δ
l
−
1
\delta^{l-1}
δl−1
δ
l
−
1
=
∂
J
(
W
,
b
)
∂
z
l
−
1
=
(
∂
z
l
∂
z
l
−
1
)
T
∂
J
(
W
,
b
)
∂
z
l
=
(
∂
z
l
∂
z
l
−
1
)
T
δ
l
=
δ
l
∗
r
o
t
180
(
W
l
)
⊙
σ
′
(
z
l
−
1
)
\delta^{l-1}=\frac{\partial J(W, b)}{\partial z^{l-1}}=\left(\frac{\partial z^{l}}{\partial z^{l-1}}\right)^{T} \frac{\partial J(W, b)}{\partial z^{l}}=\left(\frac{\partial z^{l}}{\partial z^{l-1}}\right)^{T} \delta^{l}=\delta^l*rot180(W^l) \odot \sigma^{\prime}(z^{l-1})
δl−1=∂zl−1∂J(W,b)=(∂zl−1∂zl)T∂zl∂J(W,b)=(∂zl−1∂zl)Tδl=δl∗rot180(Wl)⊙σ′(zl−1)
这个式子与DNN的类似,区别在于对于含有卷积的式子求导时,卷积核被旋转了180度,即式子中的
r
o
t
180
(
)
rot180()
rot180(),翻转180度的意思是上下翻转一次,接着左右反转一次.
(
a
11
a
12
a
13
a
21
a
22
a
23
a
31
a
32
a
33
)
∗
(
w
11
w
12
w
21
w
22
)
=
(
z
11
z
12
z
21
z
22
)
\left(\begin{array}{lll}{a_{11}} & {a_{12}} & {a_{13}} \\ {a_{21}} & {a_{22}} & {a_{23}} \\ {a_{31}} & {a_{32}} & {a_{33}}\end{array}\right) *\left(\begin{array}{cc}{w_{11}} & {w_{12}} \\ {w_{21}} & {w_{22}}\end{array}\right)=\left(\begin{array}{cc}{z_{11}} & {z_{12}} \\ {z_{21}} & {z_{22}}\end{array}\right)
⎝⎛a11a21a31a12a22a32a13a23a33⎠⎞∗(w11w21w12w22)=(z11z21z12z22)
(
0
0
0
0
0
δ
11
δ
12
0
0
δ
21
δ
22
0
0
0
0
0
)
∗
(
w
22
w
21
w
12
w
11
)
=
(
∇
a
11
∇
a
12
∇
a
13
∇
a
21
∇
a
22
∇
a
23
∇
a
31
∇
a
32
∇
a
33
)
\left(\begin{array}{cccc}{0} & {0} & {0} & {0} \\ {0} & {\delta_{11}} & {\delta_{12}} & {0} \\ {0} & {\delta_{21}} & {\delta_{22}} & {0} \\ {0} & {0} & {0} & {0}\end{array}\right) *\left(\begin{array}{cc}{w_{22}} & {w_{21}} \\ {w_{12}} & {w_{11}}\end{array}\right)=\left(\begin{array}{ccc}{\nabla a_{11}} & {\nabla a_{12}} & {\nabla a_{13}} \\ {\nabla a_{21}} & {\nabla a_{22}} & {\nabla a_{23}} \\ {\nabla a_{31}} & {\nabla a_{32}} & {\nabla a_{33}}\end{array}\right)
⎝⎜⎜⎛00000δ11δ2100δ12δ2200000⎠⎟⎟⎞∗(w22w12w21w11)=⎝⎛∇a11∇a21∇a31∇a12∇a22∇a32∇a13∇a23∇a33⎠⎞
(4)已知卷积层的
δ
l
\delta^l
δl,推导该层的
W
,
b
W,b
W,b的梯度
对于全连接层可以按照DNN的反向传播算法求该层
W
,
b
W,b
W,b的梯度,而池化层并没有
W
,
b
W,b
W,b,也不用求
W
,
b
W,b
W,b的梯度。只有卷积层的
W
,
b
W,b
W,b需要求出
注意到卷积层
z
z
z和
W
,
b
W,b
W,b的关系为:
z
l
=
a
l
−
1
∗
W
l
+
b
z^l=a^{l-1}*W^l + b
zl=al−1∗Wl+b
因此有:
∂
J
(
W
,
b
)
∂
W
l
=
a
l
−
1
∗
δ
l
\frac{\partial J(W, b)}{\partial W^{l}}=a^{l-1} * \delta^{l}
∂Wl∂J(W,b)=al−1∗δl
【注意】此时卷积核并没有反转,主要是此时是层内进行求导,而不是反向传播到上一层的求导
对于
b
b
b,稍微有些特殊,因为
δ
l
\delta^l
δl是高维张量,而
b
b
b只有一个张量,不能像DNN那样直接和
δ
l
\delta^l
δl相等。通常的做法是将
δ
l
\delta^l
δl的各个子矩阵的项分别求和,得到一个误差项量,即为
b
b
b的梯度
∂
J
(
W
,
b
)
∂
b
l
=
∑
u
,
v
(
δ
l
)
u
,
v
\frac{\partial J(W, b)}{\partial b^{l}}=\sum_{u, v}\left(\delta^{l}\right)_{u, v}
∂bl∂J(W,b)=u,v∑(δl)u,v
RNN
什么是循环神经网络?循环神经网络的基本结构是怎样的?
**循环神经网络是一类具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其它神经元的信息,也可以接受自身的信息,形成具有环路的网络结构。**和前馈神经网络相比,循环神经网络更加符合生物神经网络的结构。循环神经网络已经被广泛应用在语音识别、语言模型以及自然语言生成等任务上。循环神经网络的参数学习可以通过随时间反向传播算法来学习。随时间反向传播算法即按照时间的逆序将错误信息一步步地往前传递。当输入序列比较长时,会存在梯度爆炸和消失问题,也称为长期依赖问题。 为了解决这个问题,人么对循环神经网络进行了很多的改进,**其中最有效的改进方式引入门控机制。**此外,循环神经网络可以很容易地扩展到两种更广义的记忆网络模型:递归神经网络和图网络。
RNN的大致思路,RNN的结构图
H
t
=
ϕ
(
X
t
W
x
h
+
H
t
−
1
W
h
h
+
b
h
)
\boldsymbol{H}_{t}=\phi\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h h}+\boldsymbol{b}_{h}\right)
Ht=ϕ(XtWxh+Ht−1Whh+bh)
与多层感知机相比,RNN多了
H
t
−
1
W
h
h
H_{t - 1} W_{hh}
Ht−1Whh一项。隐藏变量
H
t
H_t
Ht能够捕获截止当前时间步的序列的历史信息
循环神经网络RNN常见的几种设计模式是怎样的?
- 序列到类别模式
- 同步序列到序列模式
- 异步的序列到序列模式
RNN前向传播算法
对于任意一个序列索引号
t
t
t,隐藏状态
h
(
t
)
h^{(t)}
h(t)有
x
(
t
)
x^{(t)}
x(t)和
h
(
t
−
1
)
h^{(t-1)}
h(t−1)得到:
h
(
t
)
=
σ
(
z
(
t
)
)
=
σ
(
U
x
(
t
)
+
W
h
(
t
−
1
)
+
b
)
h^{(t)}=\sigma\left(z^{(t)}\right)=\sigma\left(U x^{(t)}+W h^{(t-1)}+b\right)
h(t)=σ(z(t))=σ(Ux(t)+Wh(t−1)+b)
其中
σ
\sigma
σ为RNN的激活函数,通常为
t
a
n
h
,
b
tanh,b
tanh,b为偏置
序列索引号
t
t
t时模型的输出
o
(
t
)
o^{(t)}
o(t)的表达式比较简单
o
(
t
)
=
V
h
(
t
)
+
c
o^{(t)} = Vh^{(t)} + c
o(t)=Vh(t)+c
最终在序列索引号
t
t
t时我们的预测输出为:
y
^
(
t
)
=
σ
(
o
(
t
)
)
\hat{y}^{(t)}=\sigma\left(o^{(t)}\right)
y^(t)=σ(o(t))
通常由于RNN是识别类的分类模型,所以上面这个激活函数一般是softmax.
RNN反向传播算法推导
U
,
W
,
V
,
b
,
c
U,W,V,b,c
U,W,V,b,c在序列的各个位置时共享的,反向传播时更新的是相同的参数
为简化描述,损失函数使用交叉熵损失函数,输出的激活函数为softmax函数,隐藏层的激活函数为tanh
【说明】
t
a
n
h
′
(
x
)
=
1
−
t
a
n
h
2
(
x
)
tanh^{\prime}(x) = 1 - tanh^2(x)
tanh′(x)=1−tanh2(x)对求
δ
(
t
)
\delta^{(t)}
δ(t)有用
对于RNN,由于我们在序列的每个位置都有损失函数,因此最终的损失
L
L
L为:
L
=
∑
t
=
1
τ
L
(
t
)
L=\sum_{t=1}^{\tau} L^{(t)}
L=t=1∑τL(t)
其中
V
,
c
V,c
V,c的梯度计算时比较简单的
∂
L
∂
c
=
∑
t
=
1
τ
∂
L
(
t
)
∂
c
=
∑
t
=
1
τ
(
y
^
(
t
)
−
y
(
t
)
)
∂
L
∂
V
=
∑
t
=
1
τ
∂
L
(
t
)
∂
V
=
∑
t
=
1
τ
(
y
^
(
t
)
−
y
(
t
)
)
(
h
(
t
)
)
T
\begin{array}{c}{\frac{\partial L}{\partial c}=\sum_{t=1}^{\tau} \frac{\partial L^{(t)}}{\partial c}=\sum_{t=1}^{\tau} ( \hat{y}^{(t)}-y^{(t)}} ) \\ {\frac{\partial L}{\partial V}=\sum_{t=1}^{\tau} \frac{\partial L^{(t)}}{\partial V}=\sum_{t=1}^{\tau}\left(\hat{y}^{(t)}-y^{(t)}\right)\left(h^{(t)}\right)^{T}}\end{array}
∂c∂L=∑t=1τ∂c∂L(t)=∑t=1τ(y^(t)−y(t))∂V∂L=∑t=1τ∂V∂L(t)=∑t=1τ(y^(t)−y(t))(h(t))T
定义序列索引
t
t
t位置的隐藏状态的梯度:
δ
(
t
)
=
∂
L
∂
h
(
t
)
\delta^{(t)}=\frac{\partial L}{\partial h^{(t)}}
δ(t)=∂h(t)∂L
δ
(
t
)
=
(
∂
o
(
t
)
∂
h
(
t
)
)
T
∂
L
∂
o
(
t
)
+
(
∂
h
(
t
+
1
)
∂
h
(
t
)
)
T
∂
L
∂
h
(
t
+
1
)
=
V
T
(
y
^
(
t
)
−
y
(
t
)
)
+
W
T
diag
(
1
−
(
h
(
t
+
1
)
)
2
)
δ
(
t
+
1
)
\delta^{(t)}=\left(\frac{\partial o^{(t)}}{\partial h^{(t)}}\right)^{T} \frac{\partial L}{\partial o^{(t)}}+\left(\frac{\partial h^{(t+1)}}{\partial h^{(t)}}\right)^{T} \frac{\partial L}{\partial h^{(t+1)}}=V^{T}\left(\hat{y}^{(t)}-y^{(t)}\right)+W^{T} \operatorname{diag}\left(1-\left(h^{(t+1)}\right)^{2}\right) \delta^{(t+1)}
δ(t)=(∂h(t)∂o(t))T∂o(t)∂L+(∂h(t)∂h(t+1))T∂h(t+1)∂L=VT(y^(t)−y(t))+WTdiag(1−(h(t+1))2)δ(t+1)
对于
δ
τ
\delta^{\tau}
δτ,由于后面没有其他序列索引,因此有:
δ
(
τ
)
=
(
∂
o
(
τ
)
∂
h
(
τ
)
)
T
∂
L
∂
o
(
τ
)
=
V
T
(
y
^
(
τ
)
−
y
(
τ
)
)
\delta^{(\tau)}=\left(\frac{\partial o^{(\tau)}}{\partial h^{(\tau)}}\right)^{T} \frac{\partial L}{\partial o^{(\tau)}}=V^{T}\left(\hat{y}^{(\tau)}-y^{(\tau)}\right)
δ(τ)=(∂h(τ)∂o(τ))T∂o(τ)∂L=VT(y^(τ)−y(τ))
所以计算
W
,
U
,
b
W,U,b
W,U,b梯度计算表达式:
∂
L
∂
W
=
∑
t
=
1
τ
diag
(
1
−
(
h
(
t
)
)
2
)
δ
(
t
)
(
h
(
t
−
1
)
)
T
∂
L
∂
b
=
∑
t
=
1
τ
diag
(
1
−
(
h
(
t
)
)
2
)
δ
(
t
)
∂
L
∂
U
=
∑
t
=
1
τ
diag
(
1
−
(
h
(
t
)
)
2
)
δ
(
t
)
(
x
(
t
)
)
T
\begin{array}{c}{\frac{\partial L}{\partial W}=\sum_{t=1}^{\tau} \operatorname{diag}\left(1-\left(h^{(t)}\right)^{2}\right) \delta^{(t)}\left(h^{(t-1)}\right)^{T}} \\ {\frac{\partial L}{\partial b}=\sum_{t=1}^{\tau} \operatorname{diag}\left(1-\left(h^{(t)}\right)^{2}\right) \delta^{(t)}} \\ {\frac{\partial L}{\partial U}=\sum_{t=1}^{\tau} \operatorname{diag}\left(1-\left(h^{(t)}\right)^{2}\right) \delta^{(t)}\left(x^{(t)}\right)^{T}}\end{array}
∂W∂L=∑t=1τdiag(1−(h(t))2)δ(t)(h(t−1))T∂b∂L=∑t=1τdiag(1−(h(t))2)δ(t)∂U∂L=∑t=1τdiag(1−(h(t))2)δ(t)(x(t))T
循环神经网络RNN怎样进行参数学习?
随时间反向传播(BPTT)算法的主要思想是通过类似前馈神经网络的错误反向传播算法来进行计算梯度。BPTT算法将循环神经网络看作是一个展开的多层前馈网络,其中“每一层”对应循环网络中的“每个时刻”。这样,循环神经网络就可以按照前馈网络中的反向传播算法进行计算参数梯度。在“展开”的前馈网络中,所有层的参数是共享的。因此参数的真实梯度是将所有“展开层”的参数梯度之和。
δ
t
,
k
=
∂
L
t
∂
z
k
=
∂
h
k
∂
z
k
∂
z
k
+
1
∂
h
k
∂
L
t
∂
z
k
+
1
=
diag
(
f
′
(
z
k
)
)
U
T
δ
t
,
k
+
1
\begin{aligned} \delta_{t, k} &=\frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k}} \\ &=\frac{\partial \mathbf{h}_{k}}{\partial \mathbf{z}_{k}} \frac{\partial \mathbf{z}_{k+1}}{\partial \mathbf{h}_{k}} \frac{\partial \mathcal{L}_{t}}{\partial \mathbf{z}_{k+1}} \\ &=\operatorname{diag}\left(f^{\prime}\left(\mathbf{z}_{k}\right)\right) U^{\mathrm{T}} \delta_{t, k+1} \end{aligned}
δt,k=∂zk∂Lt=∂zk∂hk∂hk∂zk+1∂zk+1∂Lt=diag(f′(zk))UTδt,k+1
定义
δ
t
,
k
\delta_{t,k}
δt,k为第t时刻的损失对第k时刻隐藏神经层的净输入
z
k
=
U
h
k
−
1
+
W
x
k
+
b
z_k=Uh_{k-1} + Wx_k +b
zk=Uhk−1+Wxk+b的导数,同样对
U
,
W
U,W
U,W求导则可得到随时间反向传播的公式
∂
L
∂
U
=
∑
t
=
1
T
∑
k
=
1
t
δ
t
,
k
h
k
−
1
T
∂
L
∂
W
=
∑
t
=
1
T
∑
k
=
1
t
δ
t
,
k
x
k
T
∂
L
∂
b
=
∑
t
=
1
T
∑
k
=
1
t
δ
t
,
k
\begin{aligned} \frac{\partial \mathcal{L}}{\partial U}=& \sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{h}_{k-1}^{\mathrm{T}} \\ \frac{\partial \mathcal{L}}{\partial W}=& \sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \mathbf{x}_{k}^{\mathrm{T}} \\ \frac{\partial \mathcal{L}}{\partial \mathbf{b}}=& \sum_{t=1}^{T} \sum_{k=1}^{t} \delta_{t, k} \end{aligned}
∂U∂L=∂W∂L=∂b∂L=t=1∑Tk=1∑tδt,khk−1Tt=1∑Tk=1∑tδt,kxkTt=1∑Tk=1∑tδt,k
BPTT推导
参考: http://zh.gluon.ai/chapter_recurrent-neural-networks/bptt.html
简单起见,考虑一个无偏差的循环神经网络,且激活函数为恒等映射(
ϕ
(
x
)
=
x
\phi(x)=x
ϕ(x)=x),那么隐藏状态
h
t
∈
R
h
\boldsymbol{h}_{t} \in \mathbb{R}^{h}
ht∈Rh的计算表达式为:
h
t
=
W
h
x
x
t
+
W
h
h
h
t
−
1
o
t
=
W
q
h
h
t
\boldsymbol{h}_{t}=\boldsymbol{W}_{h x} \boldsymbol{x}_{t}+\boldsymbol{W}_{h h} \boldsymbol{h}_{t-1} \\ \boldsymbol{o}_{t}=\boldsymbol{W}_{q h} \boldsymbol{h}_{t}
ht=Whxxt+Whhht−1ot=Wqhht
设时间步
t
t
t 的损失为
ℓ
(
o
t
,
y
t
)
\ell\left(\boldsymbol{o}_{t}, y_{t}\right)
ℓ(ot,yt), 时间步数为
T
T
T 的损失函数
L
L
L 定义为
L
=
1
T
∑
t
=
1
T
ℓ
(
o
t
,
y
t
)
L=\frac{1}{T} \sum_{t=1}^{T} \ell\left(\boldsymbol{o}_{t}, y_{t}\right)
L=T1t=1∑Tℓ(ot,yt)
图中模型的参数为 W h x , W h h , W q h W_{hx}, W_{hh}, W_{qh} Whx,Whh,Wqh, 那么训练模型通常需要模型参数的梯度 ∂ L ∂ W h x , ∂ L ∂ W h h , ∂ L ∂ W q h \frac{\partial L}{\partial \boldsymbol{W}_{h x}}, \frac{\partial L}{\partial \boldsymbol{W}_{hh}}, \frac{\partial L}{\partial \boldsymbol{W}_{q h}} ∂Whx∂L,∂Whh∂L,∂Wqh∂L
首先,目标函数有关时间步输出层变量的梯度
∂
L
/
∂
o
t
∈
R
q
\partial L / \partial o_t \in \mathbb{R}^{q}
∂L/∂ot∈Rq会让你容易计算:
∂
L
∂
o
t
=
∂
T
⋅
∂
o
t
∑
t
=
1
T
ℓ
(
o
t
,
y
t
)
=
∂
ℓ
(
o
t
,
y
t
)
T
⋅
∂
o
t
\frac{\partial L}{\partial o_t} = \frac{\partial}{T \cdot \partial o_t} \sum_{t=1}^{T} \ell\left(\boldsymbol{o}_{t}, y_{t}\right)=\frac{\partial \ell\left(\boldsymbol{o}_{t}, y_{t}\right)}{T \cdot \partial \boldsymbol{o}_{t}}
∂ot∂L=T⋅∂ot∂t=1∑Tℓ(ot,yt)=T⋅∂ot∂ℓ(ot,yt)
∂ L ∂ W q h = ∑ t = 1 T prod ( ∂ L ∂ o t , ∂ o t ∂ W q h ) = ∑ t = 1 T ∂ L ∂ o t h t ⊤ \frac{\partial L}{\partial \boldsymbol{W}_{q h}}=\sum_{t=1}^{T} \operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{o}_{t}}, \frac{\partial \boldsymbol{o}_{t}}{\partial \boldsymbol{W}_{q h}}\right)=\sum_{t=1}^{T} \frac{\partial L}{\partial \boldsymbol{o}_{t}} \boldsymbol{h}_{t}^{\top} ∂Wqh∂L=t=1∑Tprod(∂ot∂L,∂Wqh∂ot)=t=1∑T∂ot∂Lht⊤
其中 prod 运算符将根据两个输入的形状,在必要的操作(如转置和互换输入位置)后对两个输入做乘法
在第T个时刻(即最后一个时刻,图中为T=3) ,
h
T
h_T
hT只依赖于
o
T
o_T
oT进行反向传播,因此:
∂
L
∂
h
T
=
prod
(
∂
L
∂
o
T
,
∂
o
T
∂
h
T
)
=
W
q
h
⊤
∂
L
∂
o
T
\frac{\partial L}{\partial \boldsymbol{h}_{T}}=\operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{o}_{T}}, \frac{\partial \boldsymbol{o}_{T}}{\partial \boldsymbol{h}_{T}}\right)=\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{T}}
∂hT∂L=prod(∂oT∂L,∂hT∂oT)=Wqh⊤∂oT∂L
对于时间步
t
<
T
,
h
t
t \lt T,h_t
t<T,ht需要依赖
o
t
o_t
ot和
h
t
+
1
h_{t+1}
ht+1反向传播。依据链式法则,目标函数有关时间步
t
<
T
t\lt T
t<T的隐藏状态的梯度
∂
L
/
∂
h
t
∈
R
h
\partial L / \partial \boldsymbol{h}_{t} \in \mathbb{R}^{h}
∂L/∂ht∈Rh需要按照时间步从打到小依次计算
∂
L
∂
h
t
=
prod
(
∂
L
∂
h
t
+
1
,
∂
h
t
+
1
∂
h
t
)
+
prod
(
∂
L
∂
o
t
,
∂
o
t
∂
h
t
)
=
W
h
h
⊤
∂
L
∂
h
t
+
1
+
W
q
h
⊤
∂
L
∂
o
t
=
W
h
h
⊤
(
W
h
h
⊤
∂
L
∂
h
t
+
2
+
W
q
h
⊤
∂
L
∂
o
t
+
1
)
+
W
q
h
⊤
∂
L
∂
o
t
=
W
h
h
⊤
2
∂
L
∂
h
t
+
2
+
W
h
h
⊤
W
q
h
⊤
∂
L
∂
o
t
+
1
+
W
q
h
⊤
∂
L
∂
o
t
=
W
h
h
⊤
3
∂
L
∂
h
t
+
3
+
W
h
h
⊤
2
W
q
h
⊤
∂
L
∂
o
t
+
2
+
W
h
h
⊤
W
q
h
⊤
∂
L
∂
o
t
+
1
+
W
q
h
⊤
∂
L
∂
o
t
=
∑
i
=
t
T
(
W
h
h
⊤
)
T
−
i
W
q
h
⊤
∂
L
∂
o
T
+
t
−
i
(BPTT-1)
\frac{\partial L}{\partial \boldsymbol{h}_{t}}=\operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{h}_{t+1}}, \frac{\partial \boldsymbol{h}_{t+1}}{\partial \boldsymbol{h}_{t}}\right)+\operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{o}_{t}}, \frac{\partial \boldsymbol{o}_{t}}{\partial \boldsymbol{h}_{t}}\right) \\ =\boldsymbol{W}_{h h}^{\top} \frac{\partial L}{\partial \boldsymbol{h}_{t+1}}+\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t}} \\ = \boldsymbol{W}_{h h}^{\top} \left(\boldsymbol{W}_{h h}^{\top} \frac{\partial L}{\partial \boldsymbol{h}_{t+2}}+\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t+1}} \right)+\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t}} \\ = {\boldsymbol{W}_{h h}^{\top} }^2 \frac{\partial L}{\partial \boldsymbol{h}_{t+2}} + \boldsymbol{W}_{h h}^{\top} \boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t+1}} +\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t}} \\ = {\boldsymbol{W}_{h h}^{\top} }^3 \frac{\partial L}{\partial \boldsymbol{h}_{t+3}} + {\boldsymbol{W}_{h h}^{\top} }^2\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t+2}}+\boldsymbol{W}_{h h}^{\top} \boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t+1}} +\boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{t}} \\ =\sum_{i=t}^{T}\left(\boldsymbol{W}_{h h}^{\top}\right)^{T-i} \boldsymbol{W}_{q h}^{\top} \frac{\partial L}{\partial \boldsymbol{o}_{T+t-i}} \tag{BPTT-1}
∂ht∂L=prod(∂ht+1∂L,∂ht∂ht+1)+prod(∂ot∂L,∂ht∂ot)=Whh⊤∂ht+1∂L+Wqh⊤∂ot∂L=Whh⊤(Whh⊤∂ht+2∂L+Wqh⊤∂ot+1∂L)+Wqh⊤∂ot∂L=Whh⊤2∂ht+2∂L+Whh⊤Wqh⊤∂ot+1∂L+Wqh⊤∂ot∂L=Whh⊤3∂ht+3∂L+Whh⊤2Wqh⊤∂ot+2∂L+Whh⊤Wqh⊤∂ot+1∂L+Wqh⊤∂ot∂L=i=t∑T(Whh⊤)T−iWqh⊤∂oT+t−i∂L(BPTT-1)
由上式中的指数项可见,当时间步数T较大或者时间步t较小时,目标函数有关隐藏状态的梯度较容易出现衰减或爆炸。这也会影响其他包含
∂
L
/
∂
h
t
\partial L / \partial \boldsymbol{h}_{t}
∂L/∂ht的梯度。
∂ L ∂ W h x = ∑ t = 1 T prod ( ∂ L ∂ h t , ∂ h t ∂ W h x ) = ∑ t = 1 T ∂ L ∂ h t x t ⊤ ∂ L ∂ W h h = ∑ t = 1 T prod ( ∂ L ∂ h t , ∂ h t ∂ W h h ) = ∑ t = 1 T ∂ L ∂ h t h t − 1 ⊤ \begin{aligned} \frac{\partial L}{\partial \boldsymbol{W}_{h x}} &=\sum_{t=1}^{T} \operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{h}_{t}}, \frac{\partial \boldsymbol{h}_{t}}{\partial \boldsymbol{W}_{h x}}\right)=\sum_{t=1}^{T} \frac{\partial L}{\partial \boldsymbol{h}_{t}} \boldsymbol{x}_{t}^{\top} \\ \frac{\partial L}{\partial \boldsymbol{W}_{h h}} &=\sum_{t=1}^{T} \operatorname{prod}\left(\frac{\partial L}{\partial \boldsymbol{h}_{t}}, \frac{\partial \boldsymbol{h}_{t}}{\partial \boldsymbol{W}_{h h}}\right)=\sum_{t=1}^{T} \frac{\partial L}{\partial \boldsymbol{h}_{t}} \boldsymbol{h}_{t-1}^{\top} \end{aligned} ∂Whx∂L∂Whh∂L=t=1∑Tprod(∂ht∂L,∂Whx∂ht)=t=1∑T∂ht∂Lxt⊤=t=1∑Tprod(∂ht∂L,∂Whh∂ht)=t=1∑T∂ht∂Lht−1⊤
RNN中为什么会出现梯度消失或梯度爆炸,如何处理?
RNN产生长期依赖的原因与参数学习BPTT过程有关,实质就是参数
U
U
U 的更新主要靠当前时刻$k $的几个相邻状态
h
k
h_k
hk来更新,长距离的状态对
U
U
U没有影响。将
δ
t
,
k
\delta_{t,k}
δt,k展开可得到:
δ
t
,
k
=
∏
i
=
k
t
−
1
(
diag
(
f
′
(
z
i
)
)
U
T
)
δ
t
,
t
\delta_{t, k}=\prod_{i=k}^{t-1}\left(\operatorname{diag}\left(f^{\prime}\left(z_{i}\right)\right) U^{T}\right) \delta_{t, t}
δt,k=i=k∏t−1(diag(f′(zi))UT)δt,t
如果令
γ
≃
∥
diag
f
′
(
z
i
)
U
T
∥
\gamma \simeq\left\|\operatorname{diag} f^{\prime}\left(z_{i}\right) U^{T}\right\|
γ≃∥∥diagf′(zi)UT∥∥,可得到:
δ
t
,
k
=
γ
t
−
k
δ
t
,
t
\delta_{t, k}=\gamma^{t-k} \delta_{t, t}
δt,k=γt−kδt,t
若
γ
>
1
\gamma \gt 1
γ>1, 当
t
−
k
→
∞
t-k \rightarrow \infty
t−k→∞造成系统不稳定,称为梯度爆炸问题, 相反,若
γ
<
1
\gamma \lt 1
γ<1,当
t
−
k
→
∞
t-k \rightarrow \infty
t−k→∞时会出现和深度前馈神经网络类似的梯度消失问题
在循环神经网络中的梯度消失不是说
α
L
α
U
\frac{\alpha L}{\alpha U}
αUαL的梯度消失了,而是当
t
−
k
→
∞
t-k \rightarrow \infty
t−k→∞时
δ
t
,
k
\delta_{t,k}
δt,k的梯度消失了。也就是说,参数
U
U
U的更新主要靠当前时刻
k
k
k的几个相邻状态
h
k
h_k
hk来更新,长距离的状态对
U
U
U没有影响
对于梯度爆炸可以采用梯度裁剪和正则化的方式进行处理。 对于梯度消失可以修改激活函数ReLU,添加门控、使用Batch Normalization以及使用ResNet等方式
为什么在FC/CNN等结构中将原先的sigmoid、tanh换成ReLU可以取得比较好的效果
因为在链式求导时,sigmoid和tanh经常会导致网络出现梯度消失的问题,而relu函数的的改进就是使得导数均为1,无论神经网络是多少层,这部分的乘积始终为1,因此深层的梯度也可以传递到浅层中
RNN中为什么要采用tanh而不是ReLu作为激活函数?
参考: https://www.zhihu.com/question/61265076/answer/186347780
- RNN中将激活函数换成Relu会导致非常大的输出值,与CNN这些每一层使用独立的参数 W i W_i Wi不同,原始的RNN在每个阶段都共享一个参数W。如果我们假设从某一层开始输入 x i x_i xi 和偏置 b i b_i bi 都为0,那么最后得到的输出就是 f [ W . . . [ W f [ W f [ W f i ] ] ] ] f[W...[Wf[Wf[Wf_i]]]] f[W...[Wf[Wf[Wfi]]]] ,这在某种程度上相当于对参数矩阵 W 作连乘,很显然,只要 W 有一个大于1的特征值,在经过若干次连乘后都会导致结果是一个数值非常庞大的矩阵。
- Relu不能解决梯度在长距离上传递的问题,容易导致梯度爆炸。
- 对于 W W W和 b i b_i bi取特殊初值: W = I , b i = 0 W=I, b_i=0 W=I,bi=0的时候, 使用Relu函数,也能获得比较好的效果
应对梯度爆炸可以进行梯度的裁剪。
GRU
R
t
=
σ
(
X
t
W
x
r
+
H
t
−
1
W
h
r
+
b
r
)
Z
t
=
σ
(
X
t
W
x
z
+
H
t
−
1
W
h
z
+
b
z
)
H
~
t
=
tanh
(
X
t
W
x
h
+
(
R
t
⊙
H
t
−
1
)
W
h
h
+
b
h
)
H
t
=
Z
t
⊙
H
t
−
1
+
(
1
−
Z
t
)
⊙
H
~
t
\begin{aligned} \boldsymbol{R}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x r}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h r}+\boldsymbol{b}_{r}\right) \\ \boldsymbol{Z}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x z}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h z}+\boldsymbol{b}_{z}\right) \end{aligned} \\ \tilde{\boldsymbol{H}}_{t}=\tanh \left(\boldsymbol{X}_{t} \boldsymbol{W}_{x h}+\left(\boldsymbol{R}_{t} \odot \boldsymbol{H}_{t-1}\right) \boldsymbol{W}_{h h}+\boldsymbol{b}_{h}\right) \\ \boldsymbol{H}_{t}=\boldsymbol{Z}_{t} \odot \boldsymbol{H}_{t-1}+\left(1-\boldsymbol{Z}_{t}\right) \odot \tilde{\boldsymbol{H}}_{t}
RtZt=σ(XtWxr+Ht−1Whr+br)=σ(XtWxz+Ht−1Whz+bz)H~t=tanh(XtWxh+(Rt⊙Ht−1)Whh+bh)Ht=Zt⊙Ht−1+(1−Zt)⊙H~t
LSTM
公式与图参考: https://zh.gluon.ai/chapter_recurrent-neural-networks/lstm.html
I
t
=
σ
(
X
t
W
x
i
+
H
t
−
1
W
h
i
+
b
i
)
F
t
=
σ
(
X
t
W
x
f
+
H
t
−
1
W
h
f
+
b
f
)
O
t
=
σ
(
X
t
W
x
o
+
H
t
−
1
W
h
o
+
b
o
)
C
~
t
=
tanh
(
X
t
W
x
c
+
H
t
−
1
W
h
c
+
b
c
)
C
t
=
F
t
⊙
C
t
−
1
+
I
t
⊙
C
~
t
H
t
=
O
t
⊙
tanh
(
C
t
)
\begin{aligned} \boldsymbol{I}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x i}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h i}+\boldsymbol{b}_{i}\right) \\ \boldsymbol{F}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x f}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h f}+\boldsymbol{b}_{f}\right) \\ \boldsymbol{O}_{t} &=\sigma\left(\boldsymbol{X}_{t} \boldsymbol{W}_{x o}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h o}+\boldsymbol{b}_{o}\right) \end{aligned} \\\tilde{\boldsymbol{C}}_{t}=\tanh \left(\boldsymbol{X}_{t} \boldsymbol{W}_{x c}+\boldsymbol{H}_{t-1} \boldsymbol{W}_{h c}+\boldsymbol{b}_{c}\right) \\\boldsymbol{C}_{t}=\boldsymbol{F}_{t} \odot \boldsymbol{C}_{t-1}+\boldsymbol{I}_{t} \odot \tilde{\boldsymbol{C}}_{t} \\ \boldsymbol{H}_{t}=\boldsymbol{O}_{t} \odot \tanh \left(\boldsymbol{C}_{t}\right)
ItFtOt=σ(XtWxi+Ht−1Whi+bi)=σ(XtWxf+Ht−1Whf+bf)=σ(XtWxo+Ht−1Who+bo)C~t=tanh(XtWxc+Ht−1Whc+bc)Ct=Ft⊙Ct−1+It⊙C~tHt=Ot⊙tanh(Ct)
LSTM中既存在tanh和sigmoid,为什么不统一采用一样的?
sigmoid用在了各种gate上,产生0~1之间的值,这个一般只有sigmoid最直接了。门是控制开闭的,全开始值为1,全闭时值为0,有开有闭时只在0到1之间。如果选择的激活函数得到的值不在0和1之间,通常来说是没有意义的。
tanh用在了状态和输出上,是对数据的处理。其实这里的激活函数的选取没有什么行与不行,只有好与不好而已。
LSTM各个单元作用分析
输出门
o
t
−
1
o_{t-1}
ot−1: 输出门的目的是从细胞状态
c
t
−
1
c_{t-1}
ct−1产生隐层单元
h
t
−
1
h_{t-1}
ht−1。并不是
c
t
−
1
c_{t-1}
ct−1中的全部信息都和隐层单元
h
t
−
1
h_{t-1}
ht−1有关,
c
t
−
1
c_{t-1}
ct−1可能包含了很多对
h
t
−
1
h_{t-1}
ht−1无用的信息。因此
o
t
o_t
ot的作用就是判断
c
t
−
1
c_{t-1}
ct−1中哪些部分是对
h
t
−
1
h_{t-1}
ht−1有用的,哪些部分是无用的。
输入门
i
t
i_t
it:
i
t
i_t
it控制当前词
x
t
x_t
xt的信息融入细胞状态
c
t
c_t
ct。在理解一句话时,当前词
x
t
x_t
xt可能对整句话的意思很重要,也可能并不重要。输入门的目的就是判断当前词
x
t
x_t
xt对全局的重要性。当
i
t
i_t
it开关打开的时候,网络将不考虑当前输入
x
t
x_t
xt。
遗忘门
f
t
f_t
ft:
f
t
f_t
ft控制上一时刻细胞状态
c
t
−
1
c_{t-1}
ct−1的信息融入细胞状态
c
t
c_t
ct。在理解一句话时,当前词
x
t
x_t
xt可能还继续延续上文的意思继续描述,也可能从当前词
x
t
x_t
xt开始描述新的内容,与上文无关。在输入门
i
t
i_t
it相反,
f
t
f_t
ft不对当前词
x
t
x_t
xt的重要性作判断,而判断的是上一时刻的细胞状态
c
t
−
1
c_{t-1}
ct−1对计算当前细胞状态
c
t
c_t
ct的重要性。当
f
t
f_t
ft开关打开的时候,网络将不考虑上一时刻的细胞状态
c
t
−
1
c_{t-1}
ct−1。
细胞状态
c
t
c_t
ct:
c
t
c_t
ct综合了当前词
x
t
x_t
xt和前一时刻细胞状态
c
t
−
1
c_{t-1}
ct−1的信息。这和ResNet中的残差逼近思想十分相似,通过从
c
t
−
1
c_{t-1}
ct−1到
c
t
c_t
ct的“短路连接”,梯度得以有效地反向传播。当
f
t
f_t
ft处于闭合状态时,
c
t
c_t
ct的梯度可以直接沿着最下面这条短路线传递到
c
t
−
1
c_{t-1}
ct−1,不受参数
W
x
h
W_{xh}
Wxh和
W
h
h
W_{hh}
Whh的影响,这是LSTM能有效地缓解梯度消失现象的关键所在。【LSTM为什么能够缓解梯度消失】
LSTM能够处理不定长的输入,但在tf中为什么还要指定长度进行补全操作?
主要目的是为了能够使用矩阵表示,这样在计算的时候才能进行并行化的操作,加快速度。
LSTM和GRU的区别
- GRU和LSTM的性能在很多任务上很接近,但GRU参数更少,因此更容易收敛,但是数据集很大的情况下,LSTM表达性能更好
- 从结构上来说,GRU只有两个门(update和reset),LSTM有三个门(forget、input和output), GRU直接将hidden state传个下一个单元,而LSTM则用memory cell把hidden state包装起来。