深度学习|一文搞懂循环神经网络(RNN)
RNN与传统神经网络 循环神经网络(RNN)是专门处理序列数据的神经网络。
传统的神经网络模型(左图),输入层(input layer)到隐藏层(hidden layer),隐藏层再到输出层(output layer),层与层之间是全连接的,但是隐藏层节点之间是无连接的。
循环神经网络(右图),隐藏层节点之间是有连接的。
文章图片
RNN的基本结构
文章图片
其中,右图圆形的箭头表示隐藏层的自连接。
在RNN中,每一层都共享参数U、V、W,降低了网络中需要学习的参数,提高学习效率。
输入单元(input units)记为:
文章图片
隐藏单元(hidden units)记为:
文章图片
输出单元(output units)记为:
文章图片
RNN的计算过程
文章图片
输入层:X t {X}_{t} Xt?表示时刻t的输入。
隐藏层:s t = f ( U x t ? + ? W s t ? 1 ) {s}_{t}=f(U{x}_{t}\, +\, W{s}_{t-1}) st?=f(Uxt?+Wst?1?) ,f是非线性激活函数,比如tanh。
输出层: o t = s o f t m a x ( ? V s t ) {o}_{t}=softmax(\, V{s}_{t}) ot?=softmax(Vst?)
其中tanh为双曲正切,公式为:
【深度学习|一文搞懂循环神经网络(RNN)】
文章图片
其曲线图如下所示:
文章图片
softmax函数是归一化的指数函数,使每个元素的范围都在0到1之间 ,并且所有元素的和为1。其公式为:
文章图片
z i {z}_{i} zi? —— 第i个节点的输出值
C —— 输出节点的个数,即分类的类别个数。
Python案例 本案例参考《Python深度学习》温度预测问题:数据使用德国耶拿的马克思? 普朗克生物地球化学研究所的气象站记录,天气时间序列数据集 jena_climate_2009_2016。
在命令行输入如下命令下载数据:
wget https://s3.amazonaws.com/keras-datasets/jena_climate_2009_2016.csv.zip
若wget命令无法使用,可以去wget官网下载一个。
https://eternallybored.org/misc/wget/
选择32位/64位,下载ZIP/EXE,将下载下来的EXE文件放到C:\Windows\System32
即可。
先来查看数据信息,这个数据集中,每10分钟记录14个不同的量(气温、气压、湿度、风向等),其中气温T(degC)数据服从正态分布——
文章图片
我们基于这个数据集来构建模型,输入最近几天的数据点,预测24小时之后的气温。
python代码:
import os
data_dir = 'E:\Tensorflow\code\data\jena_climate_2009_2016\jena_climate_2009_2016.csv'
file = open(data_dir) #打开文件,创建file对象,相关方法才可调用它进行读写
next(file) #返回文件的第二行,由于第一行是表头,从第二行开始是数据
data = https://www.it610.com/article/file.read()#逐字节(字符)读取文件中的内容
file.close()#关闭已打开文件的import numpy as np
lines = data.split('\n')#指定"\n"分隔符对字符串进行切片
#lines = lines[1:]
print(len(lines)) #420451
for i, line in enumerate(lines): #enumerate是枚举, i:0~len(lines)-1line:每行元素
values = [float(x) for x in line.split(',')[1:]]#每个元素值从String转为float
float_data[i, :] = values#每行数据存入float_datafrom matplotlib import pyplot as plt
temp = float_data[:,1]#温度(摄氏度)
plt.plot(range(len(temp)),temp)#两个参数分别是x轴数据和y轴数据
输出:
文章图片
x轴为0~420450 ,y轴为对应时刻的温度。
查看一天、一周、一个月(30天)、一年温度数据分布:
def show(daynum,index):
plt.figure(figsize=(10,10))
plt.subplot(410 + index + 1)
plt.plot(range(daynum*144), temp[:daynum*144])
title = str(daynum)+"day"
plt.title(title)
plt.showfor index,daynum in enumerate([1,7,30,365]): #一天、一周、一个月(30天)、一年
show(daynum,index)
输出:
文章图片
从结果可以看出,温度数据一天、一周数据较为分散,一个月以上的温度数据开始出现周期性。若推测未来几天的温度,可能会出现较大误差。
接下来对数据进行标准化处理,这里使用z-score标准化(标准差标准化法),该方法通常在最大值和最小值未知,或者有超出取值范围的离群数值的情况使用。
它基于原始数据的均值和标准差进行标准化,计算公式为新数据 = (原始数据 - 均值)/ 标准差。
其中,axis=0 表示纵轴平均,输出的是格式(1,x)的格式,axis=1表示横轴的平均,输出的是(x,1)的格式。
mean = float_data[:200000].mean(axis=0)#使用前200000个时间步作为训练数据
float_data -= mean
std = float_data[:200000].std(axis=0)
float_data /= std
构造generator函数,它是生成时间序列样本及其目标的生成器。它生成了一个元组(samples,targets),其中samples是输入数据的一个批量,targets是对应目标温度数组。
#data;
标准化后的浮点数数据组成的原始数组
#lookback:时间步数量=720每一个时间步是10分钟 给定过去5天内的观测数据
#delay:目标是未来24小时之后的数据=144
#min_index和max_index:data数组中的索引,用于界定需要抽取的时间步
#shuffle:False按顺序抽取样本True打乱样本
#batch_size:每个批量的样本数
#step:数据采样的周期(时间步)=6,每小时抽取一个数据点
def generator(data, lookback, delay, min_index, max_index,shuffle=False, batch_size=128, step=6):
if max_index is None:
max_index = len(data) - delay - 1
i = min_index + lookback
while 1:
if shuffle:
rows = np.random.randint(
min_index + lookback, max_index, size=batch_size)
else:
if i + batch_size >= max_index:
i = min_index + lookback
rows = np.arange(i, min(i + batch_size, max_index))
i += len(rows)
samples = np.zeros((len(rows),
lookback // step,
data.shape[-1]))
targets = np.zeros((len(rows),))
for j, row in enumerate(rows):
indices = range(rows[j] - lookback, rows[j], step)
samples[j] = data[indices]
targets[j] = data[rows[j] + delay][1]
yield samples, targets#yield类似return,带yield的函数是一个生成器而不是一个函数
使用generator函数来实例化三个生成器,分别用于训练、验证和测试,每个生成器分别读取原始数据不同的时间段。
lookback = 1440
step = 6
delay = 144
batch_size = 128
train_gen = generator(float_data,#训练集
lookback=lookback,
delay=delay,
min_index=0,
max_index=200000,
shuffle=True,
step=step,
batch_size=batch_size)
val_gen = generator(float_data,#验证集
lookback=lookback,
delay=delay,
min_index=200001,
max_index=300000,
step=step,
batch_size=batch_size)
test_gen = generator(float_data,#测试集
lookback=lookback,
delay=delay,
min_index=300001,
max_index=None,
step=step,
batch_size=batch_size)
val_steps = (300000 - 200001 - lookback) // batch_size
test_steps = (len(float_data) - 300001 - lookback)
预测24小时后的温度等于现在的温度,使用平均绝对误差(MAE)指标来评估这种方法。
def evaluate_naive_method():
batch_maes = []
for step in range(val_steps):
samples, targets = next(val_gen)
preds = samples[:, -1, 1]
mae = np.mean(np.abs(preds - targets))
batch_maes.append(mae)
print(np.mean(batch_maes))
evaluate_naive_method()
得到的MAE为0.2897,将平均绝对误差转化为摄氏度。0.2897×8.4804=2.45677188摄氏度,这个误差比较大。
应用 1.自动生成莎士比亚风格的句子
Tensorflow的官方教程里就有提到:
https://tensorflow.google.cn/tutorials/text/text_generation?hl=zh-cn
2.自动生成中文古诗
3.预测股票价格
4.语音识别
5.图像生成
…
推荐阅读
- 由浅入深理解AOP
- 继续努力,自主学习家庭Day135(20181015)
- python学习之|python学习之 实现QQ自动发送消息
- 一起来学习C语言的字符串转换函数
- 定制一套英文学习方案
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)
- 《深度倾听》第5天──「RIA学习力」便签输出第16期
- 如何更好的去学习
- 【韩语学习】(韩语随堂笔记整理)
- 焦点学习田源分享第267天《来访》