循环神经网络

循环神经网络

递归神经网络RNN

RNN按照时间序列展开:

image-20240609180740711

正向传播

$t$时刻中间隐层输入$s_t = Ux_t + Wh_{t-1}$

$t$​时刻中间隐层输出$h_t = f(s_t)$​(其中$f$为sigmoid函数)

$t$时刻输出层输出$o_t = g(Vh_t)$(其中$g$为softmax函数)

损失函数为$L_t = -[y_tlogo_t + (1-y_t)log(1-o_t)]$

所有时间的损失为$L = sum_{t=1}^{T}L_t$

反向传播

首先对$V$求导,直接得到:

$\frac{\partial L}{\partial V} = \sum_{t=1}^T \frac{\partial L_t}{\partial V} = \sum_{t=1}^{T} \frac{\partial L_t}{\partial o_t} \frac{\partial o_t}{\partial V} = \sum_{t=1}^{T} -(\frac{y_t}{o_t} + \frac{y_t-1}{1-o_t}o_t(1-o_t)h_t^T) = \sum_{t=1}^{T} (o_t - y_t)h_t^T$

对$W$求梯度,

$\frac{\partial L}{\partial W} = \sum_{t=1}^T \frac{\partial L_t}{\partial W} =\sum_{t=1}^T \frac{\partial L_t}{\partial o_t} \sum_{k=1}^t \frac{\partial o_t}{\partial h_t} \frac{\partial h_t}{\partial h_k} \frac{\partial h_k}{\partial W} = \sum_{t=1}^T \sum_{k=1}^t \frac{\partial L_t}{\partial o_t}\frac{\partial o_t}{\partial h_t}(\prod_{j=k+1}^t \frac{\partial h_j}{\partial h_{j-1}})\frac{\partial h_k}{\partial W} $

依此类推出:

$\frac{\partial L}{\partial U} = \sum_{t=1}^T \sum_{k=1}^t \frac{\partial L_t}{\partial o_t}\frac{\partial o_t}{\partial h_t}(\prod_{j=k+1}^t \frac{\partial h_j}{\partial h_{j-1}})\frac{\partial h_k}{\partial U} $

弊端

传统RNN都采用反向传播时间算法(BPTT),随着时间流逝,网络层数增加,会产生梯度消失或者梯度爆炸的问题。

以$W$的梯度更新举例,使用激活函数假如是$tanh$

$\frac{\partial h_j}{\partial h_{j-1}} = W^T \odot tanh^{‘}, tanh^{‘} \in [0,1]$

👉梯度消失:如果$W$也是大于0小于1的数,当$t$很大时,$W^T \odot tanh^{‘} <1 $,连乘起来就会趋于0.

👉梯度爆炸:如果梯度比较大的话($\frac{\partial h_j}{\partial h_{j-1}} > 1$),经过多层迭代,又会导致梯度大的不得了,比如$1,01^{100}$。

梯度消失和爆炸实际上导致了网络只能学习到短周期的依赖关系

image-20240609184920246

随着时间的推移,对于 t>1 时刻的产生的影响会越来越小,由图中的颜色的深浅代表信号的大小。这种衰减会导致 RNN 无法处理长期依赖。

LSTM(长短时记忆神经网络Long short-term memory)

与RNN的区别

image-20240609185538836

· 原始RNN的隐藏层只有一个状态,即$h$,它对于短期输入非常敏感

· 再增加一个状态$c$,来保存长期的状态,称为单元状态或者内部记忆单元,记录了当前时刻为止的所有历史信息。

内部记忆单元C

image-20240609190147525

  1. 第一个开关,负责控制继续保存内部状态C(遗忘门)

    遗忘门可以保存很久很久之前的信息

    它决定了上一时刻的单元内部状态$c_{t-1}$有多少保留到当前内部时刻内部状态$c_t$

  2. 第二个开关,负责控制把当前内部候选状态输入到当前状态C(输入门)

    它决定了当前时刻网络的输入$x_t$有多少保存到当前单元内部状态$c_t$

  3. 第三个开关,负责控制是否把内部状态C作为当前LSTM的输出(输出门)

    它决定了内部状态$c_t$有多少输出到LSTM的当前输出值$h_t$

