旭峰 2018-03-02
2017年对人工智能和加密货币(Cryptocurrency)来说是伟大的一年。现如今,人工智能行业已经出现很多研究和突破,而且人工智能是当今最流行的技术之一,未来还会更多。这一年,可以说是这是一次大规模的牛市,各种加密比、比特币、莱特币,瑞波币等方面的投资得到了一些回报。
有许多的ML专家、爱好者将这些技术应用到加密货币市场上,因为机器学习和深度学习的模型以各种各样的方式用于股票市场。
构建一个单点预测模型可能是探索时间序列深度学习(如价格数据)的一个很好的起点。当然,这不会是它的结束点,总会有改进的空间并添加更多的输入数据。使用深度强化学习作为自动交易代理是一个不错的的方式。然而万丈高楼平地起,第一步很关键,本文首先讨论的是学习使用LSTM网络并建立一个良好的预测模型。
先决条件和开发环境
老规矩,这里已经假设你在Python中拥有一些编程技能,并具备机器学习的基本知识,尤其是深度学习领域的相关知识。如果你还是一个小白,可以多关注AI中国,不定期地会发布一些干货的知识。
这儿选择的开发环境是谷歌的Colab。之所以选择了Colab,是因为它的环境设置很简单,并且可以使用免费的GPU,这对训练时间产生了很大的影响。以下是如何在Google云端硬盘中设置和使用colab的教程。你可以在GitHub上找到完整的Colab Notebook。(https://github.com/SiaFahim/lstm-crypto-predictor/blob/master/lstm_crypto_price_prediction.ipynb)
如果你希望设置AWS环境,可以看看这篇教程(https://towardsdatascience.com/how-to-set-up-deep-learning-machine-on-aws-gpu-instance-3bb18b0a2579),介绍如何在GPU上使用Docker设置AWS实例。
回到正题,本文将使用带有TensorFlow后端的Keras库来构建模型并训练历史数据。
什么是循环神经网络?
为了解释循环神经网络,我们首先回到带有一个隐藏层的简单感知网络。这样的网络对于简单的分类问题可以做得很好。通过添加更多的隐藏层,网络将能够推断我们输入数据中更复杂的模式,并提高预测的准确性。然而,这些类型的网络适用于与时间顺序无关的历史无关的任务。例如,训练集中的先前样本不会影响下一个样本的图像分类。换句话说,感知器对过去没有记忆。对于卷积神经网络来说,这是更复杂的图像识别感知器体系结构。
循环神经网络(RNN)是神经网络的一种类型,它通过在前一时间步骤的隐藏状态中循环并结合当前输入样本来解决感知器的过去记忆的问题。
接下来让我们更详细地阐述这一点,在新样本进入的每一个时间步骤中,网络将忘记前一步骤中的样本,解决时间序列问题的一种方法是引入先前的输入对当前样本进行采样,以便我们的网络可以了解之前发生的情况,但是,这样我们将无法在上一步之前捕获时间序列的完整历史记录。一个更好的方法是从前一个输入样本中获得隐藏层(隐藏层的权重矩阵),并将其与当前输入样本一起输入到我们的网络中。
将隐藏层的权重矩阵看作网络的状态,如果以这种方式来看,隐藏层已经以所有神经元的权重分布的形式捕获过去,这是更丰富的表示的网络。下面的图片将提供RNN中发生的情况的可视化。
当Xt进入时,来自Xt-1的隐藏状态将与Xt串联并在t时刻成为网络的输入。这个过程将按照时间序列对每个样本重复进行。
这里尽量保持简单。如果你想更深入地了解RNN,这里有一些有关于RNN的好资源:
·RNN简介(http://www.wildml.com/2015/09/recurrent-neural-networks-tutorial-part-1-introduction-to-rnns/)
·用于初学者的递归神经网络(https://medium.com/@camrongodbout/recurrent-neural-networks-for-beginners-7aca4e933b82)
·递归神经网络的不合理有效性(http://karpathy.github.io/2015/05/21/rnn-effectiveness/)
什么是长短期记忆网络(LSTM)?
在告诉你什么是LSTM之前,让我告诉你有关循环神经网络的最大问题。直到我们通过反向传播训练之前,一切看起来都很好。当我们的训练样本的梯度通过我们的网络向后传播时,它变得越来越弱,当它到达代表我们时间序列中较旧数据点的那些神经元时,它没有任何能量来适当地调整它们。这个问题被称为梯度消失。 LSTM单元是一种循环神经网络,它存储关于过去的重要信息并忘记非重要的部分。这样,当渐变向后传播时,它不会被不必要的信息所消耗。
当你阅读一本书时,经常在完成一章之后想想自己,虽然你可以记住前一章的内容,但是你可能无法记住所有关于它的重要观点。解决这个问题的一种方法是,我们强调并记录那些重要的要点,以记住和忽略对主题不重要的解释和填充。
让我们一起看看代码
首先,我们导入项目所需的库。
历史数据
这里使用了www.coinmarketcap.com的历史数据,你也可以使用其他来源,使用它的原因是这篇文章比较直接简单。我们将获得比特币的每日价格数据。但是,在colab笔记本中,你也会看到以太坊的代码。这里是以某种方式编写的代码,以便可以重用其他加密货币。
现在让我们编写一个获取市场数据的函数。
现在让我们获取比特币的数据并将其加载到变量'''btc_data'''并显示我们数据的前五行。
让我们来看看比特币的收盘价格以及它的日常交易量。
数据准备
构建任何深度学习模型的很大一部分是,准备我们的数据供神经网络用于训练或预测。根据我们正在使用的数据类型,此步骤称为预处理,其中可能包含多个步骤。在我们的案例中,我们将在下面的任务中作为我们预处理的一部分:
·数据清理,填补缺失的数据点
·合并多个数据通道。比特币和以太坊在一个数据框中。
·计算价格波动并将其添加为新列
·删除不必要的列
·根据日期对数据进行排序
·拆分训练和测试的数据
·创建输入样本并在0和1之间进行归一化
·创建训练和测试集的目标输出
·将我们的数据转换为numpy数组以供我们的模型使用
数据清理部分已经在我们加载数据的第一个函数中完成了。你可以在下面找到执行上述任务的必要功能:
在这里我们将调用上面的函数来创建我们模型的最终数据集。
现在我们来构建我们的LSTM-RNN模型。在这个模型中,使用了3层LSTM,每层512个神经元,在每个LSTM层之后0.25个Dropout,以防止过度拟合,最后形成一个密集层产生我们的输出。
这里使用了'tanh'作为激活函数,绝对平均误差作为损失,'adam'作为优化器。可以尝试这些功能的不同选择,看看它们如何影响模型的性能。
以下是我们的模型总结:
在代码开始时,就已经将超参数解码为完整的代码,以便从一个地方更容易地更改不同的变体。这里是超参数:
现在是对我们收集的数据进行模型训练的时候了
上述代码可能需要一段时间才能完成,具体取决于计算能力,完成后,你的训练模型也就完成了。
我们来看看BTC和ETH的结果(BTC:市值第一大的虚拟货币;ETH:市值第二大的虚拟货币,同时也是以太坊平台运行时所需的代币)
对起跑者来说还是不错的!