提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
- 探幽入微LSTM长短期记忆
提示:以下是本篇文章正文内容,下面案例可供参考
1.任务描述
本关任务了解 LSTM 的核心思想,根据教程指导创建 LSTM 网络的一个 LSTMCell 。
2.相关知识
为了完成本关任务,你需要掌握:
- 什么是长期依赖问题;
- LSTM 网络的基本结构;
- 如何创建一个 LSTM 网络的基本单元。
长期依赖(Long-Term Dependencies)问题
RNN 的关键点之一就是他们可以用来连接先前的信息到当前的任务上,例如使用过去的视频段来推测对当前段的理解。如果 RNN 可以做到这个,他们就变得非常有用。但是真的可以么?答案是,还有很多依赖因素。有时候,我们仅仅需要知道先前的信息来执行当前的任务。例如,我们有一个 语言模型用来基于先前的词来预测下一个词。如果我们试着预测 “the clouds are in the sky” 最后的词,我们并不需要任何其他的上下文 —— 因此下一个词很显然就应该是 sky。在这样的场景中,相关的信息和预测的词位置之间的间隔是非常小的, RNN 可以学会使用先前的信息。
LSTM 网络
Long Short Term 网络—— 一般就叫做 LSTM ——是一种 RNN 特殊的类型,可以学习长期依赖信息。LSTM 由 Hochreiter & Schmidhuber (1997) 提出,并在近期被 Alex Graves 进行了改良和推广。在很多问题, LSTM 都取得相当巨大的成功,并得到了广泛的使用。
LSTM 通过刻意的设计来避免长期依赖问题。记住长期的信息在实践中是 LSTM 的默认行为,而非需要付出很大代价才能获得的能力!
所有 RNN 都具有一种重复神经网络模块的链式的形式。在标准的 RNN 中,这个重复的模块只有一个非常简单的结构,例如一个 tanh 层。
LSTM 的核心思想
LSTM 的关键就是细胞状态,水平线在图上方贯穿运行。细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面流传保持不变会很容易。
逐步理解 LSTM
在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为 忘记门层 完成。该门会读取 h t − 1 h_{t−1} ht−1和 x t x_t xt,输出一个在 0 到 1 之间的数值给每个在细胞状态 C t − 1 C_{t−1} Ct−1中的数字。1 表示“完全保留”,0 表示“完全舍弃”。
在我们 LSTM 中的第一步是决定我们会从细胞状态中丢弃什么信息。这个决定通过一个称为 忘记门(forget gate) 完成。
该门的输入分别为:
h
t
−
1
h_{t−1}
ht−1:表示上一个 time-step 的神经元的输出
x
t
x_t
xt:表示当前 time-step 的神经元的输入
该门的输出为
f
t
f_t
ft,并且计算公式为(其中
σ
\sigma
σ表示 sigmoid ):
f
t
=
σ
(
W
f
⋅
[
h
t
−
1
,
x
t
]
+
b
f
)
f_t=\sigma(W_f \cdot [h_{t−1},x_t]+b_f)
ft=σ(Wf⋅[ht−1,xt]+bf)
从
f
t
f_t
ft的计算公式可以看出,
f
t
f_t
ft中的值全部为 0 到 1 的值(表示遗忘程度),这些值会与上一个 time-step 的 cell 中的值进行逐元素相乘(element-wise)。
f
t
f_t
ft 中的值越趋近于 0 代表越想忘记,越趋近与 1 代表越想记住。
下一步是确定什么样的新信息被存放在细胞状态中。这里包含两个部分。第一, sigmoid 层称 “输入门层” 决定什么值我们将要更新,即更新门(update gate)。然后,一个 tanh 层创建一个新的候选值向量, C ~ t \widetilde{C}_t C t ,会被加入到状态中。
3.编程知识
对于 BasicLSTMCell 类,LSTM 网络单元的情况有些许不同,因 为LSTM 可以看做有两个隐含状态 h 层和 c 层,对应的隐含层就是一个 Tuple,每个都是 (batch_size, state_size) 的形状。下面介绍如何创建一个 LSTMCell:
#首先创建一个输入张量,batch_size,n_inputs自行指定
inputs = tf.placeholder(np.float32, [batch_size,n_inputs])
#接下来正式创建一个包含n_units个神经元的BasicLSTMCell实例
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(num_units=n_units)
# 通过zero_state得到一个全0的初始状态
h0 = lstm_cell.zero_state(batch_size=batch_size,dtype=np.float32)
#调用一次__call__()方法,得到输出和新的隐含状态
output, h1 = lstm_cell.__call__(inputs, h0)
print(h1.h) #打印新的h层
print(h1.c) #打印新的c层
4.编程要求
根据提示,在右侧编辑器的 begin-end 间补充代码,创建一个包含 a 个神经元,可以接受一个 shape=[ b , c ]
,类型为 float32 的张量作为输入的 BasicLSTMCell ,并打印一次输入后该 BasicRNNCell 的隐含状态的 h , c 层。
5.笔者答案
#-*- coding: utf-8 -*-
import tensorflow as tf
import numpy as np
#参数 a 是 BasicLSTMCell所含的神经元数, 参数 b 是 batch_size, 参数 c 是单个 input 的维数,shape = [ b , c ]
def creatLSTMCell(a,b,c):
# 请在此添加代码 完成本关任务
# ********** Begin *********#
#首先创建一个输入张量,batch_size,n_inputs自行指定
inputs=tf.placeholder(np.float32,[b,c])
#接下来正式创建一个包含n_units个神经元的BasicLSTMCell实例
lstm_cell=tf.nn.rnn_cell.BasicLSTMCell(num_units=a)
# 通过zero_state得到一个全0的初始状态
h0=lstm_cell.zero_state(batch_size=b,dtype=np.float32)
#调用一次__call__()方法,得到输出和新的隐含状态
output,h1=lstm_cell.__call__(inputs,h0)
print(h1.h) #打印新的h层
print(h1.c) #打印新的c层
# ********** End **********#
通过截图
总结
- 探幽入微LSTM