# Continuous Bag-of-Word

Continuous Bag-of-Word(CBOW)顾名思义，即连续词袋模型，即文本以单个词为最小单位，像“support vector machine”词组也会被当做三个独立的词考虑，且是连续词袋，即目标词的前后词也作为因素考虑。

## One-word context

### 模型结构

下图为网络模型例子，词汇表大小为 $$V$$；隐藏层宽度为 $$N$$(即我们想要的词向量维度)，各层连接为全连接方式；输入为one-hot编码的向量，即词汇表出现的 $$V$$ 个非重复词，一个词 $$w$$ 的向量 $$(x\_1,x\_2,\dots,x\_V)$$ 为对应 $$x\_w$$ 的位置为 $$1$$ ，其他位置都为 $$0$$ ；真实的 $$y$$ 为文本中输入词的下一个词的one-hot编码的向量。

![](/files/-LSqxWRtiINR3pkxC4nJ)

输入层和隐藏层间的权重可由一个 $$V\times N$$ 的矩阵 $$W$$ 表示。 $$W$$ 的每一行是一个 $$N$$ 维向量，表示输入层对应的词向量 $$v\_w$$ 。

&#x20;                                                      $$W =  \left\[  \begin{matrix}    w\_{11} \ \  w\_{12} \ \ \dots\ \ w\_{1N}\  w\_{21} \ \  w\_{22} \ \ \dots\ \ w\_{2N}\  \dots \ \  \dots \ \ \dots\ \ \dots\  w\_{V1} \ \  w\_{V2} \ \ \dots\ \ w\_{VN}\  \end{matrix}   \right]$$&#x20;

$$W$$ 的第 $$i$$ 行是 $$v\_w^T$$ ，给定一个词 $$x\_k=1$$ 且 $$x\_{k'}=0$$ 对于 $$k'\neq k$$ （即这个词的one-hot向量只有 $$k$$ 位置为 $$1$$ ），我们可得：

&#x20;                                                          $$h=W^Tx=W^T\_{(k,\cdot)}:=v^T\_{w\_I}$$                                                                 （1）

其实就是将 $$W$$ 的第 $$k$$ 行复制给了 $$h$$ ，因为 $$x$$ 只有在第 $$k$$ 位置是 $$1$$ （因为输入是one-hot，经过矩阵相乘其实就是把权重 $$W$$ 对应行的值传递给下一层）。 $$v\_{w\_I}$$ 即是输入词 $$w\_I$$ 的向量表示。（这就意味着隐藏层的激活函数是线性的即可，不需要使用ReLU之类的对它们进行非线性变换。比如Multi-word context model中直接把这层的输入进行加权求和传给下层）

隐藏层到输出层的权重可用一个 $$N\times V$$ 的矩阵 $$W'={w'\_{ij}}$$ 表示：

&#x20;                                                    $$W' =  \left\[  \begin{matrix}    w'*{11} \ \  w'*{12} \ \ \dots\ \ w'*{1N}\  w'*{21} \ \  w'*{22} \ \ \dots\ \ w'*{2N}\  \dots \ \  \dots \ \ \dots\ \ \dots\  w'*{V1} \ \  w'*{V2} \ \ \dots\ \ w'\_{VN}\  \end{matrix}   \right]$$&#x20;

基于权重，我们对于每一个词汇表里的词可计算一个分数 $$u\_j$$：

&#x20;                                                                         $$u\_j=v\_{w\_j}'^T h$$                                                                                  （2）

其中 $$v'\_{w\_j}$$ 是 $$W'$$ 第 $$j$$ 列。然后我们用softmax去获得这个词的后验分布，是一个多项式分布：

&#x20;                                                       $$p(w\_j|w\_I)=y\_j=\frac{\exp(u\_j)}{\sum\limits\_{j'=1}^V\exp (u\_{j'})}$$                                                                 （3）

其中 $$y\_j$$ 是输出层第 $$j$$ 个单元的输出。结合输入层到隐藏层 $$h=W^Tx=W^T\_{(k,\cdot)}:=v^T\_{w\_I}$$ 和隐藏层到输出层 $$u\_j=v\_{w\_j}'^T h$$ 公式代入softmax，我们得到：

&#x20;                                                         $$p(w\_j|w\_I)=\frac{\exp(v\_{w\_j}'^T)v\_{w\_I}}{\sum\limits\_{j'=1}^V\exp(v\_{w\_{j'}'}'^Tv\_{w\_I})}$$                                                                  （4）

