简单RNN

递归神经网络(RNN)对于天然语言处理和其余序列任务很是有效,由于它们具备“记忆”功能。 它们能够一次读取一个输入x⟨t⟩

(如单词),而且经过隐藏层激活从一个时间步传递到下一个时间步来记住一些信息/上下文,这容许单向RNN从过去获取信息来处理后面的输入,双向RNN能够从过去和将来中获取上下文。网络

有些东西须要声明:
app

 

 

1 - 循环神经网络的前向传播
 咱们来看一下下面的循环神经网络的图,在这里使用的是Tx=Ty,咱们来实现它。

函数

 

咱们怎么才能实现它呢?有如下步骤:spa

实现RNN的一个时间步所须要计算的东西。
在Tx 时间步上实现一个循环,以便一次处理全部输入。

code

1.1 - RNN单元

 循环神经网络能够看做是单元的重复,首先要实现单个时间步的计算,下图描述了RNN单元的单个时间步的操做。blog

 

 1 def rnn_cell_forward(xt, a_prev, parameters):
 2     """
 3     根据图2实现RNN单元的单步前向传播
 4     
 5     参数:
 6         xt -- 时间步“t”输入的数据,维度为(n_x, m)
 7         a_prev -- 时间步“t - 1”的隐藏隐藏状态,维度为(n_a, m)
 8         parameters -- 字典,包含了如下内容:
 9                         Wax -- 矩阵,输入乘以权重,维度为(n_a, n_x)
10                         Waa -- 矩阵,隐藏状态乘以权重,维度为(n_a, n_a)
11                         Wya -- 矩阵,隐藏状态与输出相关的权重矩阵,维度为(n_y, n_a)
12                         ba  -- 偏置,维度为(n_a, 1)
13                         by  -- 偏置,隐藏状态与输出相关的偏置,维度为(n_y, 1)
14     
15     返回:
16         a_next -- 下一个隐藏状态,维度为(n_a, m)
17         yt_pred -- 在时间步“t”的预测,维度为(n_y, m)
18         cache -- 反向传播须要的元组,包含了(a_next, a_prev, xt, parameters)
19     """
20     
21     # 从“parameters”获取参数
22     Wax = parameters["Wax"]
23     Waa = parameters["Waa"]
24     Wya = parameters["Wya"]
25     ba = parameters["ba"]
26     by = parameters["by"]
27     
28     # 使用上面的公式计算下一个激活值
29     a_next = np.tanh(np.dot(Waa, a_prev) + np.dot(Wax, xt) + ba)
30     
31     # 使用上面的公式计算当前单元的输出
32     yt_pred = rnn_utils.softmax(np.dot(Wya, a_next) + by)
33     
34     # 保存反向传播须要的值
35     cache = (a_next, a_prev, xt, parameters)
36     
37     return a_next, yt_pred, cache

 

1.2 - RNN的前向传播

 能够看到的是RNN是刚刚构建的单元格的重复链接,若是输入的数据序列通过10个时间步,那么将复制RNN单元10次,每一个单元将前一个单元中的隐藏状态递归

(a⟨t−1⟩ a^{\langle t-1 \rangle}a ⟨t−1⟩)和当前时间步的输入数据(x⟨t⟩ x^{\langle t \rangle}x ⟨t⟩)做为输入。 它为此时间步输出隐藏状态(a⟨t⟩ a^{\langle t \rangle}a ⟨t⟩)和预测(y⟨t⟩ y^{\langle t \rangle}y ⟨t⟩)。
class

咱们要根据图3来实现前向传播的代码,它由如下几步构成:神经网络

建立0向量zeros(a),它将保存RNN计算的全部的隐藏状态。循环

使用“a0 a_0a
0

”初始化“next”隐藏状态。

循环全部时间步:

使用rnn_cell_forward函数来更新“next”隐藏状态与cache。

使用a来保存“next”隐藏状态(第t)个位置。

使用y来保存预测值。

把cache保存到“caches”列表中。

返回a,y与caches。

 1 def rnn_forward(x, a0, parameters):
 2     """
 3     根据图3来实现循环神经网络的前向传播
 4     
 5     参数:
 6         x -- 输入的所有数据,维度为(n_x, m, T_x)
 7         a0 -- 初始化隐藏状态,维度为 (n_a, m)
 8         parameters -- 字典,包含了如下内容:
 9                         Wax -- 矩阵,输入乘以权重,维度为(n_a, n_x)
10                         Waa -- 矩阵,隐藏状态乘以权重,维度为(n_a, n_a)
11                         Wya -- 矩阵,隐藏状态与输出相关的权重矩阵,维度为(n_y, n_a)
12                         ba  -- 偏置,维度为(n_a, 1)
13                         by  -- 偏置,隐藏状态与输出相关的偏置,维度为(n_y, 1)
14     
15     返回:
16         a -- 全部时间步的隐藏状态,维度为(n_a, m, T_x)
17         y_pred -- 全部时间步的预测,维度为(n_y, m, T_x)
18         caches -- 为反向传播的保存的元组,维度为(【列表类型】cache, x))
19     """
20     
21     # 初始化“caches”,它将以列表类型包含全部的cache
22     caches = []
23     
24     # 获取 x 与 Wya 的维度信息
25     n_x, m, T_x = x.shape
26     n_y, n_a = parameters["Wya"].shape
27     
28     # 使用0来初始化“a” 与“y”
29     a = np.zeros([n_a, m, T_x])
30     y_pred = np.zeros([n_y, m, T_x])
31     
32     # 初始化“next”
33     a_next = a0
34     
35     # 遍历全部时间步
36     for t in range(T_x):
37         ## 1.使用rnn_cell_forward函数来更新“next”隐藏状态与cache。
38         a_next, yt_pred, cache = rnn_cell_forward(x[:, :, t], a_next, parameters)
39         
40         ## 2.使用 a 来保存“next”隐藏状态(第 t )个位置。
41         a[:, :, t] = a_next
42         
43         ## 3.使用 y 来保存预测值。
44         y_pred[:, :, t] = yt_pred
45         
46         ## 4.把cache保存到“caches”列表中。
47         caches.append(cache)
48     
49     # 保存反向传播所须要的参数
50     caches = (caches, x)
51     
52     return a, y_pred, caches
相关文章
相关标签/搜索