RNN的自我和解
RNN
-
为什么要用RNN
-
输出是多个值,普通的前向传播网络只有一个 label。
-
输入之间有顺序关系,输出之间也有顺序关系。
综上,针对有顺序关系的预测值,可以用 RNN。
-
RNN 的特点
-
Multiple copies of the same network
因此常看见 rnn 的网络结构示意图,是自己指向自己。
牢记! RNN 的 w, b 在所有 units 间是一模一样的!所以叫做 copies。
2. hidden_state 作为下一个的输入。
-
RNN 的正向传播
-
h = tanh ( W_hh * h + W_xh *x) 这个 hidden_state 要传给下一个 lstm unit。
-
y = W_hy * h
-
根据 application 不同,我们可能 y0, y1,...yn 都重要(翻译),也可能只在乎最后一个(next word prediction)。
-
RNN 的反向传播
-
一直不太理解的点在于,既然所有 lstm unit 都用同样的 weight matrix,那反向传播,岂不是经过一个 unit 就要更新一遍?
其实是图像干扰了。写成表达式比较直接。
Yt = g(V*ht)
ht = tanh(....)
ht_1 = …
也就导致 yt 其实涉及了所有输入。因此反向传播的结果,也会涉及到纵向传播,以及横向传播。不会造成更新多次的问题。
但是也反映出“记忆” 所有 inputs。
2. 梯度爆炸/梯度消失
缘于 long-term dependencies。
因为要 trace back to t1,期间涉及 Whh + repeated gradient。small * small -> gradient vanish / large*large -> gradient explosion。
当序列很长的时候,尤为严重。
Sigmoid 函数及其导数(容易导致梯度消失)
Tanh 函数及其导数(容易导致梯度消失)
Relu 的函数及其导数(容易导致梯度爆炸)
3. 解决梯度问题
- 将激活函数从 tanh -> relu
- (tanh)’ = 1 - tanh*tanh
- (sigmoid)’ = sigmoid ( 1- sigmoid)
- 当 x > 0 时, tanh, sigmoid 的 gradient 都小于1,且随着 x 增大而减小。而 relu 的 gradient 永远是1,因此,能避免梯度消失 。
- 初始化 weights
- Identity matrix。
- 其实本质上没有解决问题,只要 iteration 次数增大,依然有这个问题。只不过将过程放缓了而已。
- Gated cell :
- 控制长期信息对当下的重要性影响。
- 不重要的信息扔掉,不用更新上一个状态。
- E.G: lstm,gru。
-
LSTM
-
Why:解决 long-term dependencies
-
重要结构-gate:通过 sigmoid 将输入限制到了(0,1)。可以想象成 how much information can be passed。
4. LSTM结构
- Forget:接了 sigmoid,说明 input 就被限制到了 (0, 1) 区间内。看图,发现过 sigmoid 的是 xt*h_(t-1) ,可以理解成以前的历史状态和现在越相似,越有保留的价值。否则,把历史都扔了。
- Store: 就更像是 rnn 的基础结构了。只不过还多了一个 sigmoid,同样是有的放矢的存储输入信息。
- Update:Store + forget 得到新的 cell state
- Output:还是 上一个的 hidden state + 当下 input,再过激活函数,得hidden_state。只不过多了些门。
5. 为什么 lstm 解决梯度爆炸问题
-
因为 gate 的输出,要么接近1,要么接近0。为1 时,减轻了梯度消失,为零时,为零时,放弃更新上一状态的梯度。
-
根据输入数据的不同,可能有的数据想让权重变大,有的数据想让权重变小。所以适当的遗忘一些输入数据,是合理的。
-