今年四月份做了关于elmo复现和微调方面的工作。近期在内部和凤巢做了两次关于elmo的分享,感觉大家对这个模型较为陌生,发现其中有些细节和经验值得拿出来说一说,希望对你会有所帮助。
ELMo全称Embeddings from Language Models,是2018年allen nlp的发布的大规模语义模型,paper为《Deep contextualized word representations》。
既然有Bert为什么要讲ELMo?个人认为,其实ELMO微调方式有一定创新性,给人以启发。
以下是根据个人经验梳理出来的你值得关注的一些细节。
细节一:elmo的网络结构是双向双层的lstm,如何实现双向的lstm的呢?
与Bert在预训练目标中使用masked language model来实现双向不同,ELMo的双向概念实际是在网络结构中体现的。输入的embedding通过lstm的hidden state作为正向输出,embedding做reverse后的结果再通过lstm的hidden state反向输出,正向输出与反向输出做concat。最后输出实际是个lauguage model,基于前面的词计算下一个词的概率。
细节二:与Bert的相比,ELMo微调是如何实现的?
ELMo的微调从严格意义上来说,不是真正的微调,预训练网络结果是fix的。 整体来说,是把句子输入到预训练网络的embedding,与下游任务word embedding做concat,concat的结果整体作为下游NLP任务的输出。图为上游ELMO网络迁移到下游阅读理解bidaf网络中。

ELMo迁移到下游NLP任务
细节三:ELMo的语义表示输出是如何处理的?
ELMo的语义表示输出计算公式如下:

其中,hk 代表三层的输出(分别是embedding层,第一层lstm,第二层lstm),与W相乘的权重参数, 通过 个softmax得到 , 权重参数W加入 L2 正则,防止拟合。
r是整体的缩放因 ,为的是与下游的任务 embedding概率分布统一 。
代码里还有个小技巧,word embeding层是256维,所以他把相同word embedding做个concat,与lstm输出的516维统一起来。
从这些细节处理可以看出ELMo在微调阶段的处理与Bert有挺大的不同。
细节四:elmo适合哪些下游NLP 任务?
ELMo在短本任务上表现好。ELMo迁移到下游网络中, 一个是答案较短的数据集,提升有3-4个点, 一个答案较长的数据集,提升只有0.5 左右。在实验中,我们对比过词法分析和阅读理解任务,其在词法分析效果好于阅读理解。
细节五:elmo还有哪些值得注意的参数细节?
1. dropout的处理方式:训练时候设置为0.5,为防止过拟合。infer阶段dropout设置为0。
2.r值对微调阶段影响很大。r值对语义表示的输出调节与下游NLP任务的阈值有较大帮助。
3.No L2 和 L2效果差不多。elmo的语义表示输出公式中权重参数W中加入了L2正则,从实验结果来,没有L2正则对结果影响不大,猜想可能是dropout的设置过大,导致L2对结果不产生影响。

图为ELMo迁移到下游网络的结果,红色的baseline为百度词法分析LAC。
细节六: 如何训练自己的elmo中文预训练模型?
准备约3G的中文文档数据。GPU:8卡GPU,显存大于22GB,调节batch_size,适合于显存大小,最大限度利用显存资源。训练时间约为一周,7天。
细节七:ELMO微调训练周期长的下游任务,如何在较短时间看是否靠谱?
有个技巧是把finetune阶段dropout往大了调,使其快速过拟合。看峰值是否符合预期。