吴恩达深度学习专项课程的所有实验均采用iPython Notebooks实现,不熟悉的朋友可以提前使用一下Notebooks。本次实验中我们将使用NumPy一步步构建一个朴素RNN网络和LSTM网络。
目录
4.LSTM(Long Short-Term Memory)网络
1.实验综述
2.导入必要的包
import numpy as np
#rnn_utils.py中定义了 本次试验需要的辅助函数
from rnn_utils import *
3.朴素(基础)RNN单元的前行传播
- 朴素RNN单元
# GRADED FUNCTION: rnn_cell_forward
def rnn_cell_forward(xt, a_prev, parameters):
"""
实现 Figure(2)中描述的在一个时间步骤上朴素RNN单元的计算过程。
Arguments:
xt -- 在时间步骤t的输入, 维度 (n_x, m),同时处理m个样本,每个样本在一个时间步骤的输入是一个向量(n_x,1).
a_prev -- 第"t-1"个时间步骤输出的隐藏状态, 维度 (n_a, m)
parameters -- Python字典包含:
Wax -- 与输入相乘的权重矩阵, 维度 (n_a, n_x)
Waa -- 与之前隐藏状态相乘的权重矩阵, 维度 (n_a, n_a)
Wya -- 与当前隐藏状态相乘用于产生输出的权重矩阵, 维度 (n_y, n_a)
ba -- 计算当前隐藏状态的偏置参数 维度 (n_a, 1)
by -- 计算当前输出的偏置参数 维度 (n_y, 1)
Returns:
a_next -- 当前的隐藏状态 (n_a, m)
yt_pred -- 当前的输出 (n_y, m)
cache -- 元组形式包括(a_next, a_prev, xt, parameters),用于与反向传播共享参数
"""
# 取出参数
Wax = parameters["Wax"]
Waa = parameters["Waa"]
Wya = parameters["Wya"]
ba = parameters["ba"]
by = parameters["by"]
#计算当前时间步骤的隐藏状态
a_next = np.tanh(Wax.dot(xt) + Waa.dot(a_prev) + ba)
# 计算当前时间步骤的输出
yt_pred = softmax(Wya.dot(a_next) + by)
#存储重要参数 与反向传播共享
cache = (a_next, a_prev, xt, parameters)
return a_next, yt_pred, cache
- RNN前行传播
# GRADED FUNCTION: rnn_forward
def rnn_forward(x, a0, parameters):
"""
实现 Figure (3)描述的RNN(朴素单元)的前向传播.
Arguments:
x -- 所有时间步骤的输入数据, 维度 (n_x, m, T_x) m个样本(序列)同时处理,每个样本(序列)有Tx个时间步骤(每个样本(序列)的长度相同)
每个样本在一个时间步骤上输入的是一个(n_x,1)向量.
实际应用中为了能够向量化处理,会将m个样本/序列统一为一个固定的长度,长序列截断,短序列填充。或者这个固定长度直接
设置为最长序列的长度,短序列都进行填充以达到这个长度。
a0 -- m个样本(序列)的初始隐藏状态 (n_a, m)
parameters -- Python字典包含:
Wax -- 与输入相乘的权重矩阵, 维度 (n_a, n_x)
Waa -- 与之前隐藏状态相乘的权重矩阵, 维度 (n_a, n_a)
Wya -- 与当前隐藏状态相乘用于产生输出的权重矩阵, 维度 (n_y, n_a)
ba -- 计算当前隐藏状态的偏置参数 维度 (n_a, 1)
by -- 计算当前输出的偏置参数 维度 (n_y, 1)
Returns:
a -- 所有时间步骤上m个样本(序列)的隐藏状态, 维度 (n_a, m, T_x)
y_pred -- 所有时间步骤上m个样本(序列)的预测输出 (n_y, m, T_x)
caches -- 元组列表 包含(list of caches, x) 与反向传播共享参数
"""
# 存储所有的cache
caches = []
# 得到输入x和参数Wya的形状
n_x, m, T_x = x.shape
n_y, n_a = parameters["Wya"].shape
# 用0初始化 a和y_pred
a = np.zeros((n_a,m,T_x))
y_pred = np.zeros((n_y,m,T_x))
#初始化a_next
a_next = a0
#遍历m个样本/序列的每个时间步骤
for t in range(T_x):
# 更新 ”下一个" 隐藏状态, 计算当前时间步骤上的预测输出, 得到cache
a_next, yt_pred, cache = rnn_cell_forward(x[:,:,t],a_next,parameters)
#保存当前时间步骤计算的隐藏状态 即"下一个"隐藏状态
a[:,:,t] = a_next
#保存当前时间步骤计算的预测输出
y_pred[:,:,t] = yt_pred
caches.append(cache)
caches = (caches, x)
return a, y_pred, caches