文章目录
1 循环神经网络
1.1 场景与多种应用
1 模仿论文生成
2 模仿linux内核编写代码
3 模仿小四写论文
4 机器翻译
5 image to text 看图说话
1.2 RNN网络结构
1.2.1为什么需要RNN
传统神经网络输入和输出是互相独立的。
我是中国人,我的母语是____。这里完形填空的结果是与前面的词相关的。
RNN引入 记忆 的概念。循环:来源于每个元素执行相同的任务。输出依赖于 输入和记忆。
有时间 顺序上的依赖,都可以使用RNN。例如一段时间内的销量。也就是说RNN不仅仅可以用于解决NLP问题。
推荐系统下也可以使用RNN。
1.2.2 RNN 结构
x
t
x_t
xt是时间t处的输入。例如时间t的词向量。
s
t
s_t
st是时间t处的记忆。
o
t
o_t
ot是时间t处的输出。例如预测下个词的话,可能是每个词出现的概率。
公式:
S
t
=
f
(
U
X
t
+
W
S
t
−
1
)
S_t=f(UX_t+WS_{t-1})
St=f(UXt+WSt−1) f可以是tanh等函数。
O
t
=
s
o
f
t
m
a
x
(
V
S
t
)
O_t=softmax(VS_t)
Ot=softmax(VSt)
例如
X
t
X_t
Xt可以是一个1000x1的向量,U是一个800x1000的矩阵,W是一个800x800的矩阵,这样
S
t
S_t
St就是一个800x1的向量。
V是一个4万x800的矩阵。(4万是词汇量)
说明:
1 隐状态
s
t
s_t
st是记忆体,捕捉了之前时间点上的信息。例如现在你读高三,
s
t
s_t
st就是你在高一,高二,高三学习内容的记忆。
2 o t o_t ot是通过之前所有时间以及当前记忆共同得到的。
3 由于容量问题, s t s_t st并不能记住所有内容。
4 RNN共享一组参数:U、W、V。可以这样理解,你就是你,你用同一套学习方法学习了高一、高二、高三的内容。
5 有些情况下,不需要每个时间都有 o t o_t ot,只需要在最后时间有输出即可。例如文本分类。
RNN唐诗生成器
1.3 多种RNN
1 双向RNN
有些时候,输出依赖于之前和之后的序列元素。
h
⃗
t
=
f
(
W
⃗
x
t
+
V
⃗
h
⃗
t
−
1
+
b
⃗
)
\vec h_t = f(\vec Wx_t+\vec V\vec h_{t-1}+\vec b)
ht=f(Wxt+Vht−1+b)
h
←
t
=
f
(
W
←
x
t
+
V
←
h
←
t
+
1
+
b
←
)
\overleftarrow{h}_{t}=f\left(\overleftarrow{W} x_{t}+\overleftarrow{V} \overleftarrow{h}_{t+1}+\overleftarrow{b}\right)
ht=f(Wxt+Vht+1+b)
y
t
=
g
(
U
[
h
⃗
t
;
h
←
t
]
+
c
)
y_{t}=g\left(U\left[\vec{h}_{t} ; \overleftarrow{h}_t\right]+c\right)
yt=g(U[ht;ht]+c)
从左向右计算记忆 h ⃗ t \vec h_t ht,从右向左计算记忆 h ← t \overleftarrow{h}_t ht, U [ h ⃗ t ; h ← t ] U\left[\vec{h}_{t} ; \overleftarrow{h}_t\right] U[ht;ht]是对两个矩阵做拼接。
h和s的含义相同,表示记忆。
左右信息融合,使用的是concat拼接的方法。
2 深层双向RNN
图中的h和之前的S是等价的。
这样的网络可以这样理解。高考前的多轮复习。高三内容有很多章,每个时间t学习一章。复习呢进行了多轮。按照图中是三轮。
h
⃗
t
(
i
)
=
f
(
W
⃗
(
i
)
h
t
(
i
−
1
)
+
V
⃗
(
i
)
h
⃗
t
−
1
(
i
)
+
b
⃗
(
i
)
)
\vec h_t^{(i)} = f(\vec W^{(i)}h_t^{(i-1)}+\vec V^{(i)}\vec h_{t-1}^{(i)}+\vec b^{(i)})
ht(i)=f(W(i)ht(i−1)+V(i)ht−1(i)+b(i))
t=第二章,i=第二轮,那么其学习记忆=W第一轮第二章的学习记忆+V第二轮第一章的学习记忆。
1.4 BPTT算法
BPTT和BP很类似,是一个思路,但是因为这里和时刻有关系。
在这样一个多分类器中,损失函数是一个交叉熵。
某一时刻的损失函数是:
E
t
(
y
t
,
y
^
t
)
=
−
y
t
log
y
^
t
E_{t}\left(y_{t}, \hat{y}_{t}\right)=-y_{t} \log \hat{y}_{t}
Et(yt,y^t)=−ytlogy^t
最终的损失函数是所有时刻的交叉熵相加:
E
(
y
,
y
^
)
=
∑
t
E
t
(
y
t
,
y
^
t
)
=
−
∑
y
t
log
y
^
t
\begin{aligned} E(y, \hat{y}) &=\sum_{t} E_{t}\left(y_{t}, \hat{y}_{t}\right) \\ &=-\sum y_{t} \log \hat{y}_{t} \end{aligned}
E(y,y^)=t∑Et(yt,y^t)=−∑ytlogy^t
损失函数对W求偏导:
∂
E
∂
W
=
∑
t
∂
E
t
∂
W
\frac{\partial E}{\partial W}=\sum_{t} \frac{\partial E_{t}}{\partial W}
∂W∂E=∑t∂W∂Et
假设t=3,
∂
E
3
∂
W
=
∂
E
3
∂
y
^
3
∂
y
^
3
∂
s
3
∂
s
3
∂
W
\frac{\partial E_{3}}{\partial W}=\frac{\partial E_{3}}{\partial \hat{y}_{3}} \frac{\partial \hat{y}_{3}}{\partial s_{3}} \frac{\partial s_{3}}{\partial W}
∂W∂E3=∂y^3∂E3∂s3∂y^3∂W∂s3
E
3
E_3
E3和
y
3
y_3
y3有关系,
y
3
y_3
y3和
s
3
s_3
s3有关系(参考2.1中的公式)。
而
s
3
=
t
a
n
h
(
U
x
3
+
W
s
2
)
s_3=tanh(Ux_3+Ws_2)
s3=tanh(Ux3+Ws2),
s
3
s_3
s3和
s
2
s_2
s2有关系,我们对
s
3
s_3
s3对W求偏导不能直接等于
s
2
s_2
s2,因为
s
2
s_2
s2也和W有关系。
s
2
=
t
a
n
h
(
U
x
2
+
W
s
1
)
s_2=tanh(Ux_2+Ws_1)
s2=tanh(Ux2+Ws1)
s 2 s_2 s2和 s 1 s_1 s1有关系…一直到0时刻。所以我们会把每个时刻的相关梯度值相加: ∂ s 3 ∂ W = ∑ k = 0 3 ∂ s 3 ∂ s k ∂ s k ∂ W \frac{\partial s_{3}}{\partial W}=\sum_{k=0}^{3} \frac{\partial s_{3}}{\partial s_{k}} \frac{\partial s_{k}}{\partial W} ∂W∂s3=k=0∑3∂sk∂s3∂W∂sk
其中我们在计算 ∂ s 3 ∂ s 2 \dfrac{\partial s_3}{\partial s_2} ∂s2∂s3的时候需要使用链式法则计算: ∂ s 3 ∂ s 1 = ∂ s 3 ∂ s 2 ∂ s 2 ∂ s 1 ∂ s 1 ∂ s 0 \dfrac{\partial s_3}{\partial s_1}=\dfrac{\partial s_3}{\partial s_2}\dfrac{\partial s_2}{\partial s_1}\dfrac{\partial s_1}{\partial s_0} ∂s1∂s3=∂s2∂s3∂s1∂s2∂s0∂s1
所以最终得到: ∂ E 3 ∂ W = ∑ k = 0 3 ∂ E 3 ∂ y ^ 3 ∂ y ^ 3 ∂ s 3 ∂ s 3 ∂ s k ∂ s k ∂ W = ∑ k = 0 3 ∂ E 3 ∂ y ^ 3 ∂ y ^ 3 ∂ s 3 ( ∏ j = k + 1 3 ∂ s j ∂ s j − 1 ) ∂ s k ∂ W \frac{\partial E_{3}}{\partial W}=\sum_{k=0}^{3} \frac{\partial E_{3}}{\partial \hat{y}_{3}} \frac{\partial \hat{y}_{3}}{\partial s_{3}} \frac{\partial s_{3}}{\partial s_{k}} \frac{\partial s_{k}}{\partial W} =\sum_{k=0}^{3} \frac{\partial E_{3}}{\partial \hat{y}_{3}} \frac{\partial \hat{y}_{3}}{\partial s_{3}}\left(\prod_{j=k+1}^{3} \frac{\partial s_{j}}{\partial s_{j-1}}\right) \frac{\partial s_{k}}{\partial W} ∂W∂E3=k=0∑3∂y^3∂E3∂s3∂y^3∂sk∂s3∂W∂sk=k=0∑3∂y^3∂E3∂s3∂y^3⎝⎛j=k+1∏3∂sj−1∂sj⎠⎞∂W∂sk
看公式中有连乘的部分。当使用tanh作为激活函数的时候,由于导数值分别在0到1之间,随着时间的累计,小于1的数不断相城,很容易趋近于0。(另外一种解释:如果权重矩阵 W的范数也不很大,那么经过 𝑡−𝑘 次传播后, ∂ s 3 ∂ s k \dfrac{\partial s_3}{\partial s_k} ∂sk∂s3的范数会趋近于0,这也就导致了梯度消失。)
梯度消失带来的一个问题就是记忆力有限,离得越远的东西记住得越少。
1.5 生成模型与图像描述
一张图片->经过VGG网络,取得倒数第一层的输出->作为RNN第一层的多加的输入。
2 LSTM
2.1 LSTM
LSTM就是为了解决普通RNN中的梯度消失问题提出的。
LSTM提出了记忆细胞C,以及各种门。下图中的h与上面的S是相同含义,表示记忆。每个时刻的输出,在这里是没有画出来的。
假设现在有一个任务是根据已经读到的词,预测下一个词。例如输入法,生成诗词。
第1步:忘记门:从记忆细胞中丢弃一些信息
使用sigmoid函数,经过sigmoid之后得到一个概率值,描述每个部分有多少量可以通过。
f
t
=
σ
(
W
f
⋅
[
h
t
−
1
,
x
t
]
+
b
f
)
f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right)
ft=σ(Wf⋅[ht−1,xt]+bf)
如果C中包含当前对象的性别属性,现在已经正确的预测了当前的名词。当我们看到另外一个新的对象的时候,我们希望忘记旧对象的性别属性。
第2步:更新什么新信息到记忆中
sigmoid决定什么值需要更新:
i
t
=
σ
(
W
i
⋅
[
h
t
−
1
,
x
t
]
+
b
i
)
i_{t}=\sigma\left(W_{i} \cdot\left[h_{t-1}, x_{t}\right]+b_{i}\right)
it=σ(Wi⋅[ht−1,xt]+bi)
tanh层创建一个新的候选值向量(高三这一年学到的所有知识):
C
~
t
=
tanh
(
W
C
⋅
[
h
t
−
1
,
x
t
]
+
b
C
)
\tilde{C}_{t}=\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right)
C~t=tanh(WC⋅[ht−1,xt]+bC)
第3步:更新记忆细胞
把旧状态与
f
t
f_t
ft相乘,丢弃掉我们确定需要丢弃的信息;
加上
i
t
i_t
it*
C
~
t
\tilde{C}_{t}
C~t,就是新的候选值,更新状态。
C
t
=
f
t
∗
C
t
−
1
+
i
t
∗
C
~
t
C_{t}=f_{t} * C_{t-1}+i_{t} * \tilde{C}_{t}
Ct=ft∗Ct−1+it∗C~t
C
t
−
1
C_{t-1}
Ct−1是到高二以及之前的所有记忆,
C
~
t
\tilde{C}_{t}
C~t高三这一年学到的所有知识。带着两部分应该留下的内容去高考。
在任务中就是希望把新看到对象的性别属性添加到C,而把旧对象的性别属性删除。
第4步,基于细胞状态得到输出
首先一个sigmoid层确定细胞状态的哪个部分的值将输出: o t = σ ( W o [ h t − 1 , x t ] + b o ) o_{t}=\sigma\left(W_{o}\left[h_{t-1}, x_{t}\right]+b_{o}\right) ot=σ(Wo[ht−1,xt]+bo)
接着用tanh处理细胞状态,输出我们确定输出的那部分,这部分是记忆用于下一时刻帮助做出决策的: h t = o t ∗ tanh ( C t ) h_{t}=o_{t} * \tanh \left(C_{t}\right) ht=ot∗tanh(Ct)
在语言模型中,既然我当前看到了一个对象,这里可能输出一个动词信息,以备下一步需要用到。例如这里可能输出当前对象是单数还是复数,这样就知道下一个动词应该填写什么形式。
总结:
1:决定老细胞只留下哪部分
f
t
=
σ
(
W
f
⋅
[
h
t
−
1
,
x
t
]
+
b
f
)
f_{t}=\sigma\left(W_{f} \cdot\left[h_{t-1}, x_{t}\right]+b_{f}\right)
ft=σ(Wf⋅[ht−1,xt]+bf)
2: 决定新知识应该记住哪部分:
i
t
=
σ
(
W
i
⋅
[
h
t
−
1
,
x
t
]
+
b
i
)
i_{t}=\sigma\left(W_{i} \cdot\left[h_{t-1}, x_{t}\right]+b_{i}\right)
it=σ(Wi⋅[ht−1,xt]+bi)
新学习到的知识:
C
~
t
=
tanh
(
W
C
⋅
[
h
t
−
1
,
x
t
]
+
b
C
)
\tilde{C}_{t}=\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right)
C~t=tanh(WC⋅[ht−1,xt]+bC)
3 更新细胞状态:
C
t
=
f
t
∗
C
t
−
1
+
i
t
∗
C
~
t
C_{t}=f_{t} * C_{t-1}+i_{t} * \tilde{C}_{t}
Ct=ft∗Ct−1+it∗C~t
4 决定要输出哪部分:
o
t
=
σ
(
W
o
[
h
t
−
1
,
x
t
]
+
b
o
)
o_{t}=\sigma\left(W_{o}\left[h_{t-1}, x_{t}\right]+b_{o}\right)
ot=σ(Wo[ht−1,xt]+bo)
产生隐藏状态的输出:
h
t
=
o
t
∗
tanh
(
C
t
)
h_{t}=o_{t} * \tanh \left(C_{t}\right)
ht=ot∗tanh(Ct)
对比普通的RNN,输出 o t = σ ( V S t ) o_t=\sigma\left(VS_t\right) ot=σ(VSt), S t = t a n h ( U x t + W S t − 1 ) S_t=tanh(Ux_t+WS_{t-1}) St=tanh(Uxt+WSt−1),对于记忆 S t S_t St是由之前记忆和新知识共同组成。加入细胞状态可以选择忘记一部分老知识和选择忘记一部分新知识。
在之前的求导过程中 ∂ s 3 ∂ s 1 = ∂ s 3 ∂ s 2 ∂ s 2 ∂ s 1 ∂ s 1 ∂ s 0 \dfrac{\partial s_3}{\partial s_1}=\dfrac{\partial s_3}{\partial s_2}\dfrac{\partial s_2}{\partial s_1}\dfrac{\partial s_1}{\partial s_0} ∂s1∂s3=∂s2∂s3∂s1∂s2∂s0∂s1,现在变为。。。。。
输出
o
t
=
σ
(
V
h
t
)
o_t=\sigma\left(Vh_t\right)
ot=σ(Vht)
h
t
=
o
t
∗
tanh
(
C
t
)
h_{t}=o_{t} * \tanh \left(C_{t}\right)
ht=ot∗tanh(Ct)
C
t
=
f
t
∗
C
t
−
1
+
i
t
∗
C
~
t
=
f
t
∗
C
t
−
1
+
i
t
∗
tanh
(
W
C
⋅
[
h
t
−
1
,
x
t
]
+
b
C
)
C_{t}=f_{t} * C_{t-1}+i_{t} * \tilde{C}_{t}=f_{t} * C_{t-1}+i_t*\tanh \left(W_{C} \cdot\left[h_{t-1}, x_{t}\right]+b_{C}\right)
Ct=ft∗Ct−1+it∗C~t=ft∗Ct−1+it∗tanh(WC⋅[ht−1,xt]+bC)
损失函数不变,还是令t=3,
∂
E
3
∂
W
=
∂
E
3
∂
y
^
3
∂
y
^
3
∂
h
3
∂
h
3
∂
C
3
∂
C
3
∂
W
c
\frac{\partial E_{3}}{\partial W}=\frac{\partial E_{3}}{\partial \hat{y}_{3}} \frac{\partial \hat{y}_{3}}{\partial h_{3}} \frac{\partial h_{3}}{\partial C_3}\frac{\partial C_{3}}{\partial W_c}
∂W∂E3=∂y^3∂E3∂h3∂y^3∂C3∂h3∂Wc∂C3
要求
∂
C
3
∂
W
c
\dfrac{\partial C_3}{\partial W_c}
∂Wc∂C3,这样
C
t
C_t
Ct与
W
c
W_c
Wc有关系,
C
t
−
1
C_{t-1}
Ct−1与
W
c
W_c
Wc有关系,两部分相加,对整个函数求导,就是对这两部分分别求导,再相加。与普通RNN的相乘
∂
C
3
∂
C
1
=
∂
C
3
∂
C
2
+
∂
C
2
∂
C
1
=
?
\dfrac{\partial C_3}{\partial C_1}=\dfrac{\partial C_3}{\partial C_2}+\dfrac{\partial C_2}{\partial C_1}=?
∂C1∂C3=∂C2∂C3+∂C1∂C2=?
2.2 GRU
GRU是LSTM的变种之一。
GRU做的改变是:
1 将忘记门和输入门合并成一个门,称为更新门。
2 细胞状态和隐藏状态,也就是上面的C和
h
t
h_t
ht合并为一个
h
t
h_t
ht。
这样GRU的参数就比标准LSTM要少,在很多情况下效果基本一致。