前言
最近做大创,实验室老师给了一个模型,一开始看老师的论文看不太懂。后来要了这篇原paper,地址如下:
InformationAggregationviaDynamicRoutingforSequenceEncoding
如果你打不开,那就点下面的镜像链接:
InformationAggregationviaDynamicRoutingforSequenceEncoding
以后如果要访问arxiv,可以采用下面的方法:
如何访问arxiv上的paper
下面将大致介绍一下这篇论文
背景
一般的text classification有下面四个步骤:
- embedding layer,可以使用一些pre-trained的词向量矩阵,如glove word2vec bert 等
- encoding layer,通过embedding,我们已经得到了每一个词的词向量表示,进而得到了整个句子的序列表示。我们进一步将这个序列放入RNN或者CNN,得到了这个句子的“context aware representation”,也就是说,CNN和RNN这样的神经网络可以更好的得到基于句子的词向量表示。
- aggregation layer,即聚合层,目前我们的句子仍旧表示成一个序列,只是现在的每一个词向量能够吸取了上下次的信息。我们通过aggregation层,进一步地将序列整合。一般的方法用两种:pooling 和 self-attention
3.1 pooling:池化又分为最大池化和平均 池化,懂的都懂,公式如下
一般认为最大池化比较好,因为在分类任务中,真正重要的单词实在是太少了。但pooling的缺点是: 不可训练
3.2 self-attention:公式如下:
对于所有的词向量 h i h_i hi我们都通过自己设置的(可训练的)参数q,去计算它的重要性 u i u_i ui,得到了所有的重要性,再通过softmax进行normalization,最后加权求和得到了整合的句子的特征向量。但self-attention的缺点是(论文里说的!不是我说的)这个加权求和太过于“primitive”(原始)了…(真敢说啊,不愧是复旦的)
4.prediction layer:这个不多说,多层感知机后通过softmax输出,没有花头。
提出问题
问题上面也说了,主要是第三步:aggregation部分,pooling和self-attention都有各自的确定。所以引出了动态路由机制。
动态路由模型
我们手头很多句子,他们是不定长的,要做分类任务时,我一般都是设置一个max_len,然后做padding。现在的这个模型并没有这样做。
第一步:embedding,还是一样,每一个词用一个词向量来表示。
第二步:encoding,通过一个BILSTM。对于句子中每一个单词而言,它会得到前向的向量输出和后向的向量输出,两者拼接,得到单词的词向量表示:
第三步:dynamic routing!
细节模型图如下:
明确一些名词:
- h i h_i hi第i个词向量输入
- v j v_j vj第j个胶囊输出
- L:即有L个词( h i h_i hi)
- M:即有M个胶囊输出
- c i j c_{ij} cij决定了有多少信息从 h i h_{i} hi转移到 v j v_{j} vj
- b i j b_{ij} bij跟 c i j c_{ij} cij差不多,只是 b i j b_{ij} bij没有经过归一化
- m i j m_{ij} mij从 h i h_{i} hi转移到 v j v_{j} vj的信息量
我们已经有句子的序列表示了,如下:
在一轮迭代中,
h
1..
L
h_{1..L}
h1..L会依次作为输入。对于一个
h
i
h_i
hi输入,它会产生M个
m
i
j
m_{ij}
mij(j=1、2…M)这个M是我们自己定的。其中,
m
i
j
m_{ij}
mij表示为,从
h
i
h_i
hi转移到
v
j
v_j
vj的信息。也就是说,一个
h
i
h_i
hi,就会影响所有的
v
j
v_j
vj。
当所有的 h i h_i hi都输入以后,每一个 h i h_i hi对所有的 v j v_j vj的转移信息都有了。现在要更新所有的 v j v_j vj了。
对于一个
v
j
v_j
vj,我们有来自所有
h
i
h_i
hi的转移信息,
m
i
j
m_{ij}
mij(i=1、2…L)。将这L个m进行加和得到
s
j
s_j
sj
将这个
s
j
s_j
sj压缩到0-1的范围,进而更新
v
j
v_j
vj
其他的v的更新都类似。
总的来说,在一次迭代中,所有的输出
v
j
v_j
vj都会得到更新,每一个
v
j
v_j
vj更新之后,会反过来更新所有的
b
i
j
b_{ij}
bij
而
c
i
j
c_{ij}
cij进而也会得到更新,它只是
b
i
j
b_{ij}
bij的归一化:
对于
b
i
j
b_{ij}
bij矩阵的一行(第i行),
b
i
j
b_{ij}
bij(j=1…M)表示分别有多少信息从
h
i
h_i
hi转移到各个
v
j
v_j
vj,我们将这一行进行softmax,使得单个
h
i
h_i
hi转移到所有
v
j
v_j
vj的概率和为1.
以上是一次迭代,我们可以迭代任意次(更新任意次)。
反向动态路由模型
层次化动态路由模型
说白了就是两次(说的挺牛),但也不可否认思想的创新。我们手头的不再是句子,而是一个文章(document),我们可以将document分解成一个一个不等长的句子。
对于每个句子而言,步骤相同,embedding、encoding、dynamic routing 的 aggregating,最终将一个句子H = (
h
1
.
.
.
h
L
h_{1}...h_{L}
h1...hL)(每一个句子的L都不相等)转换成了一个固定长度的输出胶囊V=(
v
1
.
.
.
v
M
v_{1}...v_{M}
v1...vM)(这个M是我们自己定的,也就是说我们可以通过一层的动态路由,将所有的句子都转化为相同长度的表示。
每一个句子是不等长的,这依旧是句子层的问题;而现在是每一个document都有不同个数的句子。一个document里的所有句子都得到了这样的一个输出胶囊。现有n个句子,我们将n个输出胶囊进一步通过一个动态路由,这样就可以得到一个定长的最终表示。
使用层次化路由来表示document的优点是:
总结
这篇文章只是大致介绍了模型的细节,要想知道其他相关信息,还是去看论文吧。如果你觉得我讲的解决了你的疑惑,可以点一个赞,或者评论告诉我。如果我有哪里讲得不清楚,或讲错的,也请指出,谢谢啦。