1D-CNN 就像是有很多的扫描器同时扫过一个单词一样,扫描的时候他就是一个个字符去扫描。这些个扫描器可以同时聚焦在好几个字符串。当这些扫描器扫描完之后,他们从这些扫描过得字符串上抽取信息。在所有的扫描之后,这些从不同扫描器上拿到的信息,就变成了每个单词的表示。
使用 1D-CNN 的动机是,不仅仅一整个单词是有含义的,每个字符都是有一定的含义的。
比如说,如果我们知道 "underestimate" 这个单词的时候,你同样也能够明白 "misunderestimate",虽然后面的这个单词并不是一个真正的单词。这是为什么呢?
这是因为,从你之前的英语知识中,你会知道 "mis-" 经常表示的意思是 "mistaken",这些知识就是你能够推断出 "misunderestimate" 大概是 "mistakenly underestimate" 这样的意思。
1D-CNN 这种算法就是模拟人类理解这种字符级的能力;**更广义上来说,1D-CNN 是一种能够从比较长的序列中,抽取较短语义片段的算法。**这些输入的序列可以是音乐、DNA、语音录音、网络日志等等。在BiDAF中,长的序列代表了很多单词,短的片段表示这些字符组合起来的片段。
接下来,我们创建一个 convolutional filter $H$。这个convolutional filter(kernel)是一个矩阵会一个个的扫描我们的单词。它的高度 $d$ 和 $C$ 的高度是一样的,但是它的宽度 $w$ 是一个小于 $l$ 的值。$H$ 矩阵里的值在开始时也是随机进行初始化的,随着训练的进行会逐渐的进行调整。
我们把 $H$ 矩阵(卷积核) 覆盖在 $C$ 的最左上角,并且对覆盖的面积做一个 element-wise 的乘积,这会得到一个 $d * l$ 的矩阵,最后把这些值相加,达到一个标量。这一系列的标量会被放到一个新的向量 $f$ 中。
然后,我们把卷积核向右移。
我们重复上面的过程,直到单词的结尾。我们再每一步都会在 $f$ 中增加一个值,最后 $f$ 会变成一个长度为 $l - w + 1$ 的向量。这个向量就表示在每次看三个字符的情况下 “absurdity” 这个单词。
The position invariance of the convolutional filters enables us to capture the meaning of a certain letter combination no matter where in the word such combination appears.
我们记录在 $f$ 中的最大值,这个最大值就表示 $f$ 的摘要。在这个例子中,这个值就是 0.7。我们可以把这个标量叫做"摘要标量"。这个取最大值的过程,我们叫做 "max-pooling"。
然后,我们使用另一个不一样的卷积核,这个卷积核可能会有不同的宽度。在我们的例子中,我们的第二个 $H$,我们表示为 $H'$,宽度为2。
使用不同的卷积核继续重复上面的扫描过程,每一次扫描都有一个“摘要标量”。最后,这些收集起来的"摘要标量"就是这个词的 embedding 向量。