用纯Python实现循环神经网络RNN向前传播过程(吴恩达DeepLearning.ai作业)
Google TensorFlow程序员点赞的文章!
前言
目录:
- 向量表示以及它的维度
- rnn cell
- rnn 向前传播
重点关注:
- 如何把数据向量化的,它们的维度是怎么来的
- 一共其实就是两步: 单个单元的rnn计算,拉通来的rnn计算
在看本文前,可以先看看这篇文章回忆一下:
吴恩达deepLearning.ai循环神经网络RNN学习笔记(理论篇)
我们将实现以下结构的RNN,在这个例子中 Tx = Ty。
向量表示以及它的维度
Input with nx number of units
对单个输入样本,x(i) 是一维输入向量。
用语言来举个例子,将具有5k个单词词汇量的语言用one-hot编码成具有5k个单位的向量,所以 x(i) 的维度是(5000,)。
我们将用符号 nx 表示单个训练样本的单位数。
Batches of size m
如果我们取小批量(mini-batches),每个批次有20个训练样本。
为了受益于向量化,我们将20个样本 x(i) 变成一个2维数组(矩阵)。
比如一个维度是(5000,20)的向量。
我们用m来表示训练样本的数量。
所以小批量训练数据的维度是 (nx, m)。
Time steps of size Tx
循环神经网络有多个时间步骤,我们用t来表示。
我们将看到训练样本 x(i) 将经历多个时间步骤 Tx, 比如如果有10个时间步骤,那么 Tx = 10。
3D Tensor of shape (nx, m, Tx)
输入x就是用维度是 (nx, m, Tx) 的三维张量来表示。
Taking a 2D slice for each time step:
每一个时间步骤,我们用小批量训练样本(不是单个的训练样本)。
所以针对每个时间步骤t,我们用维度是 (nx, m)的2维切片。
我们把它表示成xt。
隐藏状态a的维度
a的定义: 从一个时间步骤到另一个时间步骤的激活值 at, 我们把它叫做隐藏状态。
同输入张量 x 一样,对于单个训练样本的隐藏状态,它的向量长度是na。
如果我们是包含了m个训练样本的小批量数据,那么小批量维度是 (na, m)。
如果我们把时间步加进去,那么隐藏状态的维度就是 (na, m, Tx)。
我们将用索引t来遍历时间步,每次操作是从3维张量切片成的2维向量。
我们用at来表示2维的切片,它的维度是 (na, m)。
预测值y^的维度
同输入x和隐藏状态一样,y^是一个维度是 (ny, m, Ty) 的3维张量。
ny: 代表预测值的单位数。
m: 小批次训练的样本数量。
Ty: 预测的时间数。
比如单个时间步 t,2维的切片 y^ 的维度是 (ny, m)。
RNN cell
我们的第一个任务就是执行单个时间步骤的计算,计算如下图。
输入是a^<t-1>, xt,输出是at, yt^。以下的代码其实就是把上面的公式代码化,总的步骤分成4步:
取出参数。
计算at。
计算yt^。
返回输出的at, yt^,还要存储一些值缓存起来。
import numpy as np
def rnn_cell_forward(xt, a_prev, parameters):
"""
Implements a single forward step of the RNN-cell as described in Figure (2)
Arguments:
xt -- your input data at timestep "t", numpy array of shape (n_x, m).
a_prev -- Hidden state at timestep "t-1", numpy array of shape (n_a, m)
parameters -- python dictionary containing:
Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x) Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
ba -- Bias, numpy array of shape (n_a, 1)
by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
Returns:
a_next -- next hidden state, of shape (n_a, m)
yt_pred -- prediction at timestep "t", numpy array of shape (n_y, m)
cache -- tuple of values needed for the backward pass, contains (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(np.dot(Waa, a_prev) + np.dot(Wax, xt) + ba)
# 计算当前cell的输出
yt_pred = softmax(np.dot(Wya, a_next) + by) # 用于向后传播的缓存值
cache = (a_next, a_prev, xt, parameters)
return a_next, yt_pred, cache
RNN向前传播
一个循环神经网络就是不断的重复你上面创建的rnn 单元。
如果你的输入数据序列是10个时间步,那么你就要重复你的rnn cell 10次。
在每个时间步中,每个单元将用2个输入:
a<t-1>: 前一个单元的隐藏状态。
xt: 当前时间步的输入数据。
每个时间步有两个输出:
一个隐藏状态at
一个测值y^⟨t⟩
权重和偏差 (Waa,ba,Wax,bx) 将在每个时间步中循环使用,它们保存在"parameters"的变量中。
def rnn_forward(x, a0, parameters):
"""
Implement the forward propagation of the recurrent neural network described in Figure (3).
Arguments:
x -- Input data for every time-step, of shape (n_x, m, T_x).
a0 -- Initial hidden state, of shape (n_a, m)
parameters -- python dictionary containing:
Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x)
Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
ba -- Bias numpy array of shape (n_a, 1)
by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
Returns:
a -- Hidden states for every time-step, numpy array of shape (n_a, m, T_x)
y_pred -- Predictions for every time-step, numpy array of shape (n_y, m, T_x)
caches -- tuple of values needed for the backward pass, contains (list of caches, x)
"""
# 用于存储所有cache的列表,初始化它
caches = []
# 取一些纬度值,用于后面初始化变量
n_x, m, T_x = x.shape
n_y, n_a = parameters["Wya"].shape
# 初始化 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
# loop over all time-steps of the input 'x'
for t in range(T_x):
# Update next hidden state, compute the prediction, get the cache
xt = x[:,:,t] # 通过切片的方式从输入变量x中取出当前t时间步的输入xt
a_next, yt_pred, cache = rnn_cell_forward(xt, a_next, parameters)
# 保存当前单元计算的a_next值
a[:,:,t] = a_next
# 保存当前单元的预测值y
y_pred[:,:,t] = yt_pred
# 添加每个单元的缓存值
caches.append(cache)
# store values needed for backward propagation in cache
caches = (caches, x)
return a, y_pred, caches
恭喜你(*^▽^*),到这里你已经能够从0到1的构建循环神经网络的向前传播过程。
在现代深度学习框架中,您仅需实现前向传递,而框架将处理后向传递,因此大多数深度学习工程师无需理会后向传递的细节。我就不写向后传播了。
用纯Python实现循环神经网络RNN向前传播过程(吴恩达DeepLearning.ai作业)的更多相关文章
- 吴恩达deepLearning.ai循环神经网络RNN学习笔记_看图就懂了!!!(理论篇)
前言 目录: RNN提出的背景 - 一个问题 - 为什么不用标准神经网络 - RNN模型怎么解决这个问题 - RNN模型适用的数据特征 - RNN几种类型 RNN模型结构 - RNN block - ...
- 吴恩达deepLearning.ai循环神经网络RNN学习笔记_没有复杂数学公式,看图就懂了!!!(理论篇)
本篇文章被Google中国社区组织人转发,评价: 条理清晰,写的很详细! 被阿里算法工程师点在看! 所以很值得一看! 前言 目录: RNN提出的背景 - 一个问题 - 为什么不用标准神经网络 - RN ...
- 一文看懂神经网络初始化!吴恩达Deeplearning.ai最新干货
[导读]神经网络的初始化是训练流程的重要基础环节,会对模型的性能.收敛性.收敛速度等产生重要的影响.本文是deeplearning.ai的一篇技术博客,文章指出,对初始化值的大小选取不当, 可能造成 ...
- 吴恩达deeplearning之CNN—卷积神经网络
https://blog.csdn.net/ice_actor/article/details/78648780 个人理解: 卷积计算的过程其实是将原始的全连接换成了卷积全连接,每个kernel为对应 ...
- 循环神经网络(RNN, Recurrent Neural Networks)介绍(转载)
循环神经网络(RNN, Recurrent Neural Networks)介绍 这篇文章很多内容是参考:http://www.wildml.com/2015/09/recurrent-neur ...
- 循环神经网络(RNN, Recurrent Neural Networks)介绍
原文地址: http://blog.csdn.net/heyongluoyao8/article/details/48636251# 循环神经网络(RNN, Recurrent Neural Netw ...
- 通过keras例子理解LSTM 循环神经网络(RNN)
博文的翻译和实践: Understanding Stateful LSTM Recurrent Neural Networks in Python with Keras 正文 一个强大而流行的循环神经 ...
- 『cs231n』循环神经网络RNN
循环神经网络 循环神经网络介绍摘抄自莫凡博士的教程 序列数据 我们想象现在有一组序列数据 data 0,1,2,3. 在当预测 result0 的时候,我们基于的是 data0, 同样在预测其他数据的 ...
- 循环神经网络RNN及LSTM
一.循环神经网络RNN RNN综述 https://juejin.im/entry/5b97e36cf265da0aa81be239 RNN中为什么要采用tanh而不是ReLu作为激活函数? htt ...
随机推荐
- Oracle 11g 静默安装过程(centos7)
开启机器,本次实例分配的ip是:192.168.3.197(Xshell ssh连接) 2 安装unzip 工具.vim编辑器(个人习惯,vi也可以) 3 在/etc/hosts文件中添加本机IP跟主 ...
- 详解Javascript中的原型与原型链
目录 知识点 参考资料 结束语 知识点 面向对象编程 我们熟悉的Java和C#里,面向对象的两个基本概念是类class和实例instance,而ES6以前的Javascript并没有设计class. ...
- java枚举与常量类的区别
1)枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举的常量名.(数据库中好像也有枚举类型,不过也没用过) 2) switch语句支持枚举型,当switch使用int.Str ...
- java String、StringBuilder
Java中的String和StringBuilder类: 1.String对象是不可变的.每一个看起来修改了String值的方法,实际上都是创建了全新的String对象.代码示例如下: String ...
- Centos7上查看ext4文件系统的实际创建时间
前提:今日查看nginx日志时发现有报错,说是一些js,css文件找不到,于是想到去实际路径下查看文件是否确实不存在.结果出现下图中报错: 经过别人提醒查看文件的时间,于是看了一下登上服务器是9:52 ...
- SpringBoot 处理 POST Json 传参枚举
在 Spring 框架中对枚举类型的序列化/反序列化是有限制的. 假设如下面这样在某些情况下就不能正常工作: 123456789 public enum PayChannelEnum implemen ...
- 一致性 Hash 算法分析
当我们在做数据库分库分表或者是分布式缓存时,不可避免的都会遇到一个问题: 如何将数据均匀的分散到各个节点中,并且尽量的在加减节点时能使受影响的数据最少. Hash 取模 随机放置就不说了,会带来很多问 ...
- PHP实现读取一个1G的文件大小
需求如下: 现有一个1G左右的日志文件,大约有500多万行, 用php返回最后几行的内容. 1. 直接采用file函数来操作 or file_get_content() 肯定报内存溢出注: 由于 fi ...
- centos7下安装python3.7.2详细教程
1)下载安装python3.7.2 1:yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel r ...
- py函数式编程
函数式编程把计算视为函数而非指令,纯函数式编程不需要变量,没有副作用,测试简单,python支持的函数式编程不是纯函数式编程,允许有变量存在,支持高阶函数,支持闭包,有限度的支持匿名函数 变量可以指向 ...