带你一步步讲解RNN

最近用到了RNN来做预测,在这里给大家讲解下为什么要使用RNN:

前馈神经网络

前馈神经网络是一种最简单的神经网络,是目前应用最广泛、发展最迅速的人工神经网络之一。
各神经元分层排列,第一层是输入层;然后是隐藏层,其中隐藏层可能会有多层;最后一层为输出层。
层与层之间是全连接的,每层的节点之间是无链接的。
每层的神经元只与前一层的神经元相连,只接受前一层的输出,并传给下一层,各层间没有反馈。
每一层的神经元之间都是相互独立的,如输入层的神经元是彼此独立的。
常见的前馈神经网络有单层前馈神经网络、多层前馈神经网络(DNN、多层感知器)、CNN等。

前馈神经网络的缺陷

前馈神经网络只能单独处理一个个的输入,前一个输入与后一个输入之间没有任何关系,如果碰到需要处理输入之间关系的数据,它们将无法正确的预测输入值,比如下列样例:

1.球的轨迹(移动过程点的集合)
2.现有一个球在平面上移动,我们想要预测球的移动方向。
3.如果使用前馈网络,那么我们把点集输入模型,但是由于它只能处理单独一个个的输入,那么我们就无法根据上一个的信息来预测下一个点的方向(即球的移动方向)。
4.只能根据被动的根据所有的输入(点)的来预测方向,不清楚点位于第几步,就无法正确的预测方向。如下图:我们知道球的轨迹,却不清楚此时球位于哪一点的位置。
5.自然语言处理
6. 如果我们输入一句话我吃苹果,想要预测它的语义,那么它会被拆成一个个词输入模型

在这里插入图片描述

RNN的定义

