赞
踩
CS224N WINTER 2022(一)词向量(附Assignment1答案)
CS224N WINTER 2022(二)反向传播、神经网络、依存分析(附Assignment2答案)
CS224N WINTER 2022(三)RNN、语言模型、梯度消失与梯度爆炸(附Assignment3答案)
CS224N WINTER 2022(四)机器翻译、注意力机制、subword模型(附Assignment4答案)
CS224N WINTER 2022(五)Transformers详解(附Assignment5答案)
CS224N WINTER 2022课件可从https://web.stanford.edu/class/archive/cs/cs224n/cs224n.1224/下载,也可从下面网盘中获取:
https://pan.baidu.com/s/1LDD1H3X3RS5wYuhpIeJOkA
提取码: hpu3
本系列博客每个小节的开头也会提供该小结对应课件的下载链接。
课件、作业答案、学习笔记(Updating):GitHub@cs224n-winter-2022
关于本系列博客内容的说明:
笔者根据自己的情况记录较为有用的知识点,并加以少量见解或拓展延申,并非slide内容的完整笔注;
CS224N WINTER 2022共计五次作业,笔者提供自己完成的参考答案,不担保其正确性;
由于CSDN限制博客字数,笔者无法将完整内容发表于一篇博客内,只能分篇发布,可从我的GitHub Repository中获取完整笔记,本系列其他分篇博客发布于(Updating):
CS224N WINTER 2022(一)词向量(附Assignment1答案)
CS224N WINTER 2022(二)反向传播、神经网络、依存分析(附Assignment2答案)
CS224N WINTER 2022(三)RNN、语言模型、梯度消失与梯度爆炸(附Assignment3答案)
[slides]
神经依存分析模型架构:slides p.4
常规的依存分析方法涉及的类别特征是稀疏且不完整的,因此需要耗费大量时间用于特征运算;神经网络方法可以学习得到稠密的特征表示来更好地解决问题。
这里再次提到lecture3的notes部分提到的greedy Greedy Deterministic Transition-Based Parsing的例子,神经网络在给定状态三元组 ( σ , β , A ) (\sigma,\beta,A) (σ,β,A)的特征表示下,对下一次可能的转移(三种转移策略之一)进行预测。
与Neural transition-based依存解析模型对应,也有Neural graph-based依存解析模型,它要预测的就是图节点(单词)之间的依存关系是否存在,有点类似证明图。
### notes
神经依存分析的评估指标:slides p.5
左边的Gold是依存分析训练集的标注格式,包括词性标注的预测以及依赖关系的预测。
看起来UAS是依赖关系的精确度,LAS是词性标注的精确度。(这么解释是合理的)
正好在看这部分又查阅到另一篇博客,感觉讲得比我清楚。
神经网络参数初始化:slides p.16
这个在lecture3的式 ( 3.7 ) (3.7) (3.7)中也有提过一次,这里提到的初始化规则是:
截距项初始化为零;
权重矩阵的数值在
Uniform
(
−
r
,
r
)
\text{Uniform}(-r,r)
Uniform(−r,r)的分布上采样,尽量确保初始值的方差满足下式:
Var
(
W
i
)
=
2
n
i
n
+
n
o
u
t
(5.1)
\text{Var}(W_i)=\frac2{n_{\rm in}+n_{\rm out}}\tag{5.1}
Var(Wi)=nin+nout2(5.1)
其中
n
i
n
n_{\rm in}
nin与
n
o
u
t
n_{\rm out}
nout分别表示
W
i
W_i
Wi的fan-in与fan-out;
语言模型:slides p.19-22
语言模型旨在给定单词序列的条件下,预测下一个单词是什么(输入法的联想):
P
(
x
(
t
+
1
)
∣
x
(
t
)
,
.
.
.
,
x
(
1
)
)
(5.2)
P(x^{(t+1)}|x^{(t)},...,x^{(1)})\tag{5.2}
P(x(t+1)∣x(t),...,x(1))(5.2)
也可以看作是计算一段文本出现的概率(文本校正):
P
(
x
(
1
)
,
.
.
.
,
x
(
T
)
)
=
P
(
x
(
1
)
)
×
P
(
x
(
2
)
∣
x
(
1
)
)
×
.
.
.
×
P
(
x
(
T
)
∣
x
(
T
−
1
)
,
.
.
.
,
x
(
1
)
)
=
∏
t
=
1
T
P
(
x
(
t
)
∣
x
(
t
−
1
)
,
.
.
.
,
x
(
1
)
)
(5.3)
P(x(1),...,x(T))=P(x(1))×P(x(2)|x(1))×...×P(x(T)|x(T−1),...,x(1))=T∏t=1P(x(t)|x(t−1),...,x(1))
n-gram模型:slides p.23-32
最经典的统计语言模型莫过于n-gram模型,即只考虑长度不超过n的单词序列的转移概率与分布概率,假定:
P
(
x
(
t
+
1
)
∣
x
(
t
)
,
.
.
.
,
x
(
1
)
)
=
P
(
x
(
t
+
1
)
∣
x
(
t
)
,
.
.
.
,
x
(
t
−
n
+
2
)
)
=
P
(
x
(
t
+
1
)
,
x
(
t
)
,
.
.
.
,
x
(
t
−
n
+
2
)
)
P
(
x
(
t
)
,
.
.
.
,
x
(
t
−
n
+
2
)
)
≈
count
(
x
(
t
+
1
)
,
x
(
t
)
,
.
.
.
,
x
(
t
−
n
+
2
)
)
count
(
x
(
t
)
,
.
.
.
,
x
(
t
−
n
+
2
)
)
(5.4)
P(x(t+1)|x(t),...,x(1))=P(x(t+1)|x(t),...,x(t−n+2))=P(x(t+1),x(t),...,x(t−n+2))P(x(t),...,x(t−n+2))≈count(x(t+1),x(t),...,x(t−n+2))count(x(t),...,x(t−n+2))
最终可以使用大规模语料库中的统计结果进行近似。
当然这种假定可能并不总是正确,因为文本中的相互关联的单词可能会间隔很远,并不仅能通过前方少数几个单词就能正确推断下一个单词。
总体来说,n-gram模型的存在如下两个显著的缺陷:
稀疏性:可能一段文本根本就从来没有出现过;
高内存占用:存储文本中所有的n-gram值耗用非常大,因此一般n的取值都很小。这里笔者可以推荐一个公开的英文2-gram与3-gram数据,以arpa格式的文件存储,具体使用可以参考笔者的博客。
神经语言模型与RNN:slides p.33
这种解决与序列预测相关的学习任务,正是RNN大展身手的时候,损失函数使用交叉熵。
由于大多是RNN的基础内容,没有特别值得记录的内容,提醒一下RNN是串行结构,因此无法并行提速。
这里记录slides中几个小demo的项目地址:
使用n-gram模型自动生成文本:language-models
利用RNN语言模型生成奥巴马讲话:obama-rnn-machine-generated-political-speeches
自动智能写作(模仿哈利波特小说风格):how-to-write-with-artificial-intelligence
语言模型评估指标:slides p.56
[notes (lectures 5 and 6)] 注意这是lecture5与lecture6共用
两种解决梯度消失的技术:notes p.8(这里其实已经涉及lecture6的内容,但是前面没有看到有用的东西,权当预习性质的记录一下)
GRU:notes p.11-12
在此之前,我们先回顾一下标准RNN的传播形式(忽略截距项):
h
t
=
σ
(
W
(
h
h
)
h
t
−
1
+
W
(
h
x
)
x
t
)
y
^
t
=
softmax
(
W
S
h
t
)
(5.7)
ht=σ(W(hh)ht−1+W(hx)xt)ˆyt=softmax(WSht)
这里输入为一序列的单词
x
1
,
.
.
.
,
x
T
x_1,...,x_T
x1,...,xT(词向量),输出
y
^
(
t
)
\hat y^{(t)}
y^(t)是预测的序列中的一个结果。
GRU的关键表达式如下所示:
z
t
=
σ
(
W
(
z
)
x
t
+
U
(
z
)
h
t
−
1
)
Update gate
r
t
=
σ
(
W
(
r
)
x
t
+
U
(
r
)
h
t
−
1
)
Reset gate
h
~
t
=
tanh
(
r
t
∘
U
h
t
−
1
+
W
x
t
)
New memory
h
t
=
(
1
−
z
t
)
∘
h
~
t
+
z
t
∘
h
t
−
1
Hidden state
(5.8)
zt=σ(W(z)xt+U(z)ht−1)Update gatert=σ(W(r)xt+U(r)ht−1)Reset gate˜ht=tanh(rt∘Uht−1+Wxt)New memoryht=(1−zt)∘˜ht+zt∘ht−1Hidden state
这里的
∘
\circ
∘是一种门控运算,目前理解可能就是有一个阈值,一旦逾越就取零,否则就正常相乘。
GRU门控机制说明:
LSTM:notes p.13-14
关键表达式如下所示:
i
t
=
σ
(
W
(
i
)
x
t
+
U
(
i
)
h
t
−
1
)
Input gate
f
t
=
σ
(
W
(
f
)
x
t
+
U
(
f
)
h
t
−
1
)
Forget gate
o
t
=
σ
(
W
(
o
)
x
t
+
U
(
o
)
h
t
−
1
)
Output/Exposure gate
c
~
t
=
tanh
(
W
(
c
)
x
t
+
U
(
c
)
h
t
−
1
)
New memory cell
c
t
=
f
t
∘
c
t
−
1
+
i
t
∘
c
~
t
Final memory cell
h
t
=
o
t
∘
tanh
(
c
t
)
(5.9)
it=σ(W(i)xt+U(i)ht−1)Input gateft=σ(W(f)xt+U(f)ht−1)Forget gateot=σ(W(o)xt+U(o)ht−1)Output/Exposure gate˜ct=tanh(W(c)xt+U(c)ht−1)New memory cellct=ft∘ct−1+it∘˜ctFinal memory cellht=ot∘tanh(ct)
同样地,这里的
∘
\circ
∘运算符是LSTM中特殊的门控运算符,可以先理解为简单相乘。
LSTM门控机制说明:
[code] [handout] [latex template]
Assignment3参考答案(written+coding):囚生CYのGitHub Repository
( a ) (a) (a) 关于 Adam \text{Adam} Adam优化器(首次提出), PyTorch \text{PyTorch} PyTorch中的接口如下所示:
torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
beta
参数的两个值的正如第
(
2
)
(2)
(2)问中所示。
(
1
)
(1)
(1) 动量更新法则:保留当前点的信息(因为当前点的信息一定程度包含了之前所有更新迭代的信息,这有点类似LSTM与GRU的思想,但是此处并不会发生遗忘)
m
←
β
1
m
+
(
1
−
β
1
)
∇
θ
J
m
i
n
i
b
a
t
c
h
(
θ
)
θ
←
θ
−
α
m
(a3.1.1)
m←β1m+(1−β1)∇θJminibatch(θ)θ←θ−αm
注意
β
1
\beta_1
β1的取值默认为
0.9
0.9
0.9,这表明会尽可能多地保留当前点的信息。
从另一个角度来说,单纯的梯度下降法容易陷入局部最优,直观上来看,带动量的更新可以使得搜索路径呈现出一个弧形收敛的形状(有点像一个漩涡收敛到台风眼),因为每次更新不会偏离原先的方向太多,这样的策略容易跳出局部最优点,并且将搜索范围控制在一定区域内(漩涡内),容易最终收敛到全局最优。
(
2
)
(2)
(2) 完整的
Adam
\text{Adam}
Adam优化器还使用了自适应学习率的技术:
m
←
β
1
m
+
(
1
−
β
1
)
∇
θ
J
m
i
n
i
b
a
t
c
h
(
θ
)
v
←
β
2
v
+
(
1
−
β
2
)
(
∇
θ
J
m
i
n
i
b
a
t
c
h
)
(
θ
)
⊙
∇
θ
J
m
i
n
i
b
a
t
c
h
(
θ
)
)
θ
←
θ
−
α
m
/
v
(a3.1.2)
m←β1m+(1−β1)∇θJminibatch(θ)v←β2v+(1−β2)(∇θJminibatch)(θ)⊙∇θJminibatch(θ))θ←θ−αm/√v
其中
⊙
\odot
⊙与
/
/
/运算符表示点对点的乘法与除法(上面的
⊙
\odot
⊙相当于是梯度中所有元素取平方)。
β 2 \beta_2 β2默认值 0.99 0.99 0.99,这里相当于做了学习率关于梯度值的自适应调整(每个参数的调整都不一样,注意 / / /号是点对点的除法),在非稳态和在线问题上有很有优秀的性能。
一般来说随着优化迭代,梯度值会逐渐变小(理想情况下最终收敛到零),因此 v v v的取值应该会趋向于变小,步长则是变大,这个就有点奇怪了,理论上优化应该是前期大步长找到方向,后期小步长做微调。
找到一篇详细总结 Adam \text{Adam} Adam优化器优点的博客。
(
b
)
(b)
(b)
Dropout
\text{Dropout}
Dropout技术是在神经网络训练过程中以一定概率
p
d
r
o
p
p_{\rm drop}
pdrop将隐层
h
h
h中的若干值设为零,然后乘以一个常数
γ
\gamma
γ,具体而言:
h
d
r
o
p
=
γ
d
⊙
h
d
∈
{
0
,
1
}
n
,
h
∈
R
n
(a3.1.3)
h_{\rm drop}=\gamma d\odot h\quad d\in\{0,1\}^n,h\in\R^n\tag{a3.1.3}
hdrop=γd⊙hd∈{0,1}n,h∈Rn(a3.1.3)
这里之所以乘以
γ
\gamma
γ是为了使得
h
h
h中每个点位的期望值不变,即:
E
p
d
r
o
p
[
h
d
r
o
p
]
i
=
h
i
(a3.1.4)
\mathbb E_{p_{\rm drop}}[h_{\rm drop}]_i=h_i\tag{a3.1.4}
Epdrop[hdrop]i=hi(a3.1.4)
(
1
)
(1)
(1) 根据期望定义有如下推导:
E
p
d
r
o
p
[
h
d
r
o
p
]
i
=
p
d
r
o
p
⋅
0
+
(
1
−
p
d
r
o
p
)
γ
h
i
=
h
i
⇒
γ
=
1
1
−
p
d
r
o
p
(a3.1.5)
\mathbb E_{p_{\rm drop}}[h_{\rm drop}]_i=p_{\rm drop}\cdot 0+(1-p_{\rm drop})\gamma h_i=h_i\Rightarrow\gamma=\frac1{1-p_{\rm drop}}\tag{a3.1.5}
Epdrop[hdrop]i=pdrop⋅0+(1−pdrop)γhi=hi⇒γ=1−pdrop1(a3.1.5)
( 2 ) (2) (2) Dropout \text{Dropout} Dropout是用来防止模型过拟合,缓解模型运算复杂度,评估的时候显然不能使用 Dropout \text{Dropout} Dropout,因为用于评估的模型必须是确定的, Dropout \text{Dropout} Dropout是存在不确定性的。
本次使用的是 PyTorch1.7.1 \text{PyTorch1.7.1} PyTorch1.7.1 CPU \text{CPU} CPU版本,当然使用 GPU \text{GPU} GPU版本应该会更好。
本次实现的是基于 Transition \text{Transition} Transition的依存分析模型,就是在实现[notes]中的Greedy Deterministic Transition-Based Parsing算法。其中SHIFT是将缓存中的第一个移入栈,LEFT-ARC与RIGHT-ARC分别是建立栈顶前两个单词之间的依存关系。
( a ) (a) (a) 具体每步迭代结果如下所示(默认ROOT是指向parsed的):
Stack | Buffer | New dependency | Transition |
---|---|---|---|
[ROOT] | [Today, I, parsed, a, sentence] | Initial Configuration | |
[ROOT, Today] | [I, parsed, a, sentence] | SHIFT | |
[ROOT, Today, I] | [parsed, a, sentence] | SHIFT | |
[ROOT, Today, I, parsed] | [a, sentence] | SHIFT | |
[ROOT, Today, parsed] | [a, sentence] | parsed → \rightarrow → I | LEFT-ARC |
[ROOT, parsed] | [a, sentence] | parsed → \rightarrow → Today | LEFT-ARC |
[ROOT, parsed, a] | [sentence] | SHIFT | |
[ROOT, parsed, a, sentence] | [] | SHIFT | |
[ROOT, parsed, sentence] | [] | sentence → \rightarrow → a | LEFT-ARC |
[ROOT, parsed] | [] | parsed → \rightarrow → sentence | RIGHT-ARC |
[ROOT] | [] | ROOT → \rightarrow → parsed | RIGHT-ARC |
( b ) (b) (b) SHIFT共计 n n n次,LEFT-ARC与RIGHT-ARC合计 n n n次,共计 2 n 2n 2n次。
(
c
)
(c)
(c) 非常简单的状态定义与转移定义代码实现,运行python parser_transitions.py part_c
通过测试。
(
d
)
(d)
(d) 运行python parser_transitions.py part_d
通过测试。
(
e
)
(e)
(e) 实现神经依存分析模型,参考的是lecture4推荐阅读的第二篇(A Fast and Accurate Dependency Parser using Neural Networks)。运行python run.py
通过测试。
注意这一题要求是自己实现全连接层和嵌入层的逻辑,不允许使用PyTorch内置的层接口,有兴趣的自己去实现吧,我就直接调用接口了。如果是要从头到尾都重写,这个显得就很困难(需要把反向传播和梯度计算的逻辑都要实现),然而本题的模型还是继承了torch.nn.Module
的,因此似乎只能继承torch.nn.Module
写自定义网络层,这样其实还是比较简单的,这可以参考我的博客2.1节的全连接层重写的代码。
运行结果:
================================================================================ INITIALIZING ================================================================================ Loading data... took 1.36 seconds Building parser... took 0.82 seconds Loading pretrained embeddings... took 2.48 seconds Vectorizing data... took 1.22 seconds Preprocessing training data... took 30.56 seconds took 0.02 seconds ================================================================================ TRAINING ================================================================================ Epoch 1 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:18<00:00, 23.61it/s] Average Train Loss: 0.18908768985420465 Evaluating on dev set 1445850it [00:00, 46259788.38it/s] - dev UAS: 83.75 New best dev UAS! Saving model. Epoch 2 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:15<00:00, 24.52it/s] Average Train Loss: 0.1157231591158099 Evaluating on dev set 1445850it [00:00, 92527340.72it/s] - dev UAS: 86.22 New best dev UAS! Saving model. Epoch 3 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:14<00:00, 24.86it/s] Average Train Loss: 0.1010169279418918 Evaluating on dev set 1445850it [00:00, 61690227.55it/s] - dev UAS: 87.04 New best dev UAS! Saving model. Epoch 4 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:16<00:00, 24.17it/s] Average Train Loss: 0.09254590892414381 Evaluating on dev set 1445850it [00:00, 46221356.67it/s] - dev UAS: 87.43 New best dev UAS! Saving model. Epoch 5 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:16<00:00, 24.06it/s] Average Train Loss: 0.08614181549977754 Evaluating on dev set 1445850it [00:00, 46262964.50it/s] - dev UAS: 87.72 New best dev UAS! Saving model. Epoch 6 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:19<00:00, 23.20it/s] Average Train Loss: 0.08176740852599859 Evaluating on dev set 1445850it [00:00, 46264729.20it/s] - dev UAS: 88.29 New best dev UAS! Saving model. Epoch 7 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:17<00:00, 23.95it/s] Average Train Loss: 0.07832196695343047 Evaluating on dev set 1445850it [00:00, 45695793.40it/s] - dev UAS: 88.17 Epoch 8 out of 10 100%|██████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:15<00:00, 24.40it/s] Average Train Loss: 0.07501755065982153 Evaluating on dev set 1445850it [00:00, 46264729.20it/s] - dev UAS: 88.53 New best dev UAS! Saving model. Epoch 9 out of 10 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:16<00:00, 24.15it/s] Average Train Loss: 0.07205055564545192 Evaluating on dev set 1445850it [00:00, 45701992.11it/s] - dev UAS: 88.47 Epoch 10 out of 10 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1848/1848 [01:15<00:00, 24.54it/s] Average Train Loss: 0.06958463928537258 Evaluating on dev set 1445850it [00:00, 46266141.05it/s] - dev UAS: 88.76 New best dev UAS! Saving model. ================================================================================ TESTING ================================================================================ Restoring the best model weights found on the dev set Final evaluation on test set 2919736it [00:00, 92289480.94it/s] - test UAS: 89.15 Done!
作业中提到训练需要一个小时,使用 GPU \text{GPU} GPU可以大大加快速度,训练过程中的损失函数值与 UAS \text{UAS} UAS指数全部达标。(损失函数值应当低于 0.2 0.2 0.2, UAS \text{UAS} UAS超过 87 % 87\% 87%)
( f ) (f) (f) 这里提到几种解析错误类型:
下面几小问不是那么确信,将就着看吧。
( 1 ) (1) (1) 这个感觉是介词短语依存错误,但是 looks \text{looks} looks的确指向 eyes \text{eyes} eyes和 mind \text{mind} mind了,这是符合上面的说法的。难道是协同依存错误?
( 2 ) (2) (2) 这个感觉还是介词短语依存错误: chasing \text{chasing} chasing不该指向 fur \text{fur} fur, fur \text{fur} fur应该是与 dogs \text{dogs} dogs相互依存。
( 3 ) (3) (3) 这个很简单是 unexpectedly \text{unexpectedly} unexpectedly和 good \text{good} good之间属于修饰语依存错误,应当由 good \text{good} good指向 unexpectedly \text{unexpectedly} unexpectedly;
( 4 ) (4) (4) 这个根据排除法(没有介词短语,没有修饰词,也没有并列关系)只能是动词短语依存错误,但是具体是哪儿错了真的看不出来,可能是 crossing \text{crossing} crossing和 eating \text{eating} eating之间错标成了协同依存关系?
[slides]
RNN中的梯度消失问题:slides p.21-30
梯度消失在RNN中是最为常见的,因为RNN中容易包含一个很长很长的传播链。
我们继续用下面这张图来说明梯度消失:
RNN神经网络传播的数学表达式:
<
f
o
n
t
f
a
c
e
=
t
i
m
e
s
n
e
w
r
o
m
a
n
>
h
(
t
)
=
σ
(
W
h
h
(
t
−
1
)
+
W
x
x
(
t
)
+
b
1
)
<
/
f
o
n
t
>
(6.1)
<font face=times new roman>h^{(t)}=\sigma(W_hh^{(t-1)}+W_xx^{(t)}+b_1)\tag{6.1}</font>
<fontface=timesnewroman>h(t)=σ(Whh(t−1)+Wxx(t)+b1)</font>(6.1)
为了便于求导,假定激活函数
σ
(
x
)
=
x
\sigma(x)=x
σ(x)=x,即不作激活,有如下推导:
<
f
o
n
t
f
a
c
e
=
t
i
m
e
s
n
e
w
r
o
m
a
n
>
∂
h
(
t
)
∂
h
(
t
−
1
)
=
diag
(
σ
′
(
W
h
h
(
t
−
1
)
+
W
x
x
(
t
)
+
b
1
)
)
W
h
=
I
W
h
=
W
h
<
/
f
o
n
t
>
(6.2)
<font face=times new roman>\frac{\partial h^{(t)}}{\partial h^{(t-1)}}=\text{diag}(\sigma'(W_hh^{(t-1)}+W_xx^{(t)}+b_1))W_h=IW_h=W_h\tag{6.2}</font>
<fontface=timesnewroman>∂h(t−1)∂h(t)=diag(σ′(Whh(t−1)+Wxx(t)+b1))Wh=IWh=Wh</font>(6.2)
考察第
i
i
i次循环输出的损失
J
(
i
)
(
θ
)
J^{(i)}(\theta)
J(i)(θ)相对于第
j
j
j个隐层
h
(
j
)
h^{(j)}
h(j)的梯度(令
l
=
i
−
j
l=i-j
l=i−j):
<
f
o
n
t
f
a
c
e
=
t
i
m
e
s
n
e
w
r
o
m
a
n
>
∂
J
(
i
)
(
θ
)
∂
h
(
j
)
=
∂
J
(
i
)
(
θ
)
∂
h
(
i
)
∏
t
=
i
+
1
j
∂
h
(
t
)
∂
h
(
t
−
1
)
=
∂
J
(
i
)
(
θ
)
∂
h
(
i
)
∏
t
=
i
+
1
j
W
h
=
∂
J
(
i
)
(
θ
)
∂
h
(
i
)
W
h
l
<
/
f
o
n
t
>
<font face=times new roman>\frac{\partial J^{(i)}(\theta)}{\partial h^{(j)}}=\frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}}\prod_{t=i+1}^j\frac{\partial h^{(t)}}{\partial h^{(t-1)}}=\frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}}\prod_{t=i+1}^jW_h=\frac{\partial J^{(i)}(\theta)}{\partial h^{(i)}}W_h^l</font>
<fontface=timesnewroman>∂h(j)∂J(i)(θ)=∂h(i)∂J(i)(θ)t=i+1∏j∂h(t−1)∂h(t)=∂h(i)∂J(i)(θ)t=i+1∏jWh=∂h(i)∂J(i)(θ)Whl</font>
若
W
h
W_h
Wh不满秩(如
W
h
W_h
Wh是稀疏矩阵),则随着
W
h
W_h
Wh的求幂会使得
W
h
W^h
Wh的秩越来越小,最后就会变成一个零矩阵,这就是梯度消失。
事实上对于一般的非线性激活函数 σ \sigma σ,梯度消失的问题总是存在,ReLU是为解决梯度消失问题而提出的一种分段激活函数。
对于RNN来说,梯度消失意味着的记忆完全损失,类似GRU中彻底遗忘过去的记忆,对于长文本中间隔较长的上下文单词就很难建立联系。
不过某种意义上,在一些人眼中梯度消失并未必是坏事,这对于大模型来说,梯度消失一定程度上指示了模型优化的方向,即可以移除那些不必要的神经元。
梯度爆炸:slides p.31-32
梯度爆炸带来的直接问题就是梯度下降法中步长过大,从而错过全局最优点。在模型训练中有时候你发现损失函数突然蹦出一个Inf或者NaN,这很有可能是发生了梯度爆炸(你可以从之前的checkpoint中调取模型重新训练)。
梯度爆炸直接的解决方案就是限制梯度的大小,超过一定阈值就对梯度进行放缩。
**解决RNN梯度消失问题(LSTM与GRU):**slides p.33-41
关于LSTM与GRU的原理公式解析详见lecture5中notes小节的内容。
LSTM与GRU的门控机制使得更容易保留长距离之前的记忆,因而解决了梯度消失可能导致的问题。比如设置遗忘门的信号值为 1 1 1,输入门的信号值为 0 0 0,则过去的信息将会无限制地被保留下来。但是LSTM并不确保一定不会发生梯度消失或梯度爆炸的问题,它只是提供了一种保留长距离依赖的方法,并非彻底解决梯度消失。
LSTM通常是最好的选择,尤其在数据很多且存在长距离依赖的情况;GRU的优势在于运算更快。但是目前的趋势是RNN逐渐被Transformer取代。
残差链接(residual connections):slides p.42
梯度消失并不只是会在RNN中出现,在任何大模型中都很容易出现,因此需要引入残差连接。
即将距离较长的两个神经元直接相连,以避免梯度消失( F ( x ) + x F(x)+x F(x)+x求导,在 F ( x ) F(x) F(x)导数为零的情况下,依然可以得到 1 1 1,因而避免了梯度消失)。
其他用以解决梯度消失与梯度爆炸问题的方法:
① DenseNet:将每一层都与后面的层相连接;
② HighWay:类似残差连接,但是引入了一个动态的门控机制进行控制:
双向RNN与多层RNN:slides p.44-51
双向RNN非常容易理解,即正着遍历一次输入序列得到一个正向RNN的输出序列,反着再遍历一次序列,得到反向RNN的输出序列,然后将两个输出序列对应节点进行运算(一般是直接拼接即可)输出得到最终的输出序列,下面这个图就讲得非常清楚:
注意双向RNN仅在整个序列可知的情况下才能使用(此时双向RNN将会非常强大,比如BERT模型就是建立在双向RNN上的),比如在语言模型中就不能使用,因为语言模型中只有左侧一边的文本序列。
多层RNN就更容易理解了,即将RNN的输出序列作为输入序列输入到下一个RNN中。实际应用中Massive Exploration of Neural Machine Translation Architecutres指出在神经机器翻译中,2~4层的RNN编码器结构是最优的,4层的RNN解码器是最优的。且一般情况下残差连接与稠密连接(dense connections)对于多层RNN是非常必要的(如8层的RNN)。
基于Transformer的网络(如BERT)的网络深度会更高(通常有12层或24层)。
[notes (lectures 5 and 6)] 注意这是lecture5与lecture6共用
详见lecture5的notes小节内容。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。