【CS224n】Language Models, RNN, GRU and LSTM

CS224n系列:
【CS224n】Neural Networks, Backpropagation
【CS224n】Neural-Dependency-Parsing
【CS224n】Language Models, RNN, GRU and LSTM
【CS224n】Neural Machine Translation with Seq2Seq
【CS224n】ConvNets for NLP

1. Language Models

作业实现代码:Neural-machine-translation
Corpus BLEU: 35.18

1.1 Introduction

语言模型表示句子中的词共现的概率:
在这里插入图片描述
关于语言模型这一块的具体内容,可以参考我的另一篇博客:word2vec原理剖析

1.2 n-gram Language Models

原始的语言模型计算量非常大,因此有了n-gram语言模型,下图分别表示bigram和trigram模型:
在这里插入图片描述
n-gram语言模型存在两个问题:稀疏性和存储空间大。
for example,公式3的分子要求三个词同时出现,但更多情况情况是,这些词共现的次数为0,那这时候需要做平滑处理;当分母两个词没有同时出现时,此时不能计算概率,需要做回退(backoff)。
存储空间大是指,我们需要存储很多n-gram词组,当n很大,这个存储空间呈指数级增长。

1.3 Window-based Neural Language Model

神经语言模型是Bengio提出的第一次将深度学习用于自然语言处理模型:
在这里插入图片描述
公式:
在这里插入图片描述

2. Recurrent Neural Networks (RNN)

RNN是指循环神经网络,如下图:
在这里插入图片描述
公式:
在这里插入图片描述
值得注意的是,在每个时间步中的权重 W ( h h ) W^{(hh)} W ( h x ) W^{(hx)} 都是参数共享的。这样做有两个好处:一个是减少模型需要学习的参数量,另一个是可以使得模型对语料的输入长度不敏感。

2.1 RNN Loss and Perplexity

RNN的损失函数也是交叉熵:
在这里插入图片描述
在这里插入图片描述
困惑度:
在这里插入图片描述
困惑度越低,表示预测结果的置信度越高。

2.2 Advantages, Disadvantages and Applications of RNNs

优点:

  1. 输入可以是任意长度(过长截断,过短补齐);
  2. 模型大小并不会因为长度的增加而增大(因为参数共享);
  3. 计算第t个时间步可以使用很多步之前的信息(理论上);
  4. 相同的权重应用于输入的每个时间步,因此在处理输入时存在对称性;
    缺点:
  5. 计算过程很慢(序列化模型,没办法做并行计算);
  6. 当序列很长时,会出现梯度消失或梯度爆炸的问题。

2.3 Vanishing Gradient & Gradient Explosion Problems

梯度消失/梯度爆炸问题是因为RNN在反向传播过程中,更早的时间步的梯度存在累乘步骤,因而很容易导致梯度为0或者无穷大。具体可以看以下的反向传播过程:
计算RNN对权重W的梯度:
在这里插入图片描述
使用链式法则可以得到:
在这里插入图片描述
因为W是参数共享的,所以 h t h_t 对于W的梯度必须是前t个时刻的梯度之和,所以才有上述公式的求和过程。其中,
在这里插入图片描述
这个公式怎么理解呢?我们可以先回顾下 h t h_t h t 1 h_{t-1} 的关系:
h t = f ( W ( h h ) h t 1 + W ( h x ) x [ t ] ) h_t=f(W^{(hh)}h_{t-1}+W^{(hx)}x_{[t]})
一个个解释,首先,累乘是因为链式法则,例如:
h 4 h 2 = h 4 h 3 h 3 h 2 \frac{\partial h_4}{\partial h_{2}}=\frac{\partial h_4}{\partial h_{3}}\frac{\partial h_3}{\partial h_{2}}
其次,
在这里插入图片描述

