1. BERT中使用Transformer作特征提取器,其实只使用了Transformer的Encoder。
那么Decoder去哪了呢?显然是被BERT改造了。Transformer其实是个完整地seq-to-seq模型,可以解决诸如机器翻译、生成式QA这种输入输出为不定长句子的任务,在Transformer中,它使用Encoder做特征提取器,然后用Decoder做解析,输出我们想要的结果。
而对于BERT,它作为一个预训练模型,它使用固定的任务——language modeling来对整个模型的参数进行训练,这个language modeling的任务就是masked language model,所以它是一个用上下文去推测中心词[MASK]的任务,故和Encoder-Decoder架构无关,它的输入输出不是句子,其输入是这句话的上下文单词,输出是[MASK]的softmax后的结果,最终计算Negative Log Likelihood Loss,并在一次次迭代中以此更新参数。所以说,BERT的预训练过程,其实就是将Transformer的Decoder拿掉,仅使用Encoder做特征抽取器,再使用抽取得到的“特征”做Masked language modeling的任务,通过这个任务进行参数的修正。
当然了,BERT不仅仅做了MLM任务,还有Next Sequence Prediction,这个由于后序验证对模型的效果提升不明显,所以没有赘述。
注意:我们常说,xxx使用Transformer作为特征抽取器,这其实在说用Transformer的Encoder(主要是Self-Attention和短路连接等模块)做特征抽取器,和Decoder啥关系也没有
2. Transformer block是由multi-head self-attention + FFN构成的?
其实论文原文以及配图就是这样写的,但这么说不确切。如果你仔细地看过Transformer部分的源码,你会发现,在multi-head self-attention和FFN层之间,还有一个“intermediate layer”,即中间层,【代码详见此处】。这个中间层将前面Attention-layer的hidden size扩大了4倍,然后再做一次非线性变换(即过一个激活函数,如gelu、relu),再将hidden size变回原size。中间这部分的功能,我个人理解,有点类似于“特征组合器”,增大神经元个数,增强Transformer对于distributed的文本特征的组合能力,从而获取更多、更复杂的语义信息。此外,中间层是Transformer中唯一一个过了激活函数的layer,所以也引入了非线性信息,当然从理论上也对提升模型的拟合不同语义信息能力有帮助。(当然,BERT预训练的MLM任务中,在bert_model的输出之后,在接softmax+将结果计算loss之前,有一个hidden_size不变的线性变换Linear + 激活函数激活 + LayerNorm的过程,【代码详见此处】,这里也有个激活函数,但这并非Transformer的结构,这属于接了下游MLM任务的结构,故真正Transformer-block中的非线性映射,只在中间层的激活函数引入)
实际上,“intermediate layer”在bert代码里是集成到FFN类中的,但由于很多人经常把FFN层直接当做一次线性变换(即简单的nn.Linear layer)而忽略了其中的intermediate layer,故在这里单拎出来加以解释。