针对上述需要需要按照顺序处理的数据,在原有全连接神经网络的基础上添加了一个时间轴的概念,即诞生了循环神经网络(RNN。
循环神经网络(RNN)是一类用于处理序列数据的神经网络。RNN拥有记忆模块,可以获取以及计算过的信息,记住执行的顺序。即使是同样的输入,如果输入的顺序不同也会产生不同的输出。

RNN的基本结构

神经网络的结构分为输入层、隐藏层、输出层。输入与输出层是处理数据的输入输出的;而隐藏层则对数据进行计算、预测处理。前馈网络与循环网络(RNN)的主要区别就是在隐藏层。
在这里插入图片描述

最简前馈神经网络

前馈网络的隐藏层,如果只有一个神经元,则直接处理;如果有多个神经元,每个神经元都单独运行,互不相关,没有任何顺序、引用、传值的关系。
在这里插入图片描述

RNN的结构

而RNN的结构则是在前馈网络隐藏层上添加了时间轴的概念,让每一个单元都按照输入的顺序进行处理,上一个处理的输出作为下一个处理的输入与当前的输入一起计算,综合前几个输入的计算结果与当前输入一起进行预测。
在这里插入图片描述

RNN的种类(结构的四种形式)

1 to N

这种形式一是只在序列开始把输入信息输入模型计算(左);二是把输入信息作为每个阶段的输入(右),这种结构可以处理如: 输入图像的特征,输出y的序列是一段句子或者从别的类别生成语音;输入一个类别,输出一段描述文字这类问题。
在这里插入图片描述

N to 1

输入的是一个序列,输出的是一个单独的值。这种结构常用于处理分类问题,如:输入一段文字判断类别、输入句子判断感情倾向、输入图片判断类别。
在这里插入图片描述

N to N

输入和输出序列是等长的。这种可以作为简单的Char RNN可以用来生成文章,诗歌,甚至是代码。
在这里插入图片描述

N to M

这种结构又称Encoder-Decoder、Seq2Seq模型,它会将输入数据编码成一个上下文向量c,之后通过c输出预测序列。它广泛应用于机器翻译、文本摘要、阅读理解、对话生成等领域。
在这里插入图片描述

RNN的实现

准备数据集,提取特征信息最为输入数据

实现RNN的第一步需要准备数据集,下列是对图像进行分类的数据处理格式 。

(x_train, y_train) = dealImage()
# 处理数据格式,将图片数据x转化到-1到1之间(除以像素点最大值255),提高精确度
x_train = x_train.reshape(x_train.shape[0], 56, -1).astype('float') / 255.0
# 转换labels为one hot格式
y_train = np_utils.to_categorical(y_train, num_classes=num_classes)
# 同样的方法加载测试数据
(x_test, y_test) = dealTestImage()
复制代码
# deal.py 处理图片分类时的数据预处理,读取图片数据和对应类别
def dealImage():
 result = [(src, label)....] # 路径和类别的对应关系可以保存到本地文件或者数据库中,需要使用的时候在读取
 images = []
 labels = []
 for row in result:
 imsrc = cv2.imread(row[0], 0)
 im = cv2.resize(imsrc, (56, 56), interpolation=cv2.INTER_AREA) # 转换数据格式(按自己需要的格式转换) 
 imgData = np.array(im) # numpy array化
 images.append(imgData)
 labels.append(row[1])
 images = np.array(images)
 labels = np.array(labels)
 return (images, labels)
搭建神经网络结构(从输入到输出)

根据前向传播算法的理论,搭建RNN神经网络,选择恰当的神经网络的层数、神经元数目

创建模型
创建模型 keras模型分为顺序模型和函数式API模型
顺序模型是多个网络层的线性堆叠,可以帮助我们快速创建一些简单的模型,是我们最常使用的模型
函数式API模型是用来定义复杂模型(多输出模型、有向无环图、具有共享层的模型)的方法
 # 创建模型,当前模型比较简单无复杂的结构,使用顺序模型即可
model = Sequential()
cell_size = 300
搭建神经网络
如果当前层的输入维度与前一层的输出维度一致,可以不写输入维度
(如果创建多层)每层SimpleRNN之间必须设置return_sequences=True(默认是False)
激活函数也是神经网络中一个很重的部分。每一层的网络输出都要经过激活函数。
常用激活函数有:softmax、Softplus、Relu、tanh、sigmod、hard_sigmoid、linear
经过调试,当前模型的SimpleRNN适合使用tanh函数,输出Dense层适合采用softmax进行分类
# 循环神经网络
model.add(SimpleRNN(
 units=cell_size, # 输出数据的维度(当前层神经元的数目)
 activation='tanh', # 激活函数,默认即tanh
 return_sequences=True,
 input_shape=(56, 56) # 输入数据的维度(shape)
))
model.add(SimpleRNN(units=cell_size, return_sequences=True))
model.add(SimpleRNN(units=cell_size, return_sequences=True))
# 每层SimpleRNN之间必须设置return_sequences=True(默认是False)
# return_sequences 是返回输出序列的最后一个输出(False),还是返回全部序列(True)
# return_sequences=True 表示我们需要完整的编码序列,而不仅仅是最终总结状态
# return_sequences=True 返回的是个多维数组,如果下一层无法接收该种多维数组,则层需要设置为return_sequences=True或者不设置取默认值
model.add(SimpleRNN(units=cell_size))
# 添加全连接层作为输出层 
model.add(Dense(num_classes, activation='softmax'))

大量特征数据输入神经网络,优化神经网络参数,训练模型

使用反向传播算法迭代训练模型,根据每次训练结果优化参数后再次训练直到得到能尽可能好的预测结果的模型。

反向传播算法tensorflow与keras都有封装,直接调用方法即可

第一步需要定义模型的优化器、损失函数
机器学习分为构建模型、训练模型两部分。优化器和损失函数是模型训练时两个最重要的参数
优化器是用来更新和计算影响模型训练和输出的参数,是模型的输出逼近或达到最优值,从而最小(大)化损失函数的值
优化器有:SGD、Adagrad、RMSprop、Adam
本例采用的是常用的Adam算法
损失函数是用来评估模型好坏程度的,即预测值与真实值的不一致程度
损失函数有mse、mae、mape、msle、hinge、categorical_crossentropy等等
本例采用适合分类的交叉熵categorical_crossentropy函数
# 初始化优化器
adam = Adam(lr=1e-4)
# 定义优化器,loss function,训练过程中计算准确率
model.compile(
 optimizer=adam, # 优化器
 loss='categorical_crossentropy', # 损失函数 mse 均方差 categorical_crossentropy 交叉熵(多分类)
 metrics=['accuracy'] # 训练和测试期间的模型评估标准
)
# 开始训练模型,调用model.fit()方法,方法采用时序后向传播算法训练模型
# 以给的数目的轮次训练模型,到第epochs轮结束训练,每轮多个批次,每批次大小batch_size
model.fit(x_train, y_train, batch_size=32, epochs=20)
# 预测模型的损失值和准确率
loss, accuracy = model.evaluate(x_test, y_test)
# 保存模型,以便使用时加载
model.save('myfile/rnn.hdf5')
复制代码

训练结果如图所示
在这里插入图片描述
使用模型预测和分类数据,加载已保存的模型,输入待预测的,输出最可能的结果 。

# 加载模型
model = load_model('myfile/rnn.hdf5')
# 使用模型预测结果
pred = model.predict(data) # data 是numpy的array格式
# 取出可能性最大的值作为预测结果
print([final.argmax() for final in pred])
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值