写在前面
在CNN网络中的训练样本数据为iid(独立同分布数据),所解决的问题也是分类问题或者回归问题或者是特征表达问题。但更多的数据是不满足iid的,如语音翻译,自动文本生成。它们是一个序列问题,包括时间序列和空间序列。这时就要用到RNN网络。
传统语言模型
语言模型就是计算一个单词序列(句子)的概率$P(w_1,w_2,….w_m)$的模型。比如在机器翻译中,判断译文序列中一种词序的自然程度高于另一种,判断一种用词选择优于另一种。
为了简化问题,必须引入马尔可夫假设,句子的概率通常是通过待预测单词之前长度为n的窗口,建立条件概率来预测:
为了估计此条件概率,常用最大似然估计,对于Bigram核TriGram有
在数据量足够多的情况下,n-gram中,n越大,模型效果越好。但实际上,数据量总是不如人意,这时候一些平滑方法就不可缺失。另外,这些ngram可能会占用上百G的内存
深度学习语言模型
深度学习语言模型则比传统语言模型大大简化。训练过程非常简单,前期只要手机一个很大的语料库。
神经网络的输入和输出为
然后进行最小化交叉熵。可以看到尽管我们仍需要将句子拆成2-gram的形式,但是我们做法不是用贝叶斯的方法,而是神经网络计算出来的。
显然简便了许多。
Recurrent Neural Networks
新的语言模型是利用RNN对序列建模,服用不同时刻的线性和非线性单元及权值。理论上之前所有单词都会影响到预测单词
所需内存只与词表大小成正比,不取决于序列长度。
给定一个词向量序列:$x_1,…,x_{t-1},x_{t},x_{t+1},…,x_T$,在每个时间点上都有隐藏层的特征表示:
其中,
- $x_t∈R^d$:是时间t时输入的单词的词向量
- $W^{hx}∈R^{D_h×d}$:用来condition输入词向量$x_t$的权值矩阵。
- $W^{hh}∈R^{D_h×D_h}$:用来condition前一个时间节点隐藏层特征表示$h_{t-1}$的权值矩阵
- $h_{t-1}∈R^{D_h}$:前一个时间点t-1的非线性激活函数的输出
- $\sigma()$:非线性激活函数(sigmoid)
$\hat{y_t}=softmax(W^{(S)}h_t):$在时间t时输出的整个词表|V|上的概率分布,$\hat{y_t}$是给定上下文$h_{t-1}$和最近的单词$x^{(t)}$预测的下一个单词。其中$W^{(S)}∈R^{|V|×D_h}$,$\hat{y}∈R^{|V|}$
另外,这里的$W^{(hh)}h_{t-1}+W^{(hx)}x_t$与拼接两个向量乘以权值矩阵的拼接是一样的。
未展开的网络:
等效于
损失函数的问题:则显然是以词表大小为类别数的分类问题。
RNN的众多变体
上图的图1是cnn, 图2到图5是RNN的变体
图2的示例: Image captioning: image——> sequence of words
图3的示例: Sentiment Classification: sequence of words ——> sentiment
图4的示例:Machine Translation: seq of words——> seq of Words
图5的示例: Video classification on frame level
RNN的最重要的变体是被应用于编码器解码器
Example: Character-level Language Model
Example Character-level Language Model Sampling
At test-time sampling characters one at a time, feed back to model.
这里用Softmax后得到的概率,进行采样。而不是直接取最大值。
奇奇怪怪的RNN
训练RNN困难
有可能会出现梯度消失和梯度爆照
防止梯度爆照
我们常会做的是梯度截断法(clipping trick).
以及设置好的权重初值
还有就是适当得减小学习率
防止梯度消失
与其随机初始化参数矩阵,不如初始化为单位矩阵。
用ReLu,maxout也可减缓梯度消失。[因为sigmoid的函数的梯度会随着x的变换而变化
Softmax的计算量大且速度慢
trick: 基于类的词语预测
可以根据频繁程度来分类。
显然,类越多,perplexity越好,但是速度越慢
Bidirectional RNN
这里箭头表示从左到右或从右到左向前传播,对于每个时刻t的预测,都需要来自双向的特征向量,拼接后进行分类。箭头虽然不同,但参数还是同一套参数。
Deep Birdirectional RNNs
LSTM
长期记忆网络-通常被称为“lstm”-是一种特殊的rnn,能够学习长期依赖关系。它们是由Hochreiter&Schmidhuber(1997)介绍的,并在后续工作中得到了许多人的改进和推广。它们在各种问题上做得非常好,现在得到了广泛的应用。
LSTM的明确设计是为了避免长期依赖问题。长时间记忆信息实际上是他们的默认行为,而不是他们努力学习的东西!
所有递归神经网络都具有神经网络重复模块链的形式。在标准的RNN中,这个重复模块将有一个非常简单的结构,例如一个tanh层。
上图是我们前面介绍的标准的RNN。
LSTM也有类似链的结构,但是重复模块有不同的结构。而不是有一个单一的神经网络层,有四个,以一种非常特殊的方式相互作用。
在下面的图表中,每一条线包含一个完整的向量,从一个节点的输出到其他节点的输入。粉红色的圆圈代表点运算,如向量加法,而黄色框是学习的神经网络层。线合并表示连接,而线分叉表示其内容被复制,并且复制到不同的位置。
LSTM后的核心思想
LSTM引入一个核心元素就是状态,让它“合理地”保存长期地状态.
假设新增的状态c,称为记忆单元状态,亦称”记忆块”,用以取代传统的隐含神经元节点。它负责把记忆信息从序列的初始位置,传递到序列的末端。
上图按时间步展开的RNN的网络。
从上图可看出,在LSTM结构中,在t时刻,当前神经元(粗红线标识)的输入有三个:当前时刻输入值$x_t$,前一时刻输出值$s_{t-1}$和前一时刻的记忆单元状态$c_{t-1}$。输出有两个:当前时刻LSTM输出值$s_t$和当前时刻的记忆单元状态$c_t$.需要注意的是,这里的x,s和c都是向量,里面都包含多个参数值。
LSTM的设计思路是设计3把控制门开关(gate),从而打造一个可控记忆神经元。
gate1第一门开关是Forget gate.
gate2第二门开关是Input gate.
gate3第三门开关是output gate.
gate1:
gate2:
gate3:
上面我们用输入数据和隐状态来定义各个门。
LSTM 具体步骤:
- 使用当前词$x_t$和之前隐状态$h_t$来生成新的记忆$\widetilde{c_t}$
- Input gate 决定当前新记忆是否值得保留下来的gate
- Forget gate 衡量过去的记忆$c_{t-1}$对当前记忆是否有用来的gate
- Final memory generation: 结合2,3步得到
- Output/Exposure Gate: 可以理解为在这个时间点有信息会暂时遗忘
GRU
GRU与LSTM一样,会让网络学习选择性遗忘。从而将记忆保持很久。
GRU也引入了门的概念,不过这里只存在两个门(update gate 和 reset gate).
如上图所示,是一个完整的GRU模型。
我们还是先介绍两个门update gate和 reset gate
上述是GRU中的门的计算。上述计算中有将$h_{t-1}和x_t$进行合并后与W进行矩阵相乘,实际上就等价于$W_zx_t+U_zh_{t-1}$
用上述两个门的量来决定有多少记忆保留有多少遗忘。
该公式是用来计算候选隐藏层$\widetilde{h_t}$,这个候选隐藏层和LSTM中的$\widetilde{c_t}$是类似,可以看成是当前时刻的新信息,其中$r_t$是永安里控制需要保留多少之前的记忆
上式$z_t$控制需要从前一时刻的隐藏层$h_{t-1}$中遗忘多少信息,需要加入多少当前时刻的隐藏层信息$\widetilde{h_t}$,最后得到$h_t$,直接得到最后输出的隐藏层信息,需要注意这里与LSTM的区别是GRU中没有output gate.在GRU中$h_t$既是hidden state也是 output.
注意事项
这里两个模型中都有运算符号·,这个运算符是Hadamard products
Hadamard products:
参考文献
1.Speech Processing and Machine Learning Laboratory的李宏毅 (Hung-yi Lee)