image-20240609190718664

核心思想:LSTM的关键在于细胞的状态整个(绿色的图表示的是一个cell),和穿过细胞的那条水平线。

细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。

image-20240609190919991

若只有上面的那条水平线是没办法实现添加或者删除信息的。而是通过一种叫做 门(gates) 的结构来实现的。

门可以实现选择性地让信息通过,主要是通过一个 sigmoid 的神经层 和一个逐点相乘的操作来实现的。

image-20240609191001406

LSTM的3个门

  1. 遗忘门(控制内部记忆单元遗忘哪些历史信息)$f_t$

    image-20240609191204577

    $f^t = \sigma(W_f \cdot h^{t-1} + U_f \cdot x^t + b_f)$

  2. 输入门(控制内部记忆单元加入多少新信息)

    Part1

    image-20240609191533333

    $i^t = \sigma (W_i h^{t-1} + U_ix^t + b_i)$

    $\tilde{c}^t = tanh(W_c h^{t-1} + U_c x^t + b_c)$

    Step1: 通过输入门的sigmoid层决定加入哪些新信息

    Step2: 再由tanh层通过$X$和$h$值,生成一个候选记忆向量。

    Part2

    image-20240609192027548

    $c^t = f^t * c^{t-1} + i^t * \tilde{c}^t$

    新的内部记忆单元包括两部分
    1 经过遗忘门过滤的旧状态信息
    2 候选记忆向量与通过输入门决定的 $𝑖^𝑡$的乘积

  3. 输出门

    image-20240609192228601

    $o^t = \sigma(W_o h^{t-1} + U_o x^t + b_o)$

    $h^t = o^t * tanh(c^t)$

    $c^t$通过tanh函数,将输出信息控制在-1到1之间。

    总结:

    image-20240609193920008

缓解梯度消失和爆炸

由正向传播公式:$c^t = f^t * c^{t-1} + i^t * \tilde{c}^t$

得到 $\frac{\partial c^{t+1}}{\partial c^t} = f^t + …$

可以看到当$f^t =1$时,就算其余项很小,梯度仍可以很好的导到上一时刻,此时即使层数较沈也不会发生梯度消失;当$f^t = 0$时,即上一时刻的信号不影响当前时刻,梯度也不会传回去。

训练过程

误差使用交叉熵函数

image-20240609194737135

image-20240609200610067

image-20240609200711616

image-20240609201125891

image-20240609201155275

image-20240609201223375

LSTM其他变体

  1. 合并遗忘门和输入门 $i_t + f_t$ =1

    image-20240609201410947

  2. GRU

    image-20240609201547466

    GRU只有两个门:更新门z和重置门r

    更新门:遗忘多少历史信息和接受多少新信息。

    重置门:候选状态中有多少信息是从历史信息中得到的。

    与LSTM的比较:

    1. GRU少了一个门,也少了一个细胞状态$c_t$
    2. GRU只需要重置门来控制是否要保留原来隐藏状态的信息,单步在限制当前信息的传入。
    3. 在 LSTM 中,虽然得到了新的细胞状态$ 𝒄_𝒕$,但是还不能直接输出,而是需要经过一个过滤的处理:;同样,在GRU 中, 虽然我们也得到了新的隐藏状态$\tilde{h}_t$, 但是还不能直接输出,而是通过更新门来控制最后的输出。

重点

  1. RNN构造
  2. RNN的梯度消失和梯度爆炸产生原因
  3. LSTM结构及核心思想

循环神经网络
https://wendyflv.github.io/2024/06/09/循环神经网络/
作者
Wendyflv
发布于
2024年6月9日
许可协议