赞
踩
这篇推文主要介绍基于Tensorflow库的RNN模型预测问题。文中首先对Tensorflow库进行简单的介绍,然后以美国二氧化碳数据集为例建立RNN模型进行预测,最后通过实验结果展示了模型的良好表现。
Tensorflow是使用较为广泛的一个深度学习框架,通常运用在图像识别、图片分类等领域,它是一个采用数据流图,用于数值计算的开源软件库。从命名来理解的话:Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算。
在TensorFlow中,数据不是以整数、浮点数或者字符串形式存在的,而是被封装在一个叫做Tensor的对象中。Tensor是张量的意思,张量包含了0到任意维度的量,其中,0维叫做常数,一维叫做向量,二维叫做矩阵,多维度的直接叫做张量。
TensorFlow中的数据流图如图所示。
首先我们要创建一个数据流图,然后将我们的数据放在数据流图中计算。节点(Nodes)在图中表示数学操作,图中的边(edges)表示节点间相互联系的多维数据数组,即张量(tensor)。训练模型时tensor会不断的从数据流图中的一个节点flow到另一个节点。
我们知道对于神经网络模型而言,只要训练数据足够,那么就可以在给定输入层后,通过模型训练得到期望的输出。
那么我们为什么还需要引入RNN呢?我们知道一般的神经网络模型的输入层在时间上没有依赖关系。但是,有时我们需要处理时间序列的问题,比如股票数据、视频数据等,这时就需要RNN模型。RNN是一个具有记忆功能的网络,适合解决连续序列的问题,善于从具有一定顺序意义的样本与样本间学习规律。
一个简单的循环神经网络模型(Recurrent Neural Network, RNN)由输入层、一个隐藏层和一个输出层组成。
我们可以这样来理解,去掉循环层后就是全连接神经网络,代表输入层,代表隐藏层,代表输出层,代表输入层到隐藏层的权重矩阵,代表隐藏层到输出层的权重矩阵。
是上一期的值作为当期的权重矩阵,这里需要注意的是,RNN加入后,隐藏层的值不仅仅取决于当期输入,还取决于上一期的隐藏层的值,我们用公式表示为:
,均为激活函数。
首先加载这里需要用到的python库。
- import tensorflow.compat.v1 as tf
- tf.disable_v2_behavior()
- import numpy as np
- import itertools
- from tensorflow import keras
- from tensorflow.keras import layers
- import pandas as pd
- import matplotlib.pyplot as plt
- from datetime import datetime
- from sklearn.preprocessing import MinMaxScaler
- import statsmodels.api as sm
- plt.style.use('fivethirtyeight')
我们以美国1958年3月1日至2001年12月1日的二氧化碳数据集为例,通过建立RNN模型预测未来一期的二氧化碳含量。
- data_co2 = sm.datasets.co2.load_pandas()
- data_co2 = data_co2.data
- data_co2 = data_co2['co2'].resample('MS').mean()
- data_co2 = data_co2.fillna(data_co2.bfill())
- data_co2.plot(figsize=(15, 6))
- plt.show()
- #将字符串索引转换成时间索引
- data_co2.index = pd.to_datetime(data_co2.index)
通过绘制原始数据的时序图可看出,二氧化碳含量序列具有季节特征,总体呈上升趋势。
对数据进行归一化处理,并划分训练集和测试集。
- data_co2=np.array(data_co2)
- data_co2=np.reshape(data_co2,newshape=(-1,1))
- co2=MinMaxScaler().fit_transform(data_co2)
- co2=np.reshape(co2,newshape=-1)
- x=[]
- y=[]
- day=10
- for i in range(len(co2)-day-1):
- x.append(co2[i:i+day])
- y.append(co2[i+day])
- from sklearn.model_selection import train_test_split
- x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
搭建RNN模型。这里我们采用sigmoid激活函数,均方误差作为损失函数。
- model1=tf.keras.models.Sequential([
- tf.keras.layers.Reshape((day,1),input_shape=(day,)),
- tf.keras.layers.SimpleRNN(units=128),
- tf.keras.layers.Dense(units=64,activation='sigmoid'),
- tf.keras.layers.Dense(units=1,activation='sigmoid')
- ])
- model1.compile(optimizer=keras.optimizers.Adam(0.01),loss=keras.losses.mean_squared_error)
- model1_information=model1.fit(x_train,y_train,epochs=100,verbose=0)
损失函数可视化。
- information_loss=model1_information.history['loss']
- print(information_loss)
- def loss(information_loss):
- fig, ax = plt.subplots()
- ax.plot(range(len(information_loss)),information_loss,'r', label='loss', lineWidth=0.5)
- plt.title("plot of loss")
- plt.show()
- loss(information_loss)
我们可以看到,损失函数逐渐降低,最终稳定在0.002附近。
最后绘制在测试集上的预测值和真实值之间的对比图。
- y_pre=model1.predict(x_test)
- fig, ax = plt.subplots()
- ax.plot(range(len(y_pre)), y_pre, label='prediction', lineWidth=0.8)
- ax.plot(range(len(y_test)), y_test, label='practical', lineWidth=0.8)
- ax.legend()
- plt.title("plot of prediction and practical")
- plt.show()
其中蓝色实线表示预测值,红色实线表示真实值。我们可以看到拟合效果还是不错的。
本文展示了将RNN在序列预测问题上的应用,并通过实例验证了其有效性。但是从它的结构可以看出有三个问题:梯度爆炸、梯度消失、长距离依赖问题。面对一些变化莫测的数据集来说,直接将RNN应用与其中还是有待研究的。针对上述三个问题,使用长短期记忆(Long short-term memory, LSTM)神经网络模型是一个可以考虑改进方向。
https://zhuanlan.zhihu.com/p/30844905 https://zhuanlan.zhihu.com/p/52550025 https://blog.csdn.net/qq_29750461/article/details/81701240 https://zhuanlan.zhihu.com/p/55949716
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。