这里 $$v\_w$$ 和 $$v\_w'$$ 是词 $$w$$ 的两种表达形式。 $$v\_w$$ 源自输入层到隐藏层权重矩阵 $$W$$ 的行， $$v\_w'$$ 源自隐藏层到输出层权重矩阵 $$W'$$ 的列。我们将 $$v\_w$$ 和 $$v'\_w$$ 分别称为“输入向量”和“输出向量”。

模型目标是最大化 $$p(w\_j|w\_I)=\frac{\exp(v\_{w\_j}'^T)v\_{w\_I}}{\sum\limits\_{j'=1}^V\exp(v\_{w\_{j'}'}'^Tv\_{w\_I})}$$ ，即模型输入 $$w\_I$$，模型输出$$w\_O$$(表示它的index在输出层为$$j^\*$$) 与真实$$y$$(输入词的下一个词的one-hot向量)一致。即 $$y$$ 向量第 $$k$$ 位为 $$1$$，其他为 $$0$$ ，我们期望的最佳模型是输出层第 $$k$$ 个单元为 $$1$$ ，其他为 $$0$$ 。模型使用反向传播进行训练。

### 模型训练

#### 1）隐藏层到输出层权重更新

训练目标即最大化 $$p(w\_j|w\_I)=\frac{\exp(v\_{w\_j}'^T)v\_{w\_I}}{\sum\limits\_{j'=1}^V\exp(v\_{w\_{j'}'}'^Tv\_{w\_I})}$$ ， 公式（4）代表的就是给定上下文信息（这里为一个单词 $$w\_I$$ ）以及其权重矩阵的情况下，预测其实际输出单词（即上下文信息的中心词 $$w\_O$$）的条件概率

&#x20;                                     $$\max p(w\_O|w\_I)=\max y\_{j^\*}$$                                                                                       （5）

&#x20;                                                                    $$=\max \log y\_{j^\*}$$                                                                                （6）

&#x20;                                                                    $$= u\_{j^\*}-\log \sum\limits\_{j'=1}^V\exp(u\_{j'}):= -E$$                                           （7）

上式给了损失函数的定义，即 $$E = -\log p(w\_O|w\_I)$$ ，我们旨在最小化 $$E$$ 。 $$u\_{j^*}$$ 的表示方式由公式（2）而来， $$j^*$$ 则为实际输出单词的索引下标。我们注意到该损失函数可以理解为一种特殊情形下的交叉熵计算。

首先我们对损失函数 $$E$$ 求关于$$u\_j$$ 的偏导数，我们可得

&#x20;                                                                     $$\frac{\partial E}{\partial u\_j}=y\_j-t\_j:=e\_j$$                                                                   （8）

上式给出了 $$e\_j$$ 的定义，其中 $$t\_j$$ 只有在第 $$j$$ 个单元是所期待的输出词（即真实的 $$y$$ ）时才为 $$1$$ ，其他情况下为 $$0$$ 。这个导偏数其实就是表示在输出层的预测误差 $$e\_j$$ 。

我们根据链式法则求出损失函数 $$E$$ 关于矩阵 $$W'$$元素$$w'\_{ij}$$ 的偏导数以获得隐藏层到输出层权重的梯度

&#x20;                                                                 $$\frac{\partial E}{\partial w'*{ij}}=\frac{\partial E}{\partial u\_j}\frac{\partial u\_j}{\partial w'*{ij}}=e\_j\cdot h\_i$$                                                              （9）

因此，用随机梯度下降法，我们可以得到隐藏层到输出层的权重更新公式：

&#x20;                                                              $$w'^{(new)}*{ij}=w'^{(old)}*{ij}-\eta\cdot e\_j\cdot h\_i$$                                                       （10）

或者                                    $$v'^{(new)}*{w\_j}=v'^{(old)}*{w\_j}-\eta\cdot e\_j\cdot h\ \ \ \ for\ j=1,2,\dots,V$$                                 （11）

其中 $$\eta>0$$ 是学习率， $$e\_j=y\_j-t\_j$$ ， $$h\_i$$ 是隐藏层第 $$i$$ 个单元； $$v'\_{w\_j}$$ 是 $$w\_j$$ 的输出向量。这个更新公式其实就表明了我们需要查看词汇表中每一个可能的词，比较网络的输出$$y\_j$$与期望的输出(实际值) $$t\_j$$：

* （1）如果 $$y\_j>t\_j$$，那么就从向量 $$v'*{w\_j}$$ 中减去隐藏向量 $$h$$ 的一部分（例如 $$v*{w\_I}$$ ），这样向量 $$v'\_{w\_j}$$&#x20;
* &#x20;         就会与向量 $$v\_{w\_I}$$ 相差更远。
* （2）如果 $$y\_j\<t\_j$$ （这种情况只有在 $$t\_j=1$$ 时，才会发生，此时 $$w\_j=w\_O$$），则将隐藏向量 $$h$$&#x20;
* &#x20;         的一部分加入 $$v'*{w\_O}$$ ，使得 $$v'*{w\_O}$$ 与 $$v\_{w\_I}$$ 更接近
* （3）如果 $$y\_j$$ 与 $$t\_j$$ 非常接近，则此时 $$e\_j = y\_j-t\_j$$ 由于公式（8）非常接近于 $$0$$ ，故更新参数基
* &#x20;         本没什么变化

#### 2）输入层到隐藏层权重更新

&#x20;我们继续对损失函数 $$E$$ 求关于隐藏层 $$h\_i$$ 的偏导数，得：&#x20;

&#x20;                                                     $$\frac{\partial E}{\partial h\_i}=\sum\limits\_{j=1}^V\frac{\partial E}{\partial u\_j}\frac{\partial u\_j}{\partial h\_i}=\sum\limits\_{j=1}^Ve\_jw'\_{ij}:=EH\_i$$                                             （12）

其中 $$h\_i$$ 为隐藏层第 $$i$$ 个神经单元的输出； $$u\_j$$ 在公式（2）中已经定义，表示输出层第 $$j$$ 个神经单元的输入； $$e\_j = y\_j-t\_j$$ 为输出层第 $$j$$ 个单元的预测误差。因此 $$EH$$ 应该是一个 $$N$$ 维度向量，它的每个元素代表的是词汇表中的每个单词的预测误差 $$e\_j$$ 与其输出向量 $$w'\_{ij}$$ 在 $$j=1$$ 到 $$V$$ 上的乘积之和。

接下来，我们需要求出损失函数 $$E$$ 关于权重矩阵 $$W$$ 的偏导数。首先，分解公式（1），我们知道隐藏层激活单元的输出 $$h\_i$$ 是输入层 $$x$$ 与权重的线性组合，即

&#x20;                                                                        $$h\_i = \sum\limits\_{k=1}^Vx\_k\cdot w\_{ki}$$                                                                    （13）

因此对于权重矩阵 $$W$$ 的每一个元素，我们求关于 $$E$$ 的偏导数，得到

&#x20;                                                              $$\frac{\partial E}{\partial w\_{ki}}=\frac{\partial E}{\partial h\_i}\frac{\partial h\_i}{\partial w\_{ki}}=EH\_i\cdot x\_k$$                                                         （14）

因此我们利用张量乘积的方式，便可得到

&#x20;                                                               $$\frac{\partial E}{\partial W}=x\otimes EH=xEH^T$$                                                            （15）

我们再次得到了一个 $$N\times V$$ 的矩阵。由于 $$x$$ 向量只有一个非 $$0$$ 元素，因此 $$\frac{\partial E}{\partial W}$$ 只有一行是 $$N$$ 维非 $$0$$ 向量 $$EH^T$$ ，因此矩阵 $$W$$ 的更新公式为

&#x20;                                                                $$v^{(new)}*{w\_I}=v^{(old)}*{w\_I}-\eta EH^T$$                                                              （16）

其中 $$v\_{w\_I}$$ 是矩阵 $$W$$ 的其中一行，是唯一的上下文单词的“输入向量”，也是矩阵 $$W$$唯一的导数非 $$0$$ 的行向量。除了 $$v\_{w\_I}$$ 以外，矩阵 $$W$$ 的其他行向量在参数更新迭代过程中都会保持不变（因为其导数为 $$0$$ )

与矩阵 $$W'$$ 的更新过程相似，对于公式（16），我们分析如下：

* （1）如果过高地估计了某个单词 $$w\_j$$ 作为最终输出单词的概率（即： $$y\_j>t\_j$$ ），则上下文单词
* &#x20;         $$w\_I$$ （context word ）的输入向量与单词 $$w\_j$$ 的输出向量在更新的过程中会相差越来越大。
* （2） 如果相反，某个单词 $$w\_j$$ 作为最终输出单词的概率被低估（即： $$y\_j\<t\_j$$ ），则单词 $$w\_I$$ 的输
* &#x20;          入向量与单词 $$w\_j$$ 的输出向量在更新过程中会越来越接近。
* （3） 如果对于单词 $$w\_I$$ 的概率预测是准确的，则对于单词的输入向量在更新过程中几乎保持不变。

&#x20;因此，上下文单词 $$w\_I$$ （context word ）的输入向量的更新取决于词汇表中所有单词的预测误差。预测误差越大，则该单词对于上下文单词的输入向量的更新过程影响越大。

## Multi-word context

&#x20;根据字面意思我们就可以看出，基于multi-word context的CBOW模型就是利用多个上下文单词来推测中心单词target word的一种模型。比如下面这段话，我们的上下文大小取值为4，特定的这个词是"Learning"，也就是我们需要的输出词向量,上下文对应的词有8个，前后各4个，这8个词是我们模型的输入。由于CBOW使用的是词袋模型，因此这8个词都是平等的，也就是不考虑他们和我们关注的词之间的距离大小，只要在我们上下文之内即可。

![](/files/-LT6m25xipvWab-8Fn7G)

### 模型结构

其隐藏层的输出值的计算过程为：首先将输入的上下文单词（context words）的向量叠加起来并取其平均值，接着与输入层到隐藏层的权重矩阵相乘，作为最终的结果，公式如下：

&#x20;                                                      $$h = \frac{1}{C}W^T(x\_1+x\_2+\cdots x\_C)$$                                                             （17）

&#x20;                                                          $$=\frac{1}{C}(v\_{w\_1}+v\_{w\_2}+\cdots+v\_{w\_C})^T$$                                                       （18）

其中 $$C$$ 为上下文单词的个数， $$w\_1,w\_2,\dots,w\_C$$ 为上下文单词， $$v\_w$$ 为单词 $$w$$ 的输入向量。损失函数为

&#x20;                                                    $$E = -\log p(w\_O|w\_{I,1},\dots,w\_{I,C})$$                                                         （19）

&#x20;                                                         $$=-u\_{j^\*}+\log \sum\limits\_{j'=1}^V\exp(u\_{j'})$$                                                               （20）

&#x20;                                                         $$= -v\_{w\_O}'^T\cdot h+\log\sum\limits\_{j'=1}^V\exp(v\_{w\_j}'^T\cdot h)$$                                                 （21）

网络结构如下：

![](/files/-LT6p2tU6aToJXca8Oxm)

### 模型训练

#### 1）隐藏层到输出层权重更新

&#x20;同样，由隐藏层到输出层的权重更新公式与One-word context模型下的一模一样，即类似于公式（11），我们直接写在下面：

&#x20;                                           $$v'^{(new)}*{w\_j}=v'^{(old)}*{w\_j}-\eta\cdot e\_j\cdot h\ \ \ \ for\ j=1,2,\dots,V$$                                 （22）

#### 2）输入层到隐藏层权重更新

&#x20;由输入层到隐藏层的权重矩阵更新公式与公式（16）类似，只不过现在我们需要对每一个上下文单词 $$w\_{I,c}$$ 都执行如下更新公式：

&#x20;                                            $$v^{(new)}*{w*{I,c}}=v^{(old)}*{w*{I,c}}-\frac{1}{C}\eta EH^T \ \ \ \ for\ c=1,2,\dots,C$$                                  （23）

&#x20;其中 $$v\_{w\_{I,c}}$$ 为context中第 $$c$$ 个单词的输入向量； $$\eta$$ 为正学习速率； $$EH = \frac{\partial E}{\partial h\_i}$$ 由公式（12）给出。

## Source

{% embed url="<https://arxiv.org/pdf/1411.2738.pdf>" %}

{% embed url="<https://blog.csdn.net/lanyu_01/article/details/80097350>" %}

{% embed url="<https://www.cnblogs.com/pinard/p/7160330.html>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://chmx0929.gitbook.io/machine-learning/zi-ran-yu-yan-chu-li/zi-ran-yu-yan-chu-li/wen-ben-xiang-liang-hua/continuous-bag-of-word.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
