循环神经网络
RNN
核心思想:RNN内部有一个“内部状态”,随着序列处理而更新 h t = f W ( h t − 1 , x t ) h_t=f_W(h_{t-1},x_t) ht=fW(ht−1,xt)
h t h_t ht是new state, h t − 1 h_{t-1} ht−1是old state, x t x_t xt是当前时间步的输入,所有时间步共享 f W f_W fW这个函数和参数
y t = f W h y ( h t ) y_t=f_{W_{hy}}(h_t) yt=fWhy(ht)是当前时间步的输出
分块损失计算:计算所有时间步的前向传播,但只在每时间块内进行反向传播
RNN:
one-to-many:两种情况:
- x作为输入就最开始的一次,输出为 y 1 , y 2 . . . y_1,y_2... y1,y2...
- x作为输入多次,每轮都有x作为输入,输出为 y 1 , y 2 . . . y_1,y_2... y1,y2...
many-to-many:两种情况:
- 输入、输出都是等长的序列数据。每一步使用的参数U、W、b都是一样的,也就是说每个步骤的参数都是共享的,这是RNN的重要特点,一定要牢记。
- 输入输出不等长:encoder-decoder结构,Encoder先将输入数据编码成一个上下文语义向量c,语义向量c可以有多种表达方式,最简单的方法就是把Encoder的最后一个隐状态赋值给c,还可以对最后的隐状态做一个变换得到c,也可以对所有的隐状态做变换。拿到c之后,就用另一个RNN网络对其进行解码,这部分RNN网络被称为Decoder
RNN优势:
- 可以处理任意长度的序列
- 步骤t的计算(理论上)可以使用之前许多步骤的信息
- 输入时间越长,模型尺寸就越大
- 每个时间步都使用了相同的权重
RNN缺点:
- 循环计算速度慢
- 在实践中,很难从多个步骤中获取信息(遗忘)
LSTM
LSTM引入了三个门( 输入门、遗忘门、输出门)和一个 细胞状态(cell state)
LSTM可以在一定程度上解决梯度消失和梯度爆炸的问题,但不是完全解决
LSTM架构使RNN更容易在多个时间步长内保存信息
LSTM的连乘是 C t C_t Ct对 C t − 1 C_{t-1} Ct−1的偏导的不断累乘,如果前后的记忆差别不大,那偏导的值就是1,那就是多个1相乘。当然,也可能出现某一一些偏导的值很大,但是一定不会很多(换句话说,一句话的前后没有逻辑,那完全没有训练的必要)。
LSTM使用 t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} tanh(x)=ex+e−xex−e−x函数,而不用Sigmoid函数的原因:
- Sigmoid函数比Tanh函数收敛饱和速度慢
- Sigmoid函数比Tanh函数值域范围更窄
- tanh的均值是0,Sigmoid均值在0.5左右,均值在0的数据显然更便于数据处理
- tanh的函数变化敏感区间更大
- 对两者求导,发现tanh对计算的压力更小,直接是1-原函数的平方,不需要指数操作
forget gate:选择忘记过去某些信息
input gate:记忆现在的某些信息
i t i_t it门控信号决定了当前时间步应该更新细胞状态的哪些部分
C ~ t \widetilde C_t C t候选记忆单元代表了当前时间步可能被加入到细胞状态中的新信息
将过去与现在的记忆进行合并
output gate:输出
GRU
可以被看作是LSTM的简化版。它保留了门控机制中的更新门和重置门,用于控制信息的流动,但省略了LSTM中的单独记忆单元。相比LSTM,GRU拥有更少的参数,因此计算效率更高,通常在一些任务上可以获得相近甚至更好的效果。