这篇文章是我的笔记分享,内容主要来自吴恩达老师的深度学习课程。


神经网络

前面我们讲了word embedding。但是如何才能学习得到呢?

实践证明,建立语言模型是学习word embedding的好方法^[Neural Probabilistic Language Models | SpringerLink]。

下面我们就建立语言模型来尝试一下如何进行句子预测填充。

$$ I \quad want \quad a\quad glass\quad of\quad orange\quad \underline{\quad\quad\quad\quad\quad}. \\quad \ 4343 \quad 9665 \quad 1 \quad 3852 \quad 6163 \quad 5257\quad\quad\quad\quad\quad\quad\quad\quad $$

进行句子预测。我们现在把已经有的这个句子每个单词都标上了序号。

$$ \begin{array}{llllll} \text { I } & o_{4343} & \longrightarrow & E & \longrightarrow & e_{4343} \ \text { want } & o_{9665} & \longrightarrow & E &\longrightarrow & e_{9665} \ \text { a } & o_{1} & \longrightarrow & E& \longrightarrow & e_{1} \ \text { glass } & o_{3852} & \longrightarrow & E& \longrightarrow & e_{3852} \ \text { of } & o_{6163} & \longrightarrow & E& \longrightarrow & e_{6163}\ \text { orange } & o_{6257} & \longrightarrow & E & \longrightarrow & e_{6257}\ \end{array} $$

我们由one-hot向量$o$学习得到word embedding矩阵$E$,再通过word embedding矩阵和one-hot向量相乘。得到对应单词的word embedding向量$e$。

我们将得到的embedding向量放入到神经网络语言模型当中。再经过一个softmax层。然后这个softmax层会在你的单词表中找到一个最为可信的答案作为输出。 image.png 现在分析一下其中的维度。

  • $[o]_{10000\times 1}$

  • $[E]_{300\times 10000}$

  • $[e]_{300\times 1}$

  • $[h]_{6*300 \times 1}$

    h是经过神经网络拼接处理的,就是要预测句子的第七个单词,把句子的前六个单词拼接起来放入神经网络进行处理。

就是在实际操作的过程中,由于质子的程度不同,所以并不是每次把前面的所有内容都拼接起来。而是选择一个大小窗口来进行滑动预测。

比如设置只考虑前面4个单词。那么到了神经网络计算的这一步,H就会变为长度1200。而不是1800。

image.png 就这样使用神经网络对其进行训练。在算法的激励下,你的网络会不断进行数据调整。最终Orange、Apple、Durian、Strawberry、Watermelon短单词都会学到相近的特征值。

这就是学习获得word embedding矩阵$E$的方法之一。

这说明这个例子中我们使用的窗口是选取前4个单词。也有其他选取上下文的方式,比如空缺周围的几个单词、空缺之后的几个单词。


Word2Vec

Word2Vec有两种训练模式。

  • CBOW(Continuous Bag-of-Words Model)
  • Skip-gram (Continuous Skip-gram Model)

这一部分讲的是skip-grams^[[1301.3781] Efficient Estimation of Word Representations in Vector Space (arxiv.org)]。

我们上一部分使用的是神经网络进行了训练。我们当然要知道那个方法进行训练,计算复杂度非常大。所以有没有更简便的方法呢。

基本模型

在skip-gram模型中我们要建立一个监督学习模型。

在这里我们需要选定一个上下文词汇(Content)和一个目标词汇(Target)。

模型过程:

one-hotEword embedding e→softmax→$\hat y$

  • 首先我们要从词汇的one-hot向量$o$入手。
  • 我们可以得到一个word embedding矩阵$E$。
  • 将word embedding矩阵和one-hot向量相乘得到word embedding向量$e$。
  • 这样结果送入softmax中。
  • 得到最终结果$\hat y$

其中softmax 的计算公式为: $$ p(t \mid c)=\frac{e^{\theta_{t}^{\top} e_{c}}}{\sum_{j=1}^{10000}e^{\theta_{j}^{\top} e_{c}}} $$

  • $\theta_{t}$是与输出t有关的参数,即某个输出词汇t和标签相符的概率是多少。
  • 没有加偏置项。

损失函数使用的是负对数自然估计。 $$ \mathcal{L}(\hat{y}, y)=-\sum_{n=1}^{10000} y_{i} \log \hat y $$

