为了更好地解决序列信号问题,例如语音识别,机器翻译,情感分类,音乐发生器等,需要构建一种新的神经网络模型,RNN就是这样的序列模型
传统的神经网络模型
x < 1 > , x < 2 > , . . . , x < T s > x^{<1>},x^{<2>},...,x^{<T_s>} x < 1 > , x < 2 > , . . . , x < T s > 是序列模型的输入,即序列信号,T x T_x T x 表示输入信号的长度,例如一段文字的长度,一段语音包含的单词数目,y < 1 > , y < 2 > , . . . , y < T s > y^{<1>},y^{<2>},...,y^{<T_s>} y < 1 > , y < 2 > , . . . , y < T s > 是序列模型的输出,T y T_y T y 表示输出信号的长度。 如果使用标准的神经网络结构来处理,存在两个问题。 1.不同样本的输出序列长度或者输出的序列长度可能不同:例如无法确定两个句子中包含的单词数目是一样的 2.也是最主要的,这种标准神经网络结构无法共享序列不同。
基本的RNN模型
首先我们需要知道的是RNN输入信号的编码问题,我们知道序列信号可能是一段文字,也可能是一段语音,文字如何量化成数字信号的呢? 最常见的方式就是建立一个词汇表(例如1000个单词),每个单词使用One-Hot形式进行编码,这样一个单词就由1000*1的向量组成。该向量对应词汇表顺序,相应单词对应位置为1,其他位置为0
RNN正向传播
RNN模型包含三类权重系数,分别是W a x , W a a , W y a W_{ax},W_{aa},W_{ya} W a x , W a a , W y a ,且不同元素之间同一位置共享同一权重系数,这样做的有点是模型参数与序列信号长度无关。 上图展示了一个包含隐藏层的RNN模型,正向传播(Forward Propagation)过程的表达式如下a < t > = g ( W a a ∗ a < t − 1 > + W a x ∗ x < t > + b a ) a^{<t>} = g(W_{aa}*a^{<t-1>}+W_{ax}*x^{<t>}+b_a) a < t > = g ( W a a ∗ a < t − 1 > + W a x ∗ x < t > + b a ) y ^ < t > = g ( W y a ⋅ a < t > + b y ) hat{y}^{<t>}=gleft(W_{y a} cdot a^{<t>}+b_{y}right) y ^ < t > = g ( W y a ⋅ a < t > + b y ) 其中g ( . ) g(.) g ( . ) 表示**函数,不同的问题需要使用不同的**函数,b a b_a b a 表示输入层到隐藏层的常数项,b y b_y b y 表示隐藏层到输出层的常数项。 为了简化表达式,可以对a < t > a^{<t>} a < t > 项进行整合W a a ⋅ a < t − 1 > + W a x ⋅ x < t > = [ W a a W a x ] [ a < t − 1 > x < t > ] → W a [ a < t − 1 > , x < t > ] begin{array}{c}W_{a a} cdot a^{<t-1>}+W_{a x} cdot x^{<t>}=left[W_{a a} W_{a x}right]left[begin{array}{l}a^{<t-1>} \x^{<t>}end{array}right] \rightarrow W_{a}left[a^{<t-1>}, x^{<t>}right]end{array} W a a ⋅ a < t − 1 > + W a x ⋅ x < t > = [ W a a W a x ] [ a < t − 1 > x < t > ] → W a [ a < t − 1 > , x < t > ] 则正向传播可表示为a < t > = g ( W a [ a < t − 1 > , x < t > ] + b a ) y ^ < t > = g ( W y ⋅ a < t > + b y ) begin{array}{c}a^{<t>}=gleft(W_{a}left[a^{<t-1>}, x^{<t>}right]+b_{a}right) \hat{y}^{<t>}=gleft(W_{y} cdot a^{<t>}+b_{y}right)end{array} a < t > = g ( W a [ a < t − 1 > , x < t > ] + b a ) y ^ < t > = g ( W y ⋅ a < t > + b y ) 每个时刻的参数是共享的
RNN反向传播
RNN模型的损失函数与其他机器学习模型类似。如果是分类问题,则可使用交叉熵损失;如果是回归问题,则可使用MSE、MAE或者Huber损失。以分类问题为例,RNN模型中单个元素的损失函数为L < t > ( y ^ < t > , y < t > ) = − y < t > log y ^ < t > − ( 1 − y < t > ) log ( 1 − y ^ < t > ) L^{<t>}left(hat{y}^{<t>}, y^{<t>}right)=-y^{<t>} log hat{y}^{<t>}-left(1-y^{<t>}right) log left(1-hat{y}^{<t>}right) L < t > ( y ^ < t > , y < t > ) = − y < t > log y ^ < t > − ( 1 − y < t > ) log ( 1 − y ^ < t > ) 该样本序列信号所有元素的损失函数为L ( y ^ , y ) = ∑ t = 1 T y L < t > ( y ^ < t > , y < t > ) L(hat{y},y) = sum_{t=1}^{T_y} L^{<t>}(hat{y}^{<t>},y^{<t>}) L ( y ^ , y ) = t = 1 ∑ T y L < t > ( y ^ < t > , y < t > ) 然后,与其他机器学习模型类似,使用梯度优化算法,对参数W a , W y , b a , b y W_a,W_y,b_a,b_y W a , W y , b a , b y 分别计算偏导数,并更新,直到训练完成。
BRNN(Bidirectional RNN)
BRNN能够同时对序列进行双向处理,性能大大提高。但缺点是计算量较大,且在处理实时语音时,需要等到完整的一句话结束时才能进行分析。 除了单隐藏层的RNN之外,还有多隐藏层的Deep RNNs。Deep RNNs是由多层RNN组成,其结构如下所示