Skip to content

简单神经网络的局限

上一节我们把文字变成了一串向量。每个 token 都有了自己的数字表示,语义相近的 token 在向量空间里靠得更近。看起来万事俱备,直接把这一串向量喂给第 00 章学到的那种神经网络不就行了?

但事情没那么简单。第 00 章那种简单的神经网络在处理语言时会遇到几个根本性的问题。

问题一:输入长度必须固定

回想第 00 章的小测预测例子:输入是学习时长和复习次数,固定两个数字。我们学的神经网络第一层有几个神经元,每个神经元就有几个权重。两个输入对应两个权重,结构从一开始就定死了。

但语言不是这样的。一句话可以是三个字:

text
今天很好

也可以是一百个字。输入长度每次都不一样,这种神经网络怎么接收?

你可能会想:那就设一个最大长度,短的就补零,长的就截断。这确实是一种办法,但问题也很明显:补了太多零,网络要浪费大量计算在没用的位置上;截断了,又可能丢掉重要信息。而且不管实际句子多短,网络都得处理固定长度那么多输入,效率很低。

更关键的是,这种神经网络的参数数量跟输入维度直接挂钩。输入从 2 个变成 1000 个,权重数量就跟着暴涨。要是想把最大长度设成 2000,参数量又得翻倍。这不只是计算负担的问题,而是这种结构本身就不适合处理变长输入。

问题二:不在乎顺序

简单神经网络把输入当成一组独立的数字来处理。每个输入位置连着一组权重,这些权重各管各的,网络并不关心位置的排列。

但对语言来说,顺序就是一切。看这两个句子:

text
我爱你
你爱我

三个字完全相同,但意思截然不同。一个是"我主动爱对方",另一个是"对方主动爱我"。

假设"我"的向量是 [0.5, 0.3],"爱"的向量是 [0.2, 0.8],"你"的向量是 [0.7, 0.1]。那"我爱你"就是把三个向量拼在一起:

text
[0.5, 0.3, 0.2, 0.8, 0.7, 0.1]

而"你爱我"拼出来是:

text
[0.7, 0.1, 0.2, 0.8, 0.5, 0.3]

这两串数字排列不同,喂给网络后,因为每个位置连接的权重不同,处理方式就完全不一样。这听起来好像是好事?不是的。问题在于,网络是通过死记硬背每个位置的权重来区分顺序的,而不是真正理解了"顺序"这个概念。

打个比方:这就像一个人背下了"第一个位置很重要""第二个位置也重要",但如果你把输入打乱,他只是碰巧用不同的权重重新算了一遍,并没有一个统一的机制来理解"前面出现的词会影响后面词的意思"。

语言的本质是:词和词之间的关系取决于它们出现的顺序和相对位置。第 00 章那种简单的神经网络没有内置这种"顺序感知"的能力。

问题三:捕捉不到远距离关系

一句话里,开头和结尾之间可能隔着很多字,但它们之间有重要的联系。

text
小明今天放学后和同学在学校操场上踢了很久的足球,虽然很累但很开心,然后去了公园。

"小明"和"去了公园"之间隔了二十多个字,但语法上"小明"是"去了公园"的主语。读者能轻松理解这句话,因为人类在读的时候会记住"小明",然后等读到"去了公园"时自动把它们联系起来。

简单神经网络做不好这件事。它只做一次线性变换:把所有输入乘上各自的权重加起来。第一层的每个神经元看到的是所有输入位置的混合,但只有一轮混合。如果两个有关系的词隔得很远,一轮混合很难让它们产生有效的交互。

要是堆更多层呢?理论上更多层能间接建立起远距离的联系,但这会带来新的问题:层越深,中间信息就越容易被稀释。信号传着传着就弱了,网络可能记住了一些无关紧要的噪声,反而把真正重要的远距离关系弄丢了。

我们需要什么样的网络

把三个问题放在一起看:

text
简单神经网络的局限       语言的实际需求
-------------------      -----------------
要求固定输入长度    -->  输入长度不固定
没有顺序概念        -->  顺序改变含义
难以捕捉远距离关系  -->  远处词之间有联系

不是简单神经网络不好,它只是不适合处理语言。处理语言需要一种新的网络结构,这种结构能够:

  • 接受任意长度的输入
  • 理解 token 的排列顺序
  • 让序列中相隔很远的 token 也能产生关联

下一节要介绍的 Transformer,就是为解决这些问题而生的。