softmax之后输出的是一个10000维度的向量。结果是所有可能目标词汇的概率。

优化这个模型比我们之前讲的优化那个神经网络会简单很多很多。

解决softmax计算量大

$$ p(t \mid c)=\frac{e^{\theta_{t}^{\top} e_{c}}}{\sum_{j=1}^{10000}e^{\theta_{j}^{\top} e_{c}}} $$

看着softmax的计算公式,我们就应该知道它的分母计算量是很大的。我们这个例子词汇表只有1万。计算量已经很恐怖了。如果那些词汇表的规模为100万呢。

有一个方法是对其进行平均拆分(图左)。可以考虑一下二分查找。他不会一下子告诉你最后这个结果是在1万个单词中的哪一个位置。而是分层的告诉你。

比如第一层告诉你,他在后5000个之中。第二层告诉你,他在前7500个之中。然后第三层再逐层告诉你。

另一个方法是按频率进行统计。(图右)

可以考虑一下哈曼树那种。水平比较高的更接近根节点。当然也有的是使用力学持平比较低的,更接近于根节点。

image.png


负采样

Word2Vec我们知道了它的缺点是softmax计算起来太慢了,现在我们来看一种改进方法:负采样 | Negative sampling^[[1310.4546v1] Distributed Representations of Words and Phrases and their Compositionality (arxiv.org)]

负采样要做的是建立一个新的监督学习任务。 给定一对单词。我们要预测是否是一对context - target。

先来获取我们的训练集。

我们需要。寻找一个context word。然后跟上一节一样,在一定的词句之内选择一个target word。

使用例句:

I want a glass of orange juice to go along with my cereal.

比如我们选择orange作为context word,然后选择juice作为target word。

Orange和juice就是我们的正样本。之后我们在词典中进行随机采样,选取K个单词放入表格作为负样本。

context word word target?
Orange juice 1
Orange King
Orange Men
Orange The
Orange Of

这里你会发现of其实离orange也非常近,但是不用担心。除了你选取的target word之外,剩下的词可以随机的从字典中取,并且设置为负样本。

在这里我们K选择的是4。

论文中原文作者的建议是,少的数据集K可以取值大一点,大的数据集K就取值小一点。小一点的数据集K取5~20,大一点的取2~5。

对于负样本的选择方法:

你当然可以选择从单词表中使用均匀分布进行随机选取,但是这样随机性实在是太大。所以你可以考虑一下其他的选择方法。比如按照词频来选择。

如果你按照词频从高到低开始选择的话,那你很可能遇到一个问题,就是那些常用的词都是the、of、and之类的。另一个极端是你从低到高开始选择,那你这样会遇到一些特别生僻的词,平时根本就用不太着。

原文的建议是使用: $$ P\left(\omega_{i}\right)=\frac{f\left(\omega_{i}\right)^{3 / 4}}{\sum_{j=1}^{10,000} f\left(\omega_{j}\right)^{3 / 4}} $$

对于词频的$\frac 3 4 $次方除以整体的值进行采样。如果$f(w_i)$是观测到的语料库中的某个单词,通过计算之后会使其处于均匀分布和训练集的观测分布两个极端之间。

模型:

$$ P(y=1 \mid c, t)=\sigma\left(\theta_{t}^{\top} e_{c}\right) $$

  • $θ_t$是与输出t有关的参数,即某个输出词汇t和标签相符的概率是多少。
  • $e_t$是word embedding向量。
  • 这里在激活函数使用的是sigmoid。

现在这个问题就转化成了计算target等于1的概率。如果你有K个样本,也可以看作是$1:K$个正负样本的比例,并将其训练成一个类似于logistic回归的模型。

image.png

首先我们是获得一个orange的one-hot向量,之后我们得到的一个word embedding矩阵,再得到一个word embedding向量。下一步不是进入一个softmax,而是将其转换成一万个logistic回归的二分类。并且我们不是每次都要计算1万个,而是在每次迭代中进行训练K+1个值。这样相比原来要训练1万维度的softmax计算量会小很多。


拓展

关于负采样,我前几天看了一篇文章,包括静态负采样、强负采样、对抗式负采样等等,有一大堆相关论文提供阅读。因为是我在别人公众号看到的文章也不是我自己写的,大家感兴趣的可以自己去搜一下。