1. 循环核:参数时间共享,循环层提取时间信息。
- 前向传播时:记忆体内存储的状态信息 h t h_t ht,在每个时刻都被刷新,三个参数矩阵 W x h , W h h , W h y W_{xh}, W_{hh}, W_hy Wxh,Whh,Why自始至终都是固定不变的。
- 反向传播时:三个参数矩阵 W x h , W h h , W h y W_{xh}, W_{hh}, W_{hy} Wxh,Whh,Why被梯度下降法更新。
y
t
=
s
o
f
t
m
a
x
(
h
t
W
h
y
+
b
y
)
y_t=softmax(h_t W_{hy}+by)
yt=softmax(htWhy+by)
h
t
=
t
a
n
h
(
x
t
W
x
h
+
h
t
−
1
W
h
h
+
b
h
)
h_t=tanh(x_tW_{xh}+h_{t-1}W_{hh}+bh)
ht=tanh(xtWxh+ht−1Whh+bh)
2. 循环核按时间步展开
- 把循环核按时间步展开后看起来像一个前向传播的网络。
- 循环神经网络借助循环核提取时间特征后,送入全连接网络。
- 每个时刻根据当前的输入
x
t
x_t
xt和上一时刻的状态信息
h
t
−
1
h_{t-1}
ht−1
y t = s o f t m a x ( h t W h y + b y ) y_t=softmax(h_t W_{hy}+by) yt=softmax(htWhy+by)
h t = t a n h ( x t W x h + h t − 1 W h h + b h ) h_t=tanh(x_tW_{xh}+h_{t-1}W_{hh}+bh) ht=tanh(xtWxh+ht−1Whh+bh)
其实这和我们人类的预测是一致的,你脑中的记忆体每个时刻都根据当前的输入而更新,当前的预测推理是根据你以往的知识积累,用固化下来的参数矩阵进行的推理判断。循环神经网络借助循环核提取时间特征后,再把提取的信息送入全连接网络,实现连续数据的预测。 y t y_t yt是整个循环网络的末层,从公式来看,就是一个全连接网络,借助全连接网络实现连续数据的预测。
3. 循环计算层
- 循环计算层:向输出方向生长
- 每个循环核构成一层循环计算层,循环计算层的层数是向输出方法增长的。
- 下图的第一个网络是具有1个循环核,构成1层循环计算层。第二个有2个循环核,构成2层循环计算层。第三个有3个循环核,构成3层循环计算层。他们中的每个循环核中记忆体的个数是根据你的需求任意指定的。
- 当RNN有多个循环核时,第一个循环核的输入是 x t x_t xt,第二个循环核的输入是第一个循环核的输出 h t h_t ht,第三第四依次。
4. tensorflow描述循环计算层
tf.keras.layers.SimpleRNN(记忆体个数, activation='激活函数',
return_sequences=是否每个时刻输出ht到下一层)
activation='激活函数' # 不写,默认使用tanh
return_sequences=True # 各时间步输出ht
return_sequences=False # 仅最后时间步输出ht(默认)
例:SimpleRNN(3, return_sequences=True)
1) return_sequences = True: 循环核各时刻输出 h t h_t ht
- 循环核在每个时间步输出
h
t
h_t
ht,可以用下图表示。可看出在每个时间步循环核输出
h
t
h_t
ht。
2) return_sequences = False: 循环核仅在最后时刻输出 h t h_t ht
- 循环核在最后时间刻输出
h
t
h_t
ht,可以用下图表示。可看出中间的时间步循环核没有输出
h
t
h_t
ht,只有最后一个时间步循环核输出
h
t
h_t
ht。
3) API对送入循环层的数据维度要求
API对送入循环层的数据维度是有要求的,要求送入循环层的数据是3维的:[送入样本数,循环核时间展开步数,每个时间步输入特征个数]
5. 循环计算过程I
- 使用字母预测例子来体会循环网络的计算过程:输入一个字母预测下一个字母。例如输入a预测b,输入b预测c,输入c预测d,输入d预测e,输入e预测a。
- 由于神经网络的输入都是数字,使用我们需要把abcde转换成数字,最简单直接的方法是采用独热码(one-hot),如下表所示:
向量空间 | 字母 |
---|---|
10000 | a |
01000 | b |
00100 | c |
00010 | d |
00001 | e |
- 随机生成三个参数矩阵 W h , W h h , W h y W_{h}, W_{hh}, W_{hy} Wh,Whh,Why
W x h = [ 0.5 − 1.7 1.7 − 2.3 0.8 1.1 1.3 1.7 1.4 0.3 0.8 − 1.1 − 1.8 − 2.0 − 1.0 ] W h h = [ − 0.9 − 0.2 − 0.4 − 0.3 0.9 0.2 0.4 0.3 − 0.9 ] W h y = [ − 1.7 1.7 − 1.7 1.7 0.7 − 1.6 − 1.6 0.7 1.3 1.4 − 1.4 1.9 1.2 1.7 − 1.9 ] W_{xh}=\begin{bmatrix} 0.5&-1.7&1.7 \\ -2.3&0.8&1.1 \\ 1.3&1.7&1.4 \\ 0.3&0.8&-1.1 \\ -1.8&-2.0&-1.0\\ \end{bmatrix} \ \ W_{hh}=\begin{bmatrix} -0.9&-0.2&-0.4 \\ -0.3&0.9&0.2 \\ 0.4&0.3&-0.9\\ \end{bmatrix} \ \ W_{hy}=\begin{bmatrix} -1.7&1.7&-1.7&1.7&0.7 \\ -1.6&-1.6&0.7&1.3&1.4 \\ -1.4&1.9&1.2&1.7&-1.9\\ \end{bmatrix} Wxh=⎣⎢⎢⎢⎢⎡0.5−2.31.30.3−1.8−1.70.81.70.8−2.01.71.11.4−1.1−1.0⎦⎥⎥⎥⎥⎤ Whh=⎣⎡−0.9−0.30.4−0.20.90.3−0.40.2−0.9⎦⎤ Why=⎣⎡−1.7−1.6−1.41.7−1.61.9−1.70.71.21.71.31.70.71.4−1.9⎦⎤
-
选择记忆体个数为3,初始化为[0.0, 0.0, 0.0]。
-记忆体转态信息 h t = t a n h ( x t w x h + h t − 1 w h h + b h ) h_t=tanh(x_tw_{xh}+h_{t-1}w_{hh}+bh) ht=tanh(xtwxh+ht−1whh+bh)
-
记忆体状态信息更新(脑中的记忆因为当前输入的事物更新了):
-
输出 y t y_t yt是把提取到的时间信息通过全连接进行识别预测的过程,是整个网络的输出层,输出 y t y_t yt等于:
y t = s o f t m a x ( h t w h y + b y ) y_t=softmax(h_tw_{hy}+by) yt=softmax(htwhy+by) -
根据输出的 y t y_t yt可看出预测下一个字母是c的可能性最高是0.91。
6. 循环计算过程II
- 把时间核按时间步展开。
- 连续输入四个字母,预测下一个字母。讲解循环核按时间展开后,循环计算的过程。
- 仍然使用三个记忆体,初始时刻,记忆体内的记忆是0。使用一套训练好的参数矩阵来感受循环计算的前向传播过程。在这个过程中的每个时刻参数矩阵是固定的,记忆体会在每个时刻更新。
1)第一个时刻
- 输入字母b的独热码[0, 1, 0, 0, 0]
- 记忆体根据更新公式刷新为[-0.9, 0.2, 0.2]
2)第二个时刻
- 输入字母c的独热码[0, 0, 1, 0, 0]
- 记忆体根据更新公式刷新为[0.8, 1.0, 0.8]
3)第三个时刻
- 输入字母d的独热码[0, 0, 0, 1, 0]
- 记忆体根据更新公式刷新为[0.6, 0.5, -1.0]
4)第四个时刻
- 输入字母e的独热码[0, 0, 0, 0, 1]
- 记忆体根据更新公式刷新为[-1.0, -1.0, 0.8]
- 从输出的结果
y
t
y_t
yt看出,说明有71%的可能是字母a,模型不仅成功预测出了下一个字母是a。从神经网络输出的概率可以发现,因为输入序列的最后一个字母是e,模型认为下一个字母还是e的可能性最小,可能性最大的是a,其次是b, c, d。
7. Embedding编码
tf.keras.layers.Embedding(词汇表大小, 编码维度)
# 词汇表大小:指定编码一共要表示多少个单词
# 编码维度:指定用几个数字表示一个单词
# 对1-100进行编码,[4]编码为[0.25, 0.1, 0.11]
tf.keras.layers.Embedding(100, 3)
- 入Embedding时,x_train维度:[送入样本数,循环核时间展开步数]