Sequence Data 序列数据

很多现实中的数据都是有序的,比如一段语音,一段视频,一段话等。数据的顺序也是信息的重要构成。RNN就是用来解决对序列数据的深度学习的。比如,我们建立一个从一段语音自动翻译成一段文字的模型。又或者我们需要识别视频里人的动作。在或者从一段商品评价里得出这个人对该商品的态度得分。

RNN 里用的数据符号

比如我们需要建立一个模型,这个模型的作用是告诉我们一句话里的每个字是不是一个人名。我们用x表示输入,y表示label:


x : Harry Potter and Hermione Granger invented a new spell.
y : 1     1      0   1        1       0        0 0   0

我们用x^{<t>}表示输入序列里的某一个输入,也就是某一个单词。比如x^{<1>}在上边就代表Harry这个单词。
同理我们用y^{<t>}表示label值。
我们用T_{x},T_{y}表示input序列和label序列的长度,比如上边的例子,对于T_{x},T_{y}都应该等于9。
我们的训练集有很多,每个输入序列的长度不一样,我们用i来表示训练集合中的第i个序列。
x^{(i)<t>}表示第i个训练序列里的第t个单词。用T_{x}^{(i)}表示训练集里第i个序列的长度。

如何表示一个单词

表示单词的问题是如何把一个单词转化成一个数字。

字典

我们首先找到一个字典,然后用每个单词在字典里的序号来表示这个单词。

one-hot encoding

单一有效编码。如果我们两个单词一个在字典里的11位,另一个单词在12位。这两个单词虽然数字是加一,但是并不具备连续型数据的含义。index只是一个序号,并没有更多的内在含义。index在这里是一个离散型变量,不是一个连续型变量。我们可以用单一有效编码。假如我们的字典有10000个单词。那么对于每个单词都是一个10000个元素的向量。只有它所在的index上的值为1,其余9999个位置上的值都为0。把一个单词映射到和字典里单词数一样的一个向量上。并且只有一个1,其余全为0的值,就是one-hot encoding。字典不能包含所有的字,对于所有不在字典里的字我们都用一个<unk>来表示。

循环神经网络

为什么不用传统的神经网络

还是拿之前的例子,判断一句话里的每个单词是不是人名。如果一句话里有9个单词,每个单词都转化成one-hot encoding后的输入向量。输出是一个9个(0或者1)的的向量。0代表这个单词不是人名,1代表是。
如果用传统神经网络就会有三个问题:
1. 因为每句话的长度不一样。而传统神经网络的输入层输入个数是固定的。
2. 更重要的是传统神经网络不共享不同位置的feature。比如一句话前后出现两次的人名。需要分别学习。我们需要找到一种类似卷积神经网络里filter的东西来达到feature共享。
3. 因为one-hot encoding,每个单词的输入向量都很大,一句话又有多个单词,这样第一层如果是传统神经网络的全连接的话,将有惊人的参数。

什么是循环神经网络

还是之前的判断句子中人名的例子,循环神经网络用如下方式来解决:
1. 将句子中的第一个单词x^{<1>}输入神经网络中,得到预测值y^{<1>}
2. 将句子中的第一个单词的激励函数输出值a^{<1>}以及第二个单词x^{<2>}再次输入同一个神经网络中,得到预测值y^{<2>}
3. 以此类推,每一次循环,都是上一次循环的激励函数a^{<t-1>}和当前的输入x^{<t>}经过当前的神经网络的计算,得到输出y^{<t>},对于第一个输入,因为没有a^{<t-1>},可以用0向量来代替。

每一次循环里训练的都是同一个神经网络里的参数。下边两张图可以帮助理解,第一张图是按照时间顺序展开的循环神经网络计算过程:

这个图是循环的表示方法:

通过上边的图我们可以看到在预测靠后的单词时,它不光用到了自己那次循环的输入还同时考虑了它之前所有的输入(通过激活函数引入)来帮助预测。这很有用,但是有一个局限,就是每次预测都没有使用到它后边的输入信息。(虽然在训练时,所有的内容都参与了参数的调整,但是在预测时,只有当前输入和它之前的输入会对本次循环的输出有影响)这个局限在后边的双向循环神经网络(BRNN)会解决。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: