ELMO
1 ELMO模型结构

输入的句子维度是,其中是batch size,是句子长度,是max_characters_per_token
,即每个token的最大字符数,论文使用了固定值50。
经过Char Encoder Layer层后,输出的维度是,其中是projection_dim
。ELMO是基于char的,所以会对每个单词内的所有char进行编码,得到这个单词的表示。Char Encoder Layer层输出一个句子在单词级别上的编码维度。
biLMs层是一个双向语言模型,分开训练了正向和反向的语言模型,而后将其特征进行拼接,最终得到的输出维度是,其中是语言模型的层数,+1则是类似residual connection的操作,加上了初始的embedding层。
得到biLMs层的表征后,会经过一个混合层,会将前面的biLMs层的输出进行线性融合,得到最终的ELMO向量,维度为。
1.1 Char Encoder Layer

Char Embedding。在一个较小的char词表中进行编码。输入的维度是,首先被reshape成,然后经过embedding层,得到的维度是,其中是字符级别的embeddding。
Multi-Scale。使用不同scale的卷积层,在宽度上进行拓展,即输入都是一样的,卷积的kernel_size和channel_size不同,用于捕捉不同n-grams之间的信息。
Concat。将m个不同维度的矩阵进行拼接,得到的维度是。
Highway层。全连接+残差。
Linear映射。将输出的维度映射到。
1.2 biLMs
ELMo主要是建立在biLMs(双向语言模型)上的。
给定一个有N个token的序列,biLMs的目标是最大化下面的概率:
在每一个位置,模型都会在每一层预测一个上下文相关的表征。顶层的输出会被用来预测下一个token的概率。
而反向的语言模型跟正向一样,只是输入是相反的。

2 ELMO两阶段
ELMO是一个两阶段过程:
第一阶段:利用biLMs语言模型训练。
第二阶段:做下游任务时,从预训练网络中提取对应单词的网络各层的Word Embedding作为新特征补充到下游任务中。

输入文本后分别可以的得到三个特征:
E1:单词特征
E2:句法特征
E3:语义特征
之后给这三个Embedding分别一个权重(可以通过学习获得),加权整合成一个Embedding,作为下游任务的输入。
ELMO缺点(与BERT和GPT对比):
LSTM抽取特征的能力远弱于Transformer
拼接方式双向融合特征融合能力偏弱
3 ELMO代码实现
import torch.nn as nn
class ELMo(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, num_layers):
super(ELMo, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(embedding_dim, hidden_dim, num_layers, bidirectional=True)
self.linear = nn.Linear(hidden_dim * 2, vocab_size)
def forward(self, x):
x = self.embedding(x)
x, _ = self.lstm(x)
x = self.linear(x)
return x
vocab_size = len(vocab)
embedding_dim = 100
hidden_dim = 128
num_layers = 2
model = ELMo(vocab_size, embedding_dim, hidden_dim, num_layers)
参考
Last updated