近几年,华尔街不断裁员,高盛在2000年顶峰时期,雇佣了600名交易员,为其机构客户进行股票买卖,但时至今日,却仅剩下2名交易员“看守”柜台。 不仅高盛、瑞银、摩根士丹利等金融公司,目前都已经采用机器学习算法替代普通交易员来进行交易。 那,什么样的算法如此厉害? 它能够预测股价走势 不仅如此,它还能搭建聊天机器人,可以翻译外文,可以写新闻稿、写小说..... 这个算法就是循环神经网络,简称RNN。 这里总分为3个部分: RNN算法之预备知识:前馈神经网络(FFNN) 初始RNN算法 RNN算法之变体:长短期记忆(LSTM) RNN算法之预备知识:前馈神经网络(FFNN)
这只是我们随机编写的一些数字,它很简单,不适用任何模型算法,你也能轻而易举的找到x-y之间的规律:y=9*x 但是如果我们一定要用神经网络来计算的话,那么,这个神经网络可以简单的搭建为: 先别晕,我们举个例子,你就明白上面的逻辑了。 以第一条数据为例:
这个模型的核心:就是努力找到x与y之间的联系。 比如, 图中的1和9,就是模型找到的其中一种连接方法。 更一般的,如果你拥有数据(X,Y),神经网络算法就会去寻找最佳的参数W: 求解W,就是这条神经网络会替我们努力完成的工作。 上面的图,写成公式为: 注:两个公式中的w,数值可能不相同。 这就是一条最简单的神经网络 当然,更多的时候,你在教材上看到的是这样的: 如果我们将参数b暂时遮挡住: “公式二”与“公式一”之间,仅仅多出一个f()函数。 这个f()函数,在学术上被称为“激活函数”,通常是一个非线性的函数。 例如, 像上面这些,均可以作为激活函数来使用。 你会问:“为什么我们要使用激活函数?” 这里因为,(w*x)和(w*h)仅仅是线性运算: 而我们在现实中遇到的问题,更多都是非线性的。 这就好比, 家到学校,理论上是两点一线的距离;但在现实中,你要曲曲弯弯走很多路,才能抵达终点: 因而,在w*X的外面,包裹上一层激活函数 f(w*X) 可以将线性问题转化为非线性问题,这样更接近真实的世界,也能使我们的模型预测准确度得到大幅度提升。 好了,前面我们一直讨论的是一条数据的情形,即 ![]() 现在,如果我们把t+1条数据,全部考虑进来: ![]() 那么此时,神经网络的形态变为: ![]() 由图可以看出,它是t+1条数据的“堆叠”。 你会发现像这样的神经网络,它只是横向箭头,并没有纵向箭头。 即第t条数据,并不受之前数据的影响。 你可以视为它为一条一直向前,永不回望的神经网络,也因此而得名“前馈神经网络”。 我们单拎出第t条数据: ![]() 此时,ht仅仅受Xt的影响。 在实际工作中,它适用于“上一条数据与下一条数据,彼此之间没有任何关联”的情形。 举几个例子: 图像分类 ![]() 第一张图与第2张图之间,并无关联。 薪水等的预测 ![]() 第一条职位所提供的薪水,并不决定第2条职位薪水的高低。 电影推荐 ![]() 第一部电影的好坏,并不影响第2部电影是否受观众的欢迎。 上面这些例子,都可以借助前馈神经网络来解决。但有些例子则不然。 初始RNN算法 先来看一组数据: ![]() 这组数据来自某只大A股2017年9月份的表现 ![]() 在前馈神经网络中,数据与数据之间,并不存在依存关系,即“下一条数据,并不依赖于之前 数据的信息”。 但是,像上图中,这样的一组股票价格,你还能说“上一条数据与下一条没有关系”吗? 我们预测9月21日的价格时,不仅要参考9 月20日的,还要参考9月18日的、9月17日的、... 此时,每一条数据,都受到之前数据的影响。 除了股价预测外,像搭建聊天机器人: ![]() 写新闻稿: ![]() 预测故事发展情节: ![]() 类似这样的数据,都是带有时间顺序呢的,即 都需要通过前面已经出现过的文字(或情节),来预测下一个文字(或片段)。 遇到这种情况,我们就需要借助循环神经网络(RNN)来处理。 RNN的运行原理,我们举一个很简单的例子来说明。 假设有这样一句话: “我爱你们” 每次输入一个文字,我们都希望能预测出下一个即将出现的文字是什么? ![]() 这样的数据,写成表格的形式,即: ![]() RNN的运算过程很简单,只要你耐心看完下面这张动图: ![]() 你会发现,RNN的运算,是这样一个流程: ![]() 如果我们将上图简化,它就是这个样子: ![]() 看出它与前馈神经网络的区别了吗? ![]() 循环神经网络,除了有横向箭头外,还有纵向箭头 即,对于循环神经网络来说,它的每一条数据演算,都会依赖于之前的数据。 我们会反复用到隐藏层所携带的信息: ![]() 此时,隐藏层ht不仅受Xt影响,还受上一时刻ht-1的影响: ![]() 注意,ht是受[Xt,ht-1]的影响; 而不是受[Xt,Xt-1]的影响。 因为,ht与Xt-1,可以被视为简单的硬连接。 举个不恰当但是特别好记得例子: ![]() 如果你的第二盘菜,准备做鱼香肉丝。 那么,使用第一盘已经切好的土豆丝, 要比直接使用原材料----土豆块,更省时、省力,对吧? 开个玩笑,不管怎样,要记住: RNN的隐藏层ht是受[Xt,ht-1]的影响,而非[Xt,Xt-1的影响。 希望今后,你再看到其他教材上的公式,会觉得更好理解了。 ![]() 注:公式中的w,数值可能不同 长短期记忆,简称LSTM 上面讲到,循环神经网络的形态,类似于下图的样子: ![]() 如果我们想预测一句话 我爱你们,可以简单的描述为: ![]() 从上图中我们能够看到,在中间的灰色链条上,被塞入了各式各样的“记忆”。事实上,在这根灰色链条上,存储了大量的信息。 ![]() 这根“灰色”链条,我们可以视它为一根记忆链条。 如果将这根记忆链条,比喻成一条公路;将每一次的记忆,比作一辆车。 那么,在这条公路上,已经塞满了汽车: ![]() 如果这根记忆链条很长、很长...... 那么可以想象,在这条长长的公路上,会挤压无数条等待通行的车辆。 你或许能看清离你最近的,但却无法回望到整个队伍的尽头。 ![]() RNN算法也是一样的。 在这根记忆链条上,存储了太多、太多“有用的”和“无用的”信息。 或许,它仍保留有最近一段时间的记忆, 但是,太过久远的记忆,已经记不清了。 所以,当你的数据比较有限时,使用RNN是一个不错的选择。 但如果你的数据时间周期很长,例如: 你有100天的股票收盘数据,你希望基于这100天的数据,预测出第101天的收盘价格。 此时,如果你仍选用RNN算法,那么很可能,它并不能带来令你满意的结果。因为,它实在记不住那么久远的信息了。而此时能解决问题的,是LSTM. LSTM是RNN的一种变体。 既然是变体,说明它的基本原理与RNN大体相同。唯一的区别在于,它比RNN多出了一条公路: ![]() 在这条多出的“公路”上,LSTM存储了更加简洁的信息。 就像你在图中看到的,左边的道路,忙忙碌碌; 右边的道路,清清净净。 对应LSTM算法,忙忙碌碌的道路,即“第一根灰色链条”,依然是“隐藏层”,它用于做各种各样的记忆运算。 比如: 哪些记忆有用,我要留下; 哪些记忆没用,我要丢弃; 哪些输入带有新的信息,我要更新; 等等这些,都是在第一根灰色链条上来处理的,所以你看到它,一直在忙忙碌碌的工作。 ![]() 而第2根灰色链条,学术上称为“细胞状态”,它用于存储“有用的”记忆。 那些“无用的”记忆,是不会出现在这条链条上的,所以你看到它,是干干净净,十分简洁的。 ![]() 正因为有了这样一条“干净、简洁”的信息通道,LSTM能够记住更加久远的信息,即“在处理 ”长期记忆的问题上,LSTM相较于RNN更胜一筹”。 下面,我们来看一看,LSTM是如何“开通这样一条快速通道”的? 还是这张图,我们将其中一个隐藏层单元,放大来看: ![]() 将隐藏层单元放大后的效果为: ![]() 和RNN一样,这个单元依然受Xt和ht-1的影响。 ![]() 与RNN不同的是,在这个单元上,多出3个“阀门”: ![]() 刚刚我们已经讲了,整个单元受[Xt,ht-1]的影响。因而,这3个阀门同样也受[Xt,ht-1]的影响。 因而,在很多教材上,你会看到这样的公式: ![]() 其实,它们均在说明,这3个阀门被[Xt,ht-1]影响着: ![]() 回过头来,我们仍然看这张图: ![]() 这3个阀门,分别代表: 忘记门:忘记过去没用的记忆 输入门:输入新的记忆 输出门:输出当前时刻用得上的信息 耐心看完这张动图,LSTM的运行原理,你或许就清楚了。 ![]() 我们将动图锁定在最后一时刻 ![]() 从上图我们能够看到 右侧的灰色链条上,仅包含了有价值的信息,因而更加简洁。 也正因为多加了这根链条,使得LSTM比起RNN来,能够记住更加久远的信息。 提示: 为了方便理解,本文“输入门”的位置上,只画出了一条线: ![]() 更多的时候,你会看到2条,一条决定添加哪些信息,一条决定添加多少。 ![]() 这2条线的运算目的,就是未来向旧记忆中,添加有用的新记忆。 |
|