RNN之LSTM

循环神经网络不仅容易出现梯度弥散或者梯度爆炸,还不能处理较长的句子,也就是具有短时记忆(Short-term memory)
 

为了克服这些缺点,提出了长短时记忆网络(Long Short-Term Memory,简称 LSTM)。 LSTM 相对于基础的 RNN 网络来说,记忆能力更强,更擅长处理较长的序列信号数据

一、LSTM原理

基础的 RNN 网络结构如图,上一个时间戳的状态向量 h𝑡-1与当前时间戳的输入𝒙𝑡经过线性变换后,通过激活函数𝑡𝑎𝑛ℎ后得到新的状态向量 h𝑡。 相对于基础的 RNN网络只有一个状态向量 h𝑡,LSTM 新增了一个状态向量𝑪𝑡,同时引入了门控(Gate)机制, 通过门控单元来控制信息的遗忘和刷新,如图

在 LSTM 中,有两个状态向量𝒄和h其中𝒄作为 LSTM 的内部状态向量,可以理解为LSTM 的内存状态向量 Memory,而 h表示 LSTM 的输出向量。 相对于基础的 RNN 来说,LSTM 把内部 Memory 和输出分开为两个变量,同时利用三个门控:输入门(Input Gate)遗忘门(Forget Gate)输出门(Output Gate)来控制内部信息的流动。
 

门控机制可以理解为控制数据流通量的一种手段,在 LSTM 中,阀门开和程度利用门控值向量𝒈表示

通过𝜎(𝒈)激活函数将门控制压缩到[0,1]之间区间, 当𝜎(𝒈) = 0时,门控全部关闭,输出𝒐 = 0;当𝜎(𝒈) = 1时,门控全部打开,输出𝒐 = 𝒙。 通过门控机制可以较好地控制数据的流量程度。
 

1.遗忘门

遗忘门作用于 LSTM 状态向量𝒄上面,用于控制上一个时间戳的记忆𝒄𝑡-1对当前时间戳的影响

遗忘门的控制变量𝒈𝑓由g_{f} = \sigma (W_{h}[h_{t-1},x_{t}] + b_{f})产生,。 当门控g_{f} = 1时,遗忘门全部打开, LSTM 接受上一个状态c_{t-1}的所有信息当门控 g_{f}= 0时,遗忘门关闭, LSTM 直接忽略c_{t-1}, 输出为 0的向量,经过遗忘门后, LSTM 的状态向量变为g_{f}c_{t-1}

 

 

2.输入门

输入门用于控制 LSTM 对输入的接收程度

 首先通过对当前时间戳的输入x_{t}和上一个时间戳的输出h_{t-1}做非线性变换得到新的输入向量\tilde{c}t:\tilde{c_{t}} = \tanh (W_{c}[h_{t-1},x_{t}] + b_{c}),tanh 为激活函数,用于将输入标准化到[-1,1]区间。\tilde{c}t并不会全部刷新进入 LSTM 的 Memory,而是通过输入门控制接受输入的量

 

输入门的控制变量同样来自于输入x_{t}和输出 h_{t-1}g_{i} = \sigma (W_{i}[h_{t-1},x_{t}] + b_{i}), 输入门控制变量g_{i}决定了 LSTM 对当前时间戳的新输入\tilde{c}t的接受程度: 当g_{i} = 0时, LSTM 不接受任何的新输入\tilde{c}t;当g_{i}= 1时, LSTM 全部接受新输入\tilde{c}t,经过输入门后, 待写入 Memory 的向量为g_{i}\tilde{c_{t}}

 

在遗忘门和输入门的控制下, LSTM 有选择地读取了上一个时间戳的记忆c_{t-1}和当前时间戳的新输\tilde{c}t, 状态向量\tilde{c}t的刷新方式为c_{t} = g_{i}\tilde{c_{t}} + g_{f}c_{t-1}得到的新状态向量c_{t}即为当前时间戳的状态向量

 

 3.输出门

LSTM 的内部状态向量c_{t}并不会直接用于输出,这一点和基础的 RNN 不一样。基础的RNN 网络的状态向量既用于记忆, 又用于输出,所以基础的 RNN 可以理解为状态向量𝒄和输出向量是同一个对象。 在 LSTM 内部,状态向量并不会全部输出,而是在输出门的作用下有选择地输出

 

输出门的门控变量g_{o}为:g_{o} = \sigma (W_{o}[h_{t-1},x_{t}] + b_{o})。当输出门g_{o}= 0时,输出关闭, LSTM 的内部记忆完全被隔断, 无法用作输出,此时输出为 0 的向量;当输出g_{o}= 1时,输出完全打开, LSTM 的状态向量c_{t}全部用于输出。 LSTM 的输出由h_{t} = g_{o}.\tanh (c_{t})产生,即内存向量c_{t}经过tanh激活函数后与输入门作用,得到 LSTM 的输出。 由于g_{o}∈[0,1], tanh(c_{t}) ∈ [-1,1],因此 LSTM 的输出 h_{t}∈ [-1,1]。

二、LSTM实现

 在 TensorFlow 中, 同样有两种方式实现 LSTM 网络。既可以使用 LSTMCell 来手动完成时间戳上面的循环运算,也可以通过 LSTM 层方式一步完成前向运算
 

1.LSTMCell

 LSTMCell和SimpleRNNCell 用法一致, 区别在于 LSTM 的状态变量 List 有两个即[ h𝑡, 𝒄𝑡], 需要分别初始化,其中 List 第一个元素为 h𝑡,第二个元素为𝒄𝑡。 调用 cell完成前向运算时,返回两个元素:  第一个元素为 cell 的输出h𝑡,第二个元素为cell 的更新后的状态 List: [ h𝑡, 𝒄𝑡]。

x = tf.random.normal([2, 80, 100])
cell = layers.LSTMCell(64)   # 创建LSTM Cell
# 初始化状态
state = [tf.zeros([2, 64]), tf.zeros([2, 64])]
# 向前计算
for xt in tf.unstack(x, axis=1):
    out, state = cell(xt, state)

返回的输出out和state列表的第一个元素ht是一样的

2.LSTM层

经过 LSTM 层前向传播后,默认只会返回最后一个时间戳的输出, 如果需要返回每个时间戳上面的输出, 需要设置 return_sequences=True 标志。对于多层神经网络, 可以通过 Sequential 容器包裹多层 LSTM 层,并设置所有非末层网络 return_sequences=True,这是因为非末层的 LSTM 层需要上一层在所有时间戳的输出作为输入

x = tf.random.normal([2, 80, 100])
net = Sequential([
    layers.LSTM(64, return_sequences=True),  # 非末层需要返回所有时间戳输出
    layers.LSTM(64)
])
# 一次通过网络模型,即可得到最末层、最后一个时间戳的输出
out = net(x)

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值