在Tensorflow中使用RNN进行时间序列预测
背景:
我研究了一些基本的时间序列预测问题。目标是开始机器学习,并开始我的研究,这是关于在机器人中使用深度学习。
让我们开始解决这个问题。感兴趣的问题是预测具有线性偏差的正弦波:f(t)= 0.1t + sin(t)。假设我们的域对于我们的训练数据是t = [0,500],并且我们想要在t = [500,600]处预测信号。这是一个具有非常独特模式的信号,因此我们的RNN应该几乎完美地预测它。
直觉
让我们来看看这一点的直觉。基本上,时间序列问题是您关心输入顺序的问题。例如,预测股票价格是一个时间依赖的概念。因此,在您的RNN中,您希望按照确切的顺序一次输入一个输入。有时,时间序列问题不一定要抓住时间的概念但它需要以某种方式被排序。例如,在给定一系列单词的情况下,您可以训练RNN预测句子中的下一个单词。
在这个问题的上下文中,我们希望一次向RNN提供一维输入或单个y值。在训练中,我们想要按照顺序来做,因为我们在做预测时关心的是顺序的概念。
Python编码
1.让我们导入必要的Python库
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from sklearn metrics import mean_squared_error
确保已安装Tensorflow和sklearn。
2.创建正弦波,Python代码如下:
minimum = 0
maximum = 60
data_points = np.linspace(minimum, maximum, (maximum - minimum)*10)
dataset = np.sin(data_points)
3.归一化正弦波,范围从0到1,Python代码如下:
dataset = dataset.reshape(-1,1) # necessary for scaler fit_transform function
scaler = MinMaxScaler(feature_range=(0,1))
dataset = scaler.fit_transform(dataset)
4.初始化超参数并生成数据,Python代码如下:
n_steps = 100
n_iterations = 10000
n_inputs = 1 # one input per time step
n_neurons = 120 # one hidden layer
n_outputs = 1 # output layer
learning_rate = 0.0001
dataset = dataset.reshape(-1,) # reshape it back
dataX, dataY = create_training_dataset(dataset, n_steps, n_outputs)
我们使用这里的函数创建一系列数据点:
def create_training_dataset(dataset, n_steps, n_outputs):
dataX, dataY = [], []
for i in range(500):
x = dataset[i]
y = dataset[i+1]
dataX.append(x)
dataY.append(y)
dataX, dataY = np.array(dataX), np.array(dataY)
dataX = np.reshape(dataX, (-1, n_steps, n_outputs))
dataY = np.reshape(dataY, (-1, n_steps, n_outputs))
return dataX, dataY
5.设置计算图:
X = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_steps, n_outputs])
cell = tf.contrib.rnn.OutputProjectionWrapper(
tf.contrib.rnn.BasicRNNCell(num_units=n_neurons, activation=tf.nn.relu),
output_size=n_outputs)
outputs, states = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
loss = tf.reduce_mean(tf.square(outputs - y))
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
training_op = optimizer.minimize(loss)
6.运行计算图并偶尔绘制预测,以跟踪预测的质量,Python代码如下:
# initialize all variables
init = tf.global_variables_initializer()
with tf.Session() as sess:
init.run()
for iteration in range(n_iterations):
X_batch, y_batch = dataX, dataY
# prediction dimension [batch_size x t_steps x n_inputs]
_, prediction =sess.run((training_op, outputs), feed_dict={X: X_batch, y: y_batch})
if iteration % 20 == 0:
mse = loss.eval(feed_dict={X: X_batch, y: y_batch})
print(iteration, " MSE", mse)
# roll out prediction dimension into a single dimension
prediction = np.reshape(prediction, (-1,))
plt.plot(prediction)
plt.title('prediction over training data')
plt.show()
# simulate the prediction for some time steps
#sequence = [0.]*n_steps
num_batches = X_batch.shape[0]
sequence = X_batch[num_batches
1,:,:].reshape(-1).tolist()
prediction_iter = 100
for iteration in range(prediction_iter):
X_batch = np.array(sequence[-n_steps:]).reshape(1, n_steps, 1)
y_pred = sess.run(outputs, feed_dict={X: X_batch})
sequence.append(y_pred[0, -1, 0])
plt.plot(sequence[-prediction_iter:])
plt.title('prediction')
plt.show()
7.结果:
在第一个图中,您可能会注意到图中有中断。这是由于每100个时间步长将隐藏状态初始化为零。更精确地说,100个时间步长是我们告诉Tensorflow为(优化目的)我们将迭代的最大时间步长,当这100个时间步长耗尽时,我们将从0的隐藏状态重新开始。