数据准备:
股票价格是长度为N的时间序列,定义为p0,p1,... ,pN- 1,其中pi是指在第i日的收盘价,0≤i
上图为标准普尔500价格。我们在一个滑动窗口中使用内容来预测下一个,而在两个连续的窗口之间没有重叠。
将建立的RNN模型中LSTM单元作为基本的隐藏单元。我们使用在时间t内从第一个滑动窗口W0到窗口Wt的值:
W0=(p0,p1,...,pw-1)
W1=(pw,pw+1,...p2w-1)
...
Wt=(ptw,ptw+1,...,p(t+1)w-1)
来预测下一个窗口Wt+1的值:
Wt+1=(p(t+1)w,p(t+1)w+1,...,p(t+2)w-1)
以上类似于在学习一个近似函数f(W0,W1,... ,Wt)≈Wt+1。
考虑到反向传播(BPTT)的工作方式的,我们通常将RNN训练成一个“展开”版本,这样我们就不需要做太多的传播计算,而且可以节省训练的复杂性。
价格的顺序首先被分成不重叠的小窗口。每个都包含input_size数字,每个都被认为是一个独立的输入元素。然后,任何num_steps连续的输入元素被分组到一个训练输入中,形成一个在Tensorfow上进行训练的“非滚动”版本的RNN。相应的标签就是它们后面的输入元素。
例如,如果input_size=3和num_steps=2,前几个训练的示例如下所示:
数据标准化
以下我们以最新的10%的数据作为测试数据。S&P500指数随着时间的推移而增加,导致测试集中大部分数值超出训练集的范围,也就是说该模型必须预测一些以前从未见过的数字。
解决这一问题,作者将任务变成预测相对变化率而不是绝对值。在t时刻的标准化滑动窗口W't中,所有的值除以最后一个滑动窗口Wt-1中的未知价格价格:
建立模型:
定义参数:
lstm_size:一个LSTM图层中的单元数量。
num_layers:堆叠的LSTM层的数量。
keep_prob:单元格单元在退出操作中保留的百分比。
init_learning_rate:开始学习的速率。
learning_rate_decay:后期训练时期的衰减率。
init_epoch:使用常量init_learning_rate的时期数。
max_epoch:训练中的时期总数
input_size:滑动窗口的大小/一个训练数据点
batch_size:在一个小批量中使用的数据点的数量。
LSTM模型是具有num_layers堆叠的LSTM层,每层包含lstm_size数量的LSTM单元。然后将保留概率为keep_prob的退出掩码应用于每个LSTM单元的输出。退出的目标是消除潜在的强烈具有依赖性维度,以防止过度拟合。
训练总共需要max_epoch 时期(epoch);一个时期(epoch)指所有训练数据点的一个完整通过。在一个时期(epoch)中,训练数据点被分成小批量batch_size的规模。我们发送一小批量的到一个BPTT学习的模型。学习速率在第一个init_epoch时期被设置为init_learning_rate,然后在每个后续时期learning_rate_decay使学习速率衰减。
定义图形
tf.Graph没有依附于任何真实的数据。它主要用于处理数据和运行计算流程。如果用tf.session提供的数据,这时计算的数据是真实的。
(1)首先初始化一个新的图表。
(2)图表的工作原理应在其范围内定义。
(3)定义计算所需的数据。在这里需要三个输入变量,全部定义为tf.placeholder。
1.inputs:训练数据X,形状张量(#数据例子num_steps,input_size); 数据示例的数量是未知的,所以是None。就这个示例而言,在训练中它将是batch_size。如果感到困惑,请查看输入格式示例。
2.targets:训练标签y,形状张量(#数据例子input_size)。
3.learning_rate:一个简单的浮点数。
(4)该函数返回一个LSTMCell有无退出操作。
(5)如果需要的话,我们可以将单元格堆叠成多层。MultiRNNCell有助于依次连接多个简单单元来组成一个单元。
(6)tf.nn.dynamic_rnn是由cell(RNNCell)指定的循环神经网络构建的。状态是指LSTM单元的当前状态,在这里没有消耗。
(7)tf.transpose输出的维度从(batch_size,num_steps,lstm_size)转换为(num_steps,batch_size,lstm_size),然后将其输出。
(8)定义隐藏层和输出层之间的权重和偏差。
(9)我们使用均方误差作为损失度量和RMSPropOptimizer算法进行梯度下降优化。
训练阶段
(1)要开始用真实数据训练图表,我们需要先从一个tf.session开始。
(2)按照定义初始化变量。
(3)训练时期的学习率应该预先计算好。指数是指epoch指数。
(4)下面的每个循环完成一次epoch训练。
(5)下面的每个循环完成一次epoch训练。
使用TensorBoard
在没有可视化的情况下构建图形,非常模糊和容易出错。Tensorboard提供的图形结构和学习过程简单可视,查看这个实践教程。
小结
1.用于with [tf.name_scope]
(https://www.tensorflow.org/api_docs/python/tf/name_scope)("your_awesome_module_name"):将包含在类似目标上的元素一起打包。
2.许多tf.*方法接受name=参数。分配一个定制的名字可以让你阅读图表时更容易。
3.类似tf.summary.scalar和tf.summary.histogram的方法可以帮助跟踪迭代期间图中变量的值。
4.在训练课程中,用tf.summary.FileWriter定义一个日志文件:
上图由示例代码构建的RNN图。“训练”模块已经“从主图表中删除”,因为它在预测时间内不是模型的实际部分。
结果
作者在示例中使用了以下配置。
num_layers=1
keep_prob=0.8
batch_size = 64
init_learning_rate = 0.001
learning_rate_decay = 0.99
init_epoch = 5
max_epoch = 100
num_steps=30
上图是在测试数据中最近200天的预测结果。使用input_size = 1和lstm_size = 32来训练模型。
上图是在测试数据中最近200天的预测结果。模型使用input_size = 1和lstm_size = 128进行训练。
上图在测试数据中的最近200天的预测结果。使用input_size = 5,lstm_size = 128和max_epoch = 75(替代50)训练模型。
本文由阿里云云栖社区组织翻译。
作者:Lilian Weng
译者:乌拉乌拉,审校:袁虎。