- 循环神经网络简介
循环神经网络(Rerrent Neural Network, RNN )出现于20世纪80年代,其雏形见于美国物理学家 J.J.Hopfield 于 1982 年提出的可用作联想存储器的互联网络一Hopfield 神经网络模型。卷积神经网络擅长处理大小可变的图像,而循环神经网络则对可变长度的序列数据有较强的处理能力。
随着循环神经网络在结构方面的进步和 GPU 硬件性能的迅猛发展而出现的深度学习训练的效率有所突破,RNN变得越来越流行。 RNN对具有时间序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息。研究人员充分利用了RNN的这种能力,使深度学习模型在解决语音识别、语言模型、机器翻译以及时序分析等自然语言处理(NLP)领域的问题时有所突破。
全连神经网络或卷积神经网络模型中,信息从网络的输 入层到隐藏层再到输出层,因为网络只存在层与层之间的全连接或部分连 接,而每层中的节点之间没有连接,所以信息不会在同层之间流动。 这样的网络(指全连或卷积〉因为在每一个时间点都有一个单独的参 数,导致了不能在时间上共享不同序列长度或序列不同位置的统计强度, 所以无法对训练时没有见过的序列长度进行泛化。在模型的不同部分共享 参数解决了这个问题,并使得模型能够扩展到对不同形式的样本(这里指不同长度的样本)进行泛化。
循环神经网络更加注重“ 时 刻” 的 概念。
对于循环神经网络的优化 也可以使 用梯度下降的方法,但是当循环体过长(循环体被无限次执行)时,会发生梯度消失(在多数情况下是梯度消失,极少情况下会出现梯度爆炸) 的问题,所以目前循环神经网络无法做到
真正的无限循环。
循环神经网络在每一个时刻会有一个输入xt, H根据xt和上一个H的结果提供一个输出ot。
- 不同设计模式
循环神经网络要求每一个时刻都有一个输入,但是不一定每个时刻都需要有输出。这涉及了循环神经网络的不同设计模式。
最简单循环体结构的循环神经网络如下:
一个循环神经网络前向传播的具体计算过程(不包括 softmax 部分):
使用 numpy 实现上述简单循环神经网络前向传播的计算过程。
import numpy as np
# 定义相关参数,init_state是输入到t1的t0时刻输出的状态
x = [0.8,0.1]
init_state = [0.3, 0.6]
W = np.asarray([[0.2, 0.4], [0.7, 0.3]])
U = np.asarray([0.8, 0.1])
b_h = np.asarray([0.2, 0.1])
V = np.asarray([[0.5], [0.5]])
b_o = 0.1
#执行两轮循环,模拟前向传播过程
for i in range(len(x)):
#numpy的dot()函数用于矩阵相乘,函数原型为dot(a, b, out)
before_activation = np.dot(init_state, W) + x[i] * U + b_h
#numpy也提供了tanh()函数实现双曲正切函数的计算
state = np.tanh(before_activation)
#本时刻的状态作为下一时刻的初始状态
init_state=state
#计算本时刻的输出
final_output = np.dot(state, V) + b_o
# 打印t1和t2时刻的状态和输出信息
print("t%s state: %s" %(i+1,state))
print("t%s output: %s\n" %(i+1,final_output))
打印结果如下: