<style type="text/css">
th{padding:5px; font-size: 14px; background-color:#e6baff;}
td{padding:5px; font-size: 14px;}
</style>
神经网络是深度学习的载体,而神经网络模型中,最经典非RNN模型所属,尽管它不完美,但它具有学习历史信息的能力。后面不管是encode-decode 框架,还是注意力模型,以及自注意力模型,以及更加强大的Bert模型家族,都是站在RNN的肩上,不断演化、变强的。
这篇文章,阐述了RNN的方方面面,包括模型结构,优缺点,RNN模型的几种应用,RNN常使用的激活函数,RNN的缺陷,以及GRU,LSTM是如何试图解决这些问题,RNN变体等。
这篇文章最大特点是图解版本,其次语言简练,总结全面。
<font size="3" style="line-height: 45px;" color="#c200ff"><strong>概述</strong></font>
传统RNN的体系结构。Recurrent neural networks,也称为RNNs,是一类允许先前的输出用作输入,同时具有隐藏状态的神经网络。
它们通常如下所示:
<center><img width="600" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="传统RNN的体系结构"></center><br>
对于每一时步 t , 激活函数 a<sup><t></sup> ,输出 y<sup><t></sup>被表达为:
<center> a<sup><t></sup> = g1( W<sub>aa</sub>a<sup><t-1></sup> + W<sub>ax</sub>x<sup><t></sup> + b<sub>a</sub> ) </center>
<center> y<sup><t></sup> = g2( W<sub>ya</sub>a<sup><t></sup> + b<sub>y</sub> ) </center>
<br />
这里 W<sub>ax</sub>,W<sub>aa</sub>,W<sub>ya</sub>,b<sub>a</sub>,b<sub>y</sub> 是时间维度网络的共享权重系数
g1,g2是激活函数
<center><img width="600" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="传统RNN"></center><br>
下表总结了典型RNN架构的优缺点:
<table border="1" align="center">
<tr>
<th>优点</th><th>缺点</th>
</tr>
<tr>
<td>处理任意长度的输入</td><td>计算速度慢</td>
</tr>
<tr>
<td>模型形状不随输入长度增加</td><td>难以获取很久以前的信息</td>
</tr>
<tr>
<td>计算考虑了历史信息</td><td>无法考虑当前状态的任何未来输入</td>
</tr>
<tr>
<td>权重随时间共享</td><td> / </td>
</tr>
</table>
<br />
<font size="3" style="line-height: 45px;" color="#c200ff"><strong>RNNs应用</strong></font>
RNN模型主要应用于自然语言处理和语音识别领域。下表总结了不同的应用:
<table border="1" align="center">
<tr>
<th>RNN类型</th>
<th>图解</th>
<th>例子</th>
</tr>
<tr>
<td>1对1 <br />T<sub>x</sub> = T<sub>y</sub> = 1 </td>
<td><img width="250" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RNN模型主要应用 - 传统神经网络"></td>
<td>传统神经网络</td>
</tr>
<tr>
<td>1对多<br />T<sub>x</sub> = 1 ,T<sub>y</sub> > 1</td>
<td><img width="250" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RNN模型主要应用 - 音乐生成"></td>
<td>音乐生成</td>
</tr>
<tr>
<td>多对1 <br />T<sub>x</sub> > 1 ,T<sub>y</sub> = 1 </td>
<td><img width="250" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RNN模型主要应用 - 情感分类"></td>
<td>情感分类</td>
</tr>
<tr>
<td>多对多 <br />T<sub>x</sub> = T<sub>y</sub> </td>
<td><img width="250" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RNN模型主要应用 - 命名实体识别"></td>
<td>命名实体识别</td>
</tr>
<tr>
<td>多对多 <br />T<sub>x</sub> ≠ T<sub>y</sub></td>
<td><img width="250" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RNN模型主要应用 - 机器翻译"></td>
<td>机器翻译</td>
</tr>
</table>
<br />
<font style="line-height: 40px;"><strong>损失函数</strong></font>
对于RNN网络,所有时间步的损失函数 <img src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="损失函数"> 是根据每个时间步的损失定义的,如下所示:
<center><img width="260" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="损失函数"></center><br>
<font style="line-height: 40px;"><strong>时间反向传播</strong></font>
在每个时间点进行反向传播。在时间步 T ,损失 <img src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="损失函数"> 相对于权重矩阵 W 的偏导数表示如下:
<center><img width="200" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="时间反向传播"></center><br>
<font size="3" style="line-height: 45px;" color="#c200ff"><strong>处理长短依赖</strong></font>
<font style="line-height: 40px;"><strong>常用激活函数</strong></font>
RNN模块中最常用的激活函数描述如下:
<table border="1" align="center">
<tr>
<th>Sigmoid</th>
<th>Tanh</th>
<th>RELU</th>
</tr>
<tr>
<td><img width="185" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="Sigmoid"></td>
<td><img width="185" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="Tanh"></td>
<td><img width="185" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="RELU"></td>
</tr>
</table>
<br />
<font style="line-height: 40px;"><strong>梯度消失/爆炸</strong></font>
在RNN中经常遇到梯度消失和爆炸现象。之所以会发生这种情况,是因为很难捕捉到长期的依赖关系,因为乘法梯度可以随着层的数量呈指数递减/递增。
<font style="line-height: 40px;"><strong>梯度修剪</strong></font>
梯度修剪是一种技术,用于执行反向传播时,有时遇到的梯度爆炸问题。通过限制梯度的最大值,这种现象在实践中得以控制。
<center><img width="600" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="梯度修剪"></center><br>
<font style="line-height: 40px;"><strong>门的类型</strong></font>
为了解决消失梯度问题,在某些类型的RNN中使用特定的门,并且通常有明确的目的。它们通常标注为 Γ,等于:
<center>Γ = σ( Wx<sup><t></sup> + Ua<sup><t-1></sup> +b ) </center>
<br />
其中,W,U,b 是特定于门的系数,σ 是sigmoid函数。主要内容总结如下表:
<table border="1" align="center">
<tr>
<th>门的种类</th>
<th>作用</th>
<th>应用</th>
</tr>
<tr>
<td>更新门Γ<sub>u</sub></td>
<td>过去对现在有多重要?</td>
<td>GRU, LSTM</td>
</tr>
<tr>
<td>关联门Γ<sub>r</sub></td>
<td>丢弃过去信息?</td>
<td>GRU, LSTM</td>
</tr>
<tr>
<td>遗忘门Γ<sub>f</sub></td>
<td>是不是擦除一个单元?</td>
<td>LSTM</td>
</tr>
<tr>
<td>输出门Γ<sub>o</sub></td>
<td>暴露一个门的多少?</td>
<td>LSTM</td>
</tr>
</table>
<br />
<font style="line-height: 40px;"><strong>GRU/LSTM</strong></font>
Gated Recurrent Unit(GRU)和长-短期记忆单元(LSTM)处理传统RNNs遇到的消失梯度问题,LSTM是GRU的推广。下表总结了每种结构的特征方程:
<center><img width="600" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="GRU和LSTM的特征方程"></center><br>
注:符号★表示两个向量之间按元素相乘。
<font style="line-height: 40px;"><strongRNN的变体</strong></font>
下表总结了其他常用的RNN模型:
<table border="1" align="center">
<tr>
<th>Bidirectional (BRNN)</th>
<th>Deep (DRNN)</th>
</tr>
<tr>
<td><img width="265" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="Bidirectional (BRNN)"></td>
<td><img width="200" src="http://imgtec.eetrend.com/files/2021-05/%E5%8D%9A%E5%AE%A2/100112570-20…; alt="Deep (DRNN)"></td>
</tr>
</table>
<br />
<font color="#9a9a9a">参考文献:</font>
https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-recurrent-neu…
<font color="#9a9a9a">来源:Python与算法社区-zhenguo
原文链接:https://mp.weixin.qq.com/s/F5OQKlgrDTMo_bGM4A10yQ</font>