CopyNet 个人理解
之前了解过seq2seq模型,最近因为一些原因想要深入了解下copyNet 和 pointNet 。我首先读了 《Incorporating Copying Mechanism in Sequence-to-Sequence Learning 》这篇比较经典的论文,接下来就简单介绍一下论文中模型的结构以及自己的一些理解。
简单来说,copyNet 还是属于seq2seq类型的模型,它也包含了encoder 和 decoder 两个部分。和比较经典的基于LSTM 或 RNN 的seq2seq 模型相比,他主要的区别是在copyNet 的decoder 部分 分为了 Generate-Mode 和 Copy-Mode,Generate-Mode 主要任务是根据语义来决定输出,而Copy-Mode 就是根据输入文本的位置来决定copy。并且在decoder过程中,上一个step的输出作为当前step输出的形式有所不同。
copyNet的优势是 能够比较好的处理 OOV 问题,比如人名、地名等等,因为他可以直接把这部分内容copy到输出中。论文中也使用copyNet 在文本摘要这个问题上进行了测试和评估。
上面这个图是copyNet 的整体架构,初次看这张图有点懵逼。但是读完之后,再去看这个图就感觉清晰明了。
1.Encoder
encoder部分和普通seq2seq并没有什么太大区别,在论文中使用了双向RNN,也就是上图中的左下角部分。RNN每个time_step的输入就是当前词的embedding 向量,至于embedding 是采用word2vec 还是 glov 或者随着模型进行训练,我觉得都可以,在图中直接用词来表示了,其实应该是词对应的词向量
ht
h
t
代表了RNN t 时刻(时刻就等于第几个词)的输出,所有的
ht
h
t
组成了M。M就包含了encoder 过程中每个时刻的输出。
另外,bi-RNN 最后的hidden-state
(1)中的 c c 代表了context vector ,是对enecodr所有时刻hiden state 的一个代表,也就是输入的整句话经过双向RNN映射到的向量空间的向量表示形式。比如可以取最后一个时刻的hidden state。所以encoder 部分的输出就是M矩阵和context vector 。
2.Decoder
- 传统RNN decoder
st=f(yt−1,st−1,c)(2)p(yt|y<t,X)=g(yt−1,st,c)(3) s t = f ( y t − 1 , s t − 1 , c ) ( 2 ) p ( y t | y < t , X ) = g ( y t − 1 , s t , c ) ( 3 )
yt−1
y
t
−
1
:t-1 时刻decoder 的输出。论文后面的
yt−1
y
t
−
1
有些不同
st−1
s
t
−
1
:t-1时刻 decoder 的状态,在这里不要与hidden state 混淆。
c
c
: encoder 部分提到的 context vector
:当前时刻decoder的状态,由
yt−1,st−1,c
y
t
−
1
,
s
t
−
1
,
c
计算得到。
(3)中的g(z)函数用来计算实际输出。能够看出,当前的state,上一个时刻的输出,以及context vector 决定了deocder 最终的输出。
- 词汇类别的划分
X
X
:出现在输入语句中的词汇
: embedding矩阵中包含的已知词汇
UNK
U
N
K
:unknown word,输入语句和已知词汇中都不包含的词汇
上图体现了copyNet 对不同种类词汇,计算score时的差异。
Copy-mode 负责计算出现在输入中的词汇(
X
X
)的score 。
Generate-mode 则负责计算其他词汇的score.
ψg
ψ
g
对于同时出现在
V
V
和中的词汇,就需要同时用两个mode来评估。
上面图中的公式展示了copy和generate mode 在做预测时的细节。
- Generate Mode
ψg(yt=vi)=vTiWost,vi∈ν∪UNK(7) ψ g ( y t = v i ) = v i T W o s t , v i ∈ ν ∪ U N K ( 7 )
generate Mode 主要根据原语句含义进行推断。 (7) ( 7 ) 中的 vTi v i T 为one-hot 向量,比如『你好』 这个词在词表 ν ν 中的index为3,则 vT你好={0,0,1,…,0} v 你 好 T = { 0 , 0 , 1 , … , 0 } .通过 ψg ψ g 可以得到已知词表和UNK的每个词的score.
Copy Mode
ψc(yt=xj)=σ(hTjWc)st,xj∈χ(8) ψ c ( y t = x j ) = σ ( h j T W c ) s t , x j ∈ χ ( 8 )
copy Mode 主要用来根据原语句的位置信息进行复制。 hTj h j T 是M矩阵中的第 j j 列 ,也就是 encoder RNN 中第个词(time step)对应的输出。 σ σ 是一个激活函数,论文中提到选用 tanh t a n h 效果比较好。这样得到的是原输入中 xj x j 这个词作为本时刻输出的score。
State Update (重点)
(7) ( 7 ) 和 (8) ( 8 ) 看起来只是针对不同类型词汇,在计算相应score的时候方式上有所差异。 χ χ 中的词我们用每个词本身以及decoder当前状态去计算该词可能作为输出的概率。而对于 ν ν 中的词则只用decoder 当前的状态 st s t 。为什么 st s t 可以即被用在copy-mode 也能被用在 generate-mode? 这和其更新方式有很大关系,简单来说, st s t 的更新依赖于 t−1 t − 1 时刻输出的词汇所属类别。下面根据论文公式解释一下。
论文中出现的t-1时刻的输出为 yt−1 y t − 1 ,这里的输出和我一般理解的输出不一样。一般来讲,最后的输出为 softmax(z) s o f t m a x ( z ) 。不精确的来讲这里指代的是 argmax(softmax(z)) a r g m a x ( s o f t m a x ( z ) ) ,之所以说不精确,是因为这里softmax要使用 copy-mode 和 generate-mode 两者logits 的累加。
yt−1 y t − 1 :t-1 时刻 输出,是一个词汇的index
论文对 yt−1 y t − 1 做了下面一些事情…..
首先论文对 yt−1 y t − 1 在上述基础上进行改动,并作用到state 更新上;
e 可以看作从embedding 矩阵获取词向量的操作。
ζ ζ 函数是copy-mode 和 genenrate 能作用的关键。先看定义
ζ ζ 是 M M 矩阵(encoder 每个时刻hidden state) 的带权重累加和。
权重 只在与 t−1 t − 1 时刻输出相同的输入词汇处有取值,其他均为0值。
也就是说,t-1时刻的输出如果不在输入词汇中,那么 ζ ζ 就会是个0向量,此时 yt−1 y t − 1 只包含输出的embedding 信息。
如果 t−1 t − 1 输出在输入词汇中,那么 ζ ζ 包含的应该是这些词在输入中的位置信息(RNN 本身序列特性,就会把一部分部分信息encoder 进来)。
在我个人看来,一旦 ζ ζ 有值或不为0向量,模型接下来的输出就极大的偏向copy-mode。 因为输出能在输入中找到,那么其后面的内容也很有可能应该copy。
有了 yt−1 y t − 1 结合公式(2),就能对 st s t 进行更新,然后采用词汇类别划分部分的方法进行预测。
总结
copyNet 重点是在对不同词汇类型分别进行不同的处理。
处理的不同主要体现在:
1.预测时(copy-mode,generate-mode)
2.更新 st s t 时 (针对上一时刻输出的不同)
3.其 ζ ζ 等同于对经典attention 的一个改动,在计算encoder 输出权重时,引入了词汇类别的概念。
2