在本教程中,无涯教程将使用带有时间序列数据的RNN。时间序列取决于以前的时间,这意味着过去的值包括网络可以学习的重要信息。时间序列预测是为了估计任何序列的未来价值,例如,股价,温度,GDP等。
RNN和时间序列的数据准备有些棘手。目的是预测该系列的其他值,将使用过去的信息来估算t +1时的成本。标签等于一个周期的输入连续。
其次,输入的数量设置为1,即每次观察一次。最后,时间步长等于数值的顺序。如果将时间步长设置为10,则输入序列将连续返回十次。
看下面的图,必须在左侧表示时间序列数据,在右侧表示虚拟输入序列。创建一个函数以返回2001年1月至2016年12月的每一天的随机值数据集
# To plotting amazing figure %matplotlib inline import matplotlib import pandas as pd import matplotlib.pyplot as plt def create_ts(start = '2001', n = 201, freq = 'M'): ring = pd.date_range(start=start, periods=n, freq=freq) ts =pd.Series(np.random.uniform(-18, 18, size=len(rng)), ring).cumsum() return ts ts= create_ts(start = '2001', n = 192, freq = 'M') ts.tail(5)
输出:
2016-08-31 -93.459631 2016-09-30 -95.264791 2016-10-31 -95.551935 2016-11-30 -105.879611 2016-12-31 -123.729319 Freq: M, dtype: float64 ts = create_ts(start = '2001', n = 222)
# Left plotting diagram plt.figure(figsize=(11,4)) plt.subplot(121) plt.plot(ts.index, ts) plt.plot(ts.index[90:100], ts[90:100], "b-",linewidth=3, label="A train illustration in the plotting area") plt.title("A time series (generated)", fontsize=14) ## Right side plotted Diagram plt.subplot(122) plt.title("A training instance", fontsize=14) plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance") plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red') plt.legend(loc="upper left") plt.xlabel("Time") plt.show()
图的右侧部分显示了所有系列。它从2001年开始,到2019年结束。相反,必须创建一批长度等于时间步长的数据。这批将是X变量。 Y变量与X相同,但只移位了一个周期(即希望预测t + 1)。
两个向量具有相同的长度。可以在上图的右侧看到这一点。该行表示x输入的十个值,而红点标签具有十个值y。请注意,标签在X的前面开始一个周期,在一个周期之后结束。
现在是时候建立第一个 rnn 来预测该系列。必须为模型指定一些超参数(模型的参数,即神经元数量等)。
无涯教程的网络将从 10 天的序列中学习,其中包含 120 个复发神经元。用一个输入来输入模型。
在构建模型之前,需要将数据集拆分为列车集和测试集。完整的数据集具有 222 数据点;将使用前201个点培训模型,最后21分来测试模型。
定义训练和测试集后,需要创建一个包含批次的对象。在这些批次中,有X值和Y值。请记住,X值是一个周期散布。因此,使用前200个观察值,并且时间步长等于10。x_batches对象必须具有20个大小为10或1的批次。Y_batches的大小与X_batches对象相同,但是带有一个周期。
首先,将序列转换为numpy数组;然后定义窗口(网络将从中学习的时间),输入,输出的数量以及大小。
series = np.array(ts) n_windows = 20 n_input = 1 n_output = 1 size_train = 201
之后,将数组分成两个数据集。
# Split data train = series[:size_train] test = series[size_train:] print(train.shape, test.shape) (201) (21)
可以创建一个返回两个不同数组的函数,一个数组用于 X_batches ,另一个数组用于 y_batches 。为了使它更容易。
让无涯教程创建一个构造批处理的函数。
请注意,X_batches记录了一个周期(取值t-1)。函数的输出具有三个维度。第一个尺寸等于批处理的数量,第二个尺寸等于窗口的大小,最后一个尺寸是输入的数量。
时间序列的棘手部分是正确选择数据点。对于X个数据点,从 t = 1到t = 200 中选择观测值,而对于Y个数据点,将观测值从 t = 2到201 中返回。一旦有了正确的数据点,就可以毫不费力地重塑系列。
要使用批处理构造对象,需要将数据集分成同一长度的十批次。可以使用重塑方法和PASS -1,使得该系列与批次大小相同。值20是每批注释的数量,1是输入的数量。
需要为标签做同样的步骤。
x_data = train[:size_train-1]: Select the training instance. X_batches = x_data.reshape(-1, Windows, input): creating the right shape for the batch. def create_batches(df, Windows, input, output): ## Create X x_data = train[:size_train-1] # Select the data X_batches = x_data.reshape(-1, windows, input) # Reshaping the data in this line of code ## Create y y_data = train[n_output:size_train] y_batches = y_data.reshape(-1, Windows, output) return X_batches, y_batches #return the function
现在定义了函数,其称为创建批次。
Windows = n_ Windows, # Creating windows input = n_input, output = n_output)
可以打印形状以确保尺寸正确。
print(X_batches.shape, y_batches.shape) (10, 20, 1) (10, 20, 1)
只需要创建一批数据和20个观察值的测试集即可。
请注意,预测日复一日,这意味着第二个预测值将基于测试数据集第一天的实际值( t + 1 )。真实值将是已知的。
如果要预测 t + 2 ,需要使用预测值 t + 1 ;如果您要预测 t + 3 ,需要使用期望值t + 1和t + 2。这使得很难准确地预测" t + n"天。
X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1) print(X_test.shape, y_test.shape) (10, 20, 1) (10, 20, 1)
无涯教程的批次大小已准备就绪,可以构建RNN架构。记住有120个复发神经元。
要创建模型,需要定义三个部分:
1.变量
需要以适当的形状指定X和y变量。这一步是微不足道的。张量与对象 X_batches 和对象 y_batches 相同。
例如
结果是:
tf.placeholder(tf.float32, [None, n_windows, n_input]) ## 1. Construct the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output])
2.创建RNN
在第二部分中,需要定义网络的体系结构。和以前一样,使用TensorFlow估计器中的对象BasicRNNCell和dynamic_rnn。
## 2. create the model basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
下一部分比较棘手,但可以加快计算速度。需要将运行输出转换为密集层,然后将其转换为具有与输入字段相同的尺寸。
stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])
3.创建损失和优化
模型优化取决于正在执行的任务。
这种差异很重要,因为它可以改变优化问题。连续变量的优化问题用于最小化均方误差。要在 TF 中构建这些指标,无涯教程可以使用:
tf.reduce_sum(tf.square(outputs - y))
持久代码与以前相同;使用AdamOptimizer优化器来减少损失。
tf.train.AdamOptimizer(learning_rate=learning_rate) optimizer.minimize(loss)
可以将所有内容打包在一起,并且模型已经准备好进行训练。
tf.reset_default_graph() r_neuron = 120 ## 1. Constructing the tensors X = tf.placeholder(tf.float32, [None, n_windows, n_input]) y = tf.placeholder(tf.float32, [None, n_windows, n_output])
## 2. creating our models basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output]) ## 3. Loss optimization of RNN learning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) training_op = optimizer.minimize(loss) init = tf.global_variables_initializer()
将使用 1500 时期培训模型,并每150次迭代打印丢失。培训模型后,会在测试集上评估模型,并创建包含预测的对象。
iteration = 1500 with tf.Session() as sess: init.run() for iters in range(iteration): sess.run(training_op, feed_dict={X: X_batches, y: y_batches}) if iters % 150 == 0: mse = loss.eval(feed_dict={X: X_batches, y: y_batches}) print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test}) "0 MSE: 502893.34 150 MSE: 13839.129 300 MSE: 3964.835 450 MSE: 2619.885 600 MSE: 2418.772 750 MSE: 2110.5923 900 MSE: 1887.9644 1050 MSE: 1747.1377 1200 MSE: 1556.3398 1350 MSE: 1384.6113"
最后,可以将序列的实际值与预测值一起绘制。如果无涯教程的模型得到纠正,则预测值应置于实际值之上。
可以看到,该模型还有改进的空间需要更改超级参数(例如窗口),当前文件中循环神经元数量的批处理大小。
plt.title("Forecast vs Actual", fontsize=14) plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="actual", color='green') plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="forecast", color='red') plt.legend(loc="lower left") plt.xlabel("Time") plt.show()
递归神经网络是一种用于时间序列和文本分析的体系结构。前一状态的输出用于保存一段时间或字序列上的系统内存。
在TensorFlow中,以使用be; ow给定的代码来训练时间序列的递归神经网络:
模型参数
n_windows = 20 n_input = 1 n_output = 1 size_train = 201
定义模型
X = tf.placeholder(tf.float32, [none, n_windows, n_input]) y = tf.placeholder(tf.float32, [none, n_windows, n_output]) basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu) rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32) stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron]) stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output) outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])
构建优化函数
learning_rate = 0.001 loss = tf.reduce_sum(tf.square(outputs - y)) optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate) training_op = optimizer.minimize(loss)
培训模型
init = tf.global_variables_initializer() iteration = 1500 with tf.Session() as sess: init.run() for iters in range(iteration): sess.run(training_op, feed_dict={X: X_batches, y: y_batches}) if iters % 150 == 0: mse = loss.eval(feed_dict={X: X_batches, y: y_batches}) print(iters, "\tMSE:", mse) y_pred = sess.run(outputs, feed_dict={X: X_test})
祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)