完整版 · 分步教学

前馈神经网络语言模型

N-gram 的死穴是「没见过就不会」。把词换成一串数字再送进神经网络,模型就能对没见过的组合举一反三——这中间到底发生了什么?

目标实验目标

亲手走一遍 Bengio 提出的三步法:查向量 → 拼成一长串 → 过网络。看清「词变成数字」这一步,如何让模型在语料里从没出现过「围绕黑洞运转」的情况下,照样预测出「行星」。

课堂问题「围绕黑洞运转的 ___」这句话,N-gram 因为查不到统计只能回退乱猜。如果先把「黑洞」变成一串和「恒星」很像的数字,结果会不一样吗?
1把上下文词翻译成数字

模型不认字,只认数字。第一步把最近 2 个上下文词各查出一串词向量。这里为了能手算,每个词向量只取 2 维;第 1 维叫「天文性」(越大越像天文词)。

选择上下文(两个词)

第一个词围绕 · 0.100.20
重点对比「恒星」和「黑洞」的词向量几乎一样——这正是下一站「举一反三」的关键。

查表得到的词向量

围绕0.100.20
恒星
第 1 维 = 天文性,第 2 维 = 其它语义。
2拼成一长串:网络的输入

把两串 2 维向量首尾相接,拼成 4 个数,作为神经网络的一整条输入。

观察换第二个词时,只有后两格在变。语料里「围绕黑洞」从未出现过,但只要「黑洞」的数字和「恒星」贴近,这里拼出来的输入就贴近。
3过网络:一个「天文语境探测器」

隐藏层只放这一个神经元,它专盯待定词的「天文性」那一维,做的就是 tanh(w·x + b)(权重 1.5、偏置 −0.8)。天文味越浓,h 越大,越该接「行星」。

隐藏层计算

天文性输入
隐藏层 h
h = −1(无天文味)h = +1(强烈天文味)

输出层:谁更该是下一个词

「行星」的分数 = 2.5 × h,「雨伞」固定为 0,两个分数一起过 softmax。

行星—
雨伞—
等待计算…
4三词对照:见过 / 没见过 / 无关

把三个不同的第二个词排在一起,差别一目了然。前两行的预测几乎一样——哪怕训练里从没出现过「围绕黑洞」。

第二个上下文词天文性隐藏层 hP(行星)说明
这就是泛化词向量相近的词 → 拼出的输入相近 → 隐藏层是连续函数 → 输出也相近。N-gram 把这三个词当三个毫不相关的符号,「恒星」的统计一丝一毫都借不给「黑洞」。
5和 N-gram 放在同一张桌上比较
维度N-gram(数数)FFNN 语言模型
词是什么孤立的符号一串数字(向量)
没见过的组合查不到 → 回退乱猜看相近的词,举一反三
存储庞大的统计表(GB 级)紧凑(向量 + 网络权重)
训练方式数数反向传播
上下文窗口N 个词(固定)N 个词(固定)— 共同的死结
遗留问题窗口仍然固定。要填「那只从小被遗弃在废弃工厂里……的流浪犬,今天终于__」,FFNN 只看得见最后几个词,前面一长串铺垫全被挡在窗口外。这正是下一课 RNN 要解决的。

挑战实验课挑战

挑战 1 · 见证举一反三
把第二个词从「恒星」切到「黑洞」,P(行星) 从 78% 变成多少?为什么几乎不变?
挑战 2 · 翻盘的那一下
再把第二个词换成「香蕉」,天文性只有 0.10。h 变成负的了吗?P(行星) 掉到多少?
挑战 3 · 窗口之外
如果待预测的词要靠 5 个词之前的线索,这个固定 2 词窗口能做对吗?为什么?
挑战 4 · 数字从哪来
这里的词向量是给定的。真实模型里这些数字(以及 1.5 / −0.8 这些权重)是怎么来的?