本文介绍了LSTM(长短时记忆)网络,它是RNN的一种特殊类型,适合处理序列数据,尤其在NLP领域有优势。LSTM通过遗忘门、更新门和输出门控制信息流动,保持长时间信息。文章还展示了LSTM单元和网络架构,并说明如何使用TensorFlow和word embedding处理文本数据,进行舆情分类。后续将详细讲解如何用TensorFlow搭建LSTM模型。
(本文独家发布在金蝶云社区上)
基本介绍
LSTM(Long short-term memory)是RNN(Recurrent Neural networks)的一个种类,不知道用中文怎么能准确得把他翻译出来,貌似不管怎么翻译都比较拗口:“长短时记忆”? 我个人感觉还是直接叫LSTM比较合适,而且也显得比较高级。
因为近几年人工智能在工业界大爆发,LSTM这个术语听起来比较时尚新颖,其实这个模型早在1997年就被Hochreiter和Schmidhuber给搞出来了,论文在这LSTM Original Paper。就像神经网络的命运一样,LSTM直到最近才被深度学习的浪潮给带起来,成为所谓的网红。
前面已经说过,LSTM是RNN的一个很特殊的种类,这种网络结构主要用来给序列型数据建模,尤其适合应用于NLP(Natural Language Processing)的这样的问题。对比传统的RNN网络结构,LSTM的优势是能够保持更长时间的信息,确切得说,从时间序列数据早期获得的重要信息将对最终的模型的决策起到很重要的作用。
在这篇文章中,我将介绍LSTM的总体网络架构,LSTM计算单元的一些细节,以及用搭建LSTM模型对从网站stocktwits抓取的股票信息进行舆情分类。在这里我们使用TensorFlow来实现,因为这个框架相对来说比较容易使用,而且他也在产业界比较很流行。
LSTM单元和网络架构
在构建整个网络之前,我们先看看单个的LSTM单元如何工作,以及整个连成网络以后的总体蓝图,看一下下面的图:
比如上面中间的A表示了一个完整的RNN单元,其当前输入的序列是Xt,然后输出当前的隐藏状态h[t],再将其输入下一个RNN单元,当然下一个单元也一样会将X[t+1]作为输入。LSTM单元内部比传统的RNN单元更复杂。传统RNN内部只有一个计算层来处理从h[t-1]到h[t]的转变,而我们的LSTM有三个单元。
我们来看看这三个单元尽有什么奥妙:
1. 遗忘门(Forget Gate)
遗忘门主要控制有多少从前一个Cell(也可以解释为前一个状态)过来的信息将会被保持。从前一个状态过来的隐藏信息h[t-1]和当前的输入X[t]作为遗忘门的输入,先进行一个线性回归计算,即需要W和b作为参数。然后应用sigmoid激活函数来得到一个介于0和1之间的向量,然后再与前一个Cell的第二个状态c[t-1]做一个逐个元素的乘积,得到:forget_gate * c[t-1]
2. 更新门(Update Gate)
更新门基于当前的输入来更新。更新门有两个部分:都是基于X[t]和h[t-1]的输入,分别进行各自的线性回归后,第一个进行sigmoid激活计算,第二个进行tanh激活计算,然后将二者进行逐个元素的乘积,得到的结果与遗忘门的最后的式子相加,形成c[t]: c[t] = update-gate * tanh + forget_gate * c[t-1]
3. 输出门(Output Gate)
输出门用来控制什么信息可以输出到下一个cell。首先,我们将当前计算出来的c[t]通过tanh激活函数,然后和通过了sigmoid函数的于X[t]和h[t-1]的线性回归进行逐个元素级别的乘积,然后得到当前cell的h[t]: h[t] = output-gate * tanh(c[t]).
现在我们对LSTM单元有了更深层次的理解,下面我们来看看LSTM网络架构:
在图二,我们看到了一个展开的带有Embedding层的LSTM网络,从Embeding层出来后紧接着是一个LSTM单元,然后接上一个Sigmoid激活函数。我们看到在这个例子里的输入是电影评论的文本,顺序得输入。
这些输入的文本首先经过embeding层。在很多情况下,当处理一批语料库的时候,字典的规模一般都特别大。因为这个原因,使用word embedding是非常合适的(因为精确性和效率都很高)。这是向量空间中的单词的多维分布式表示。 这些embedding的权值参数可以使用word2vec等其他深度学习技术来学习和训练,或者正如我们在这里所做的那样,我们可以在端到端的方式训练模型,以便在训练时可以得到这些embedding的输出。在这里先要说明一下,输入的单词,语句虽然最开始是字符串,但是真正输入的并不是字符串,而是每个单词在字典当中的索引。
然后将这些输出的embeddings输入到LSTM层,然后再将输出输入到Sigmoid输出层,然后再用LSTM单元处理序列中的下一个单词。在我们这个例子里,我们只关注当整个序列都被输入计算之后模型的输出,因此我们只需要关注我们输入的序列中的最后一个单词的sigmoid输出。
由于篇幅原因,我们分成几篇系列文章。下一篇主要具体讲如何用代码利用TensorFlow来搭建我们需要的模型。