h j h j 1 = W T × d i a g [ f ( j j 1 ) ] \frac{\partial h_j}{\partial h_{j-1}}=W^T \times diag[f^{'}(j_{j-1})]
当激活函数为sigmoid时,
h j h j 1 = W T × d i a g [ f ( j j 1 ) ] = W T × d i a g [ σ ( 1 σ ) ] \frac{\partial h_j}{\partial h_{j-1}}=W^T \times diag[f^{'}(j_{j-1})]= W^T \times diag[\sigma(1-\sigma)]
当激活函数为tanh时,
h j h j 1 = W T × d i a g [ f ( j j 1 ) ] = W T × d i a g [ 1 ( t a n h ) 2 ] \frac{\partial h_j}{\partial h_{j-1}}=W^T \times diag[f^{'}(j_{j-1})]= W^T \times diag[1-(tanh)^2]
因此,总的导数为:
在这里插入图片描述
其中,
在这里插入图片描述
β W \beta_W β h \beta_h 分别表示两个矩阵2范式的上界;
因此,
在这里插入图片描述
当t-k足够大是, β W β h \beta_W\beta_h 小于1会出现梯度消失, β W β h \beta_W\beta_h 大于1会出现梯度爆炸。
在实验中,当出现梯度爆炸时,会导致计算流中出现NaN,所以比较检测出来;仔细看上述的分析,我们可以知道,梯度消失在计算过程中不会报错,只是在较前时间步的梯度贡献很少(或者为0),因此比较难察觉出来。

2.4 Solution to the Exploding & Vanishing Gradients

为了解决梯度爆炸问题,当梯度比较大时,我们设定一个阈值,使梯度不大于这个值,具体如下:
在这里插入图片描述
为了解决梯度消失问题,可以使用的方法有:1. 初始化权重 W ( h h ) W^{(hh)} 为单位矩阵代替随机初始化(优化指数衰减的第一项);2. 使用ReLU激活函数代替sigmoid, tanh等(因为ReLU导数为1,优化指数衰减的第二项);3. 从根本上修改,RNN模型改为LSTM(后面会介绍该模型)。

2.5 Deep Bidirectional RNNs

双向RNN是指从左到右以及从右到左两个方向的RNN模型,如下图:
在这里插入图片描述
公式:
在这里插入图片描述
深度双向RNN顾名思义就是多层的双向RNN,如下图:
在这里插入图片描述
公式:
在这里插入图片描述
在这里插入图片描述

2.6 Application: RNN Translation Model

这一小节将RNN应用于机器翻译模型,包括encoder, decoder两个阶段,如下图:
在这里插入图片描述
公式:
在这里插入图片描述
第一条公式表示encoder阶段,第二三条公式表示decoder阶段。
上述例子只能产生一个输出结果,且模型的解码能力有限,更通常的,我们使用以下的编解码方式:
在这里插入图片描述
在这里插入图片描述
一些tricks:
1. encoder和decoder阶段使用不同的RNN权重;
2. decoder阶段使用三个类型的输入(入上图所示),包括前一个时刻的隐藏层,encoder变量,上一个时刻的预测输出;
3. 训练多层的RNN模型(前提是要有足够大的语料);
4. encoder阶段训练双向的RNN模型;
5. 使用倒序的方法训练RNN模型。(ABC->XY改为CBA->XY)。

3 Gated Recurrent Units

GRU是在隐藏层 h t h_{t} h t 1 h_{t-1} 的过程中,使用了复杂的门控激活函数来修正RNN结构,具体如下:
在这里插入图片描述
结构图:
在这里插入图片描述
每个结构的解析:

  1. New memory generation(新的记忆单元): 新的记忆单元 h ^ t \hat h_t 是新输入词 x t x_t 与过去的隐藏状态 h t 1 h_{t-1} 的合并。从人类学的角度来看,这一阶段是将新观察到的词与过去的隐藏状态 h t 1 h_{t-1} 结合起来以根据上下文过去作为向量 h ^ t \hat h_t ;
  2. Reset Gate(重置门): r t r_t 负责确定 h t 1 h_{t-1} 对于 h ^ t \hat h_t 有多重要。如果重置门发现 h t 1 h_{t-1} 与新的记忆单元的计算无关,则它有能力完全消除过去的隐藏状态;
  3. Update Gate(更新门): z t z_t 负责确定应将多少 h t 1 h_{t-1} 结转到下一状态。例如,如果 z t z_t ≈1,则 h t 1 h_{t-1} 几乎全部复制到ht。相反,如果 z t z_t ≈0,则大多数新的记忆单元 h ^ t \hat h_t 将转发到下一个隐藏状态;
  4. Hidden state:最终更新门的建议下, 使用过去的隐藏输入 h t 1 h_{t-1} 和新的记忆单元 h ^ t \hat h_t 生成隐藏状态 h t h_{t}

4 Long-Short-Term-Memories

LSTM有点类似于GRU,只是隐藏层 h t h_{t} h t 1 h_{t-1} 的门控激活函数有一些不同,具体如下:
在这里插入图片描述
结构图:
在这里插入图片描述
每个结构的解析:

  1. New memory generation(新的记忆单元): 此阶段类似于我们在GRU中看到的新的记忆单元生成阶段。我们实质上是使用输入词 x t x_t 和过去的隐藏状态 h t 1 h_{t-1} 来生成一个新的记忆单元 c ~ t \widetilde c_t ,其中包括新词 x ( t ) x^{(t)} 的各个方面;
  2. Input Gate(输入门): 我们看到,新的记忆单元生成阶段不会在生成新的记忆单元之前检查新单词是否重要-这正是输入门的功能。输入门使用输入词和过去的隐藏状态来确定输入是否值得保留,因此用于门控新记忆单元。因此,它将其作为此信息的指示;
  3. Forget Gate(忘记门): 该门与输入门相似,不同之处在于它不确定输入词的有用性,而是评估过去的记忆单元是否对当前记忆单元的计算有用。因此,忘记门查看输入的单词和过去的隐藏状态并产生 f t f_t ;
  4. Final memory generation: 该阶段首先接受遗忘门 f t f_t 的建议,并因此遗忘过去的记忆单元 c t 1 c_{t-1} 。类似地,它接受输入门的建议,将其选通,并相应地选通新的记忆单元。然后,将这两个结果相加,以生成最终记忆 c t c_{t}
  5. Output/Exposure Gate: 这是GRU中未明确存在的门。目的是将最终记忆与隐藏状态分开。最终记忆单元 c t c_t 包含很多信息,这些信息不一定需要以隐藏状态保存。在LSTM的每个单独的门中都使用了隐藏状态,因此,此门将对记忆单元ct的哪些部分需要在隐藏状态 h t h_t 中进行暴露/呈现进行评估。

猜你喜欢

转载自blog.csdn.net/Flying_sfeng/article/details/105312964