RNN原理
-
现在考虑这样一个问题,给一句话,如何判断这句话的情感是积极的(Positive)还是消极的(Negative)
例如下图中的一句话"I hate this boring movie",我们看一眼就知道这句话肯定是消极的,但是如何构建一个网络模型去识别呢?
有一种naive的方法,假设我们把这句话变成一个维度是(5,100)(5, 100)(5,100)的tensor,5表示这句话里有5个词,100表示每个词的维度是100。然后对于将每个词xix_ixi作为输入,分别带入5个Linear Layer,假设得到的输出yiy_iyi,把这五个输出合在一起就是yyy,它的维度是(5,2)(5, 2)(5,2)。最后再接一个Linear Layer,输出ppp,它的维度是(1)(1)(1),这个值表示给出句子是xxx的情况下,这个句子的情感是Positive的概率,即P(pos∣x)P(pos|x)P(pos∣x),就变成了一个二分类的问题
这只是一个naive的做法,这样做会存在很多问题。首先如果输入是一个很长的句子,那么这个句子里的单词就会很多,再加上每个单词对应还需要一段长度的词向量,整个参数量就会非常大;其次,这种做法没有考虑到上下文的信息,例如"我不喜欢你"这句话,如果你只分析"喜欢",你会以为这是一个积极的句子,但其实没有考虑到上文中的"不"字。再比如,一个人说:我喜欢旅游,其中最喜欢的地方是云南,以后有机会一定要去
__
。这里填空,是个正常人都知道填"云南"。我们是根据上下文内容推断出来的,这就意味着,一句话不能单独一个单词一个单词来分析,所以我们希望能有一个consistent tensor来存储语境信息,并且在训练的时候能够将这个语境信息利用起来对于第一个问题,如何解决参数量过大,我们可以参考CNN,卷积神经网络中的每个kernel都利用的权重共享的思想,应用到我们这里就是,每个单词经过的Linear Layer,其www和bbb,都是相同的,而不再是上面那张图的w1w_1w1,w2w_2w2,…b1b_1b1,b2b_2b2,…,具体见下图
对于第二个问题,如何将语境信息也贯穿在整个网络训练的过程中?
看下图的网络结构,每一层的输出,都会作为下一层的一部分输入。例如将"I"的词向量x1x_1x1和h0h_0h0作为输入,输出得到h1h_1h1,就,然后将"hate"这个词的词向量x2x_2x2和h1h_1h1作为输入,输出得到h2h_2h2,如此循环下去。因此这种网络被称为循环神经网络(RNN)
下图是一个典型的RNN网络结构。右边可以理解为左边按照时间进行展开
假设xt−1,xtx_{t-1},x_{t}xt−1,xt表示输入"我"和"是",xt+1x_{t+1}xt+1表示输入"中国",连起来输入就是"我是中国",那么Ot−1,OtO_{t-1},O_{t}Ot−1,Ot就应该对应"是"和"中国",预测下一个词最有可能是什么?就是预测Ot+1O_{t+1}Ot+1最有可能是什么,应该是"人"的概率比较大
因此,我们可以做这样的定义:
Xt:表示t时刻的输入,Ot:表示t时刻的输出,St:表示t时刻的记忆X_t:表示t时刻的输入,O_t:表示t时刻的输出,S_t:表示t时刻的记忆Xt:表示t时刻的输入,Ot:表示t时刻的输出,St:表示t时刻的记忆
因为我们当前时刻的输出是由记忆和当前时刻的输入共同决定的。就像你现在大四,你的知识是由大四学到的知识(当前输入)和大三以及大三以前学到的知识(记忆)的结合。RNN在这点上也类似,神经网络最擅长做的就是通过一系列参数把很多内容整合到一起,然后学习这个参数,因此就定义了RNN的基础:
St=f(U<em>xt+W</em>St−1)S_t=f(U<em>x_t + W</em>S_{t-1})St=f(U<em>xt+W</em>St−1)
这里的f()f()f()函数表示激活函数,对于CNN来说,激活函数一般选取的都是ReLUReLUReLU,但是RNN一般选用tanhtanhtanh假设你大四快毕业了,要参加考研,请问你参加考研是先记住学过的内容然后去考研,还是直接带几本书参加考研呢?答案很显然。RNN的做法也就是预测的时候带着当前时刻的记忆StS_tSt去预测。假如你要预测"我是中国"的下一个词,运用SoftMax在合适不过了,但预测不能直接用一个矩阵去预测,要转为一个向量,所以最终的公式表示为:
Ot=softmax(V∗St)O_t = softmax(V*S_t)Ot=softmax(V∗St)RNN的结构细节:
- 可以把StS_tSt当作隐状态,捕捉了之前时间点上的信息。就像你去考研一样,考的时候记住了你能记住的所有信息
- 可惜的是StS_tSt并不能捕捉之前所有时间点的信息,或者说在网络传播的过程中会"忘掉"一部分。就像你考研也记不住所有的英语单词一样
- 和卷积神经网络一样,RNN中的每个节点都共享了一组参数(U,V,W)(U, V, W)(U,V,W),这样就能极大降低计算量