从dnn到rnn

先思考一个简单的序列:

1
abcabcabcabc...

这个序列的特征是 a->b, b->c, c->a 依次循环往复,这样的一个序列我们可以用最简答的dnn来进行分类,比如a=1, b=2, c=3,那么只需要 y=x+1 函数就可以对a和b的对应值进行预测。但是我们的整数域并没有循环性,老实说数学所有数字都不是封闭的,这意味着我们无法对任何一种数域进行均等分割。

那么一种思路是可以通过平行扩充维度的方式来进行分割,比如将abc设置为:

1
2
3
a=[1,0,0]
b=[0,1,0]
c=[0,0,1]

那么我们拿这样一个矩阵出来:

1
2
3
0 1 0
1 0 0
0 0 1

让abc分别点乘这个矩阵,就可以得到 a->b, b->c, c->a 的循环特点。这样一种矩阵,你可以叫状态转移矩阵,也可以叫系数矩阵,叫法不同,催生的流派也不同,只不过殊途同归。dnn另外还做了高维和非线性变换两种处理,但那两种操作并没有对这个问题的数学本源做改变。

对dnn来说,一个输入,有一个唯一且固定的输出,但是考虑下面这个序列:

1
aabcaabcaabcaabc...

这个序列就不支持上面那种对应关系了,a出现一次的时候对应的是a,只有第二次出现了才会对应b。如果还用dnn进行单一字符的映射,是做不到这点的,关键问题在于我们遇到了一个序列整体作为输入的情况。如果我们采用两个字符来推导第三个字符的形式,也就是说 aa->b, ab->c, bc->a,ca->a 这样一种方案,我们发现dnn依然起作用了!但是大多数情况下,除非是肉眼可以分辨的模式,我们很难确定下一个字符究竟是由前面多少个字符决定的。最稳妥的定义是下面这种方式:

1
2
3
4
5
6
7
8
a->a
aa->b
aab->c
aabc->a
aabca->a
aabcaa->b
aabcaab->c
...

这种方式绝对正确,但是几乎毫无用处。但这至少给了这个问题一个数学上的最完美模型,后面只需要在实践中进行取舍即可。最差的取舍就是如前文所说的单一字符的映射关系,想变好就只有拉长前序字符。但是前序字符越长,我们的转移矩阵就会越复杂。假设我们为这种语言是火星人用的语言,只有3个字母abc,那么对于长度为n的序列,其可能的原始状态就有3的n次方个,这么大的原始数据空间,几乎很难找到正确统一的转移矩阵。比如一个小说有100万字,你想准确预测小说最后一个字是什么,数学上就要完成对3的100万次方的可能空间进行建模。

这个时候出现一种思路,假设纳美克星人大脑比较发达能记住远超过火星人的字符数量,他们的语言一共有100的100次方个字符,日常交流中纳美克人之间往往只要说一个字就能清楚表达所有的意思,上一次交流中出现两个字的情况还是在500年前。那么我们是否能够用纳美克语作为对于火星语超长序列的一种表述,这样对于几乎所有序列,虽然不是所有的,但是能概括一部分的这些进行一种转述?之后再用转述后的纳美克语来实现字符对应的预测。这样一来,之前的数量级的麻烦就转变为纳美克语应该怎么说的麻烦上了。

对应来说,rnn就是这种方案,引入了一种新的语言,对原有超长前序字符进行包装。但只要这样做,就一定有损失,而且这种损失会发生在各个方面。rnn的问题也就发生在损失上,后面出现的lstm等变形实际作用的也只是想办法降低rnn的损失,但基本原理并没有变化。

但是这样一来其实带来另外一些问题:建模序列就是语言吗?我们的语言究竟多少是序列因素的东西多少是其他方面的东西?语言中选择的本质是什么?