language model with pointer network

1.什么是pointer network

在这里插入图片描述
       如上图所示, P 1 , P 2 , P 3 , P 4 P_1,P_2,P_3,P_4 P1,P2,P3,P4的坐标分别为( x 1 , y 1 x_1,y_1 x1,y1),( x 2 , y 2 x_2,y_2 x2,y2),( x 3 , y 3 x_3,y_3 x3,y3),( x 4 , y 4 x_4,y_4 x4,y4),我们想从这些点中找出几个点,这几个点的坐标连起来后,能涵盖所有点。
       以上面这幅图为例,将各个点的坐标输入encoder后,decoder依次输出1、4、2、1。 P 1 , P 4 , P 2 P_1,P_4,P_2 P1,P4,P2连起来的点正好是我们想要的结果。
       pointer network具体是如何工作的:

在这里插入图片描述
       pointer是指针的意思
       step1:
在这里插入图片描述
decoder的第一个cell输入encoder的结果以及begin(本例中为"→")后,输出一个和encoder的cell数相同(4)的向量,各个元素的大小代表了这四个点的权重,假设为(0.5,0.1,0.3,0.1),那么 P 1 P_1 P1的权重最大,指针就指向 P 1 P_1 P1
       step2
在这里插入图片描述
       decoder的第二个cell输入第一个cell的结果以及 P 1 P_1 P1(因为pointer第一个指向的是 P 1 P_1 P1)的坐标后,同样输出一个包含4个元素的向量(0.1,0.2,0.1,0.6), P 4 P_4 P4的权重最大,所以指针指向 P 4 P_4 P4
       后面的步骤都是一样,直到输出end(本例中为"←")。
       可以看出,pointer network的最后的输出( P 1 , P 4 , P 2 P_1,P_4,P_2 P1,P4,P2),都来自最开始的输入( P 1 , P 2 , P 3 , P 4 P_1,P_2,P_3,P_4 P1,P2,P3,P4),即相当于把部分输入信息copy到输出。

2.OOV问题

       OOV问题(Out Of Vocablaury)指,词典不够大,不能涵盖source中的所有单词。一般我们创建词典的时候,都是选择出现频率较高的词,比如经过分词,一共有2.1万个单词,选择出现频率最高的2万个单词建立vocab,那1000个出现频率较低的词就属于OOV,虽然在输入神经网络前会给这部分低频词统一赋一个’'的编码,但是这多多少少会影响模型整体效果,因为这部分单词全部用来表示了,信息有所丢失。
       一个处理该问题的思想就是:直接把这个低频词从输入copy到输出,那么信息就不会丢失了。
       那么pointer network就可以完成copy这个步骤。

3. LM with pointer network

       假设我们现在要做一个总结摘要的工作,比如输入“Germany emerge victorious 2-0 win against Argentina on Saturday”,我们希望输出“Germany beat Argentina”.

3.1 传统的seq2seq with attention:

在这里插入图片描述
       decoder中’Germany’的hid + encoder的output → context
       context + decoder中’Germany’的hid → vocab distribution(即右上角绿色的部分)
       vocab distribution是一个长度为vocab size的向量,每个元素代表了vocab中对应单词的权重,此时代表"beat"的那个元素的权重最大,所以这个cell的结果应该就是"beat".

3.2 LM with pointer net work

在这里插入图片描述
       从vocab distribution中可以看出,vocab中的词汇为’a’一直到‘zoo’,所以source text中的‘2-0’在vocab中是以‘unk’存在的,虽然在本例最后的输出中不涉及‘2-0’,但是我们还是希望这个信息在输出部分(final distribution)有所体现。
       因此我们可以在上述传统模型中加入pointer network。
        P g P_g Pg代表传统模型输出的vocab distribution,也就是final distribution中的绿色部分;
        P c P_c Pc代表pointer network输出的distribution,也就是final distribution中的蓝色部分。
       参照第一节中我们介绍的pointer network的具体工作流程,我们知道,我们使用pointer network就是想知道source text中每个单词的权重,哪个单词的权重最大就copy哪个单词。而attention机制中的attention distribution正好代表了source text中每个单词的权重,所以我们可以直接用attention distribution表示 P c P_c Pc.
       因此整个的思路如下:
       1.decoder中’Germany’的hid + encoder的output → Attention distribution(即 P c P_c Pc)
       2.encoder中每个cell的输出以attention distribution做weight进行加权平均得到context
       3.decoder中’Germany’的hid + context → vocab distribution(即 P g P_g Pg)
       4.decoder中’Germany’的hid + context → P g e n P_{gen} Pgen( P g e n P_{gen} Pgen是一个scalar)
       5. P g e n ∗ P g + ( 1 − P g e n ) ∗ P c P_{gen}*P_g+(1-P_{gen})*P_c PgenPg+(1Pgen)Pc 得到final distribution
       从最后的final distribution中可以看出,‘2-0’虽然没有在 P g P_g Pg(绿色部分)中体现,但是在 P c P_c Pc中得到了体现(图片放大看,‘zoo’后面那个单词就是‘2-0’)

4.pytorch代码实现LM with pointer network

def get_final_distribution( x, p_gen, p_vocab, attention_weights,batch_oov_num):

        batch_size = x.size()[0]
        p_gen = torch.clamp(p_gen, 0.001, 0.999)
        p_vocab_weighted = p_gen * p_vocab

        attention_weighted = (1 - p_gen) * attention_weights
        # attention_weighted表示source中每个单词的权重,size为(b,seq_len) 可以看成有b个句子,每个句子长度为seq_len
        # 比如(2,5),第一行为[[0.4,0.1,0.2,0.1,0.2]] 就表示第一句中各个单词的权重分别为0.4,0.1 ...

        extension = torch.zeros((batch_size,batch_oov_num)).float()
        p_vocab_extended = torch.cat([p_vocab_weighted, extension], dim=1)
        final_distribution = p_vocab_extended.scatter_add_(dim=1,index=x,src=attention_weighted)
        # final_distribution的size为(batch_size,vocab_size+batch_oov_num)

        return final_distribution


vocab = {'pad':0
        ,'unk':1
        ,'wyb':2
        ,'and':3
        ,'xz':4
        ,'are':5
        ,'good':6
        ,'friends':7}

seq1 = 'wyb and xz are actors' # => [2,3,4,5,1,0]
seq2 = 'wyb and xz are dedicated actors' # => [2,3,4,5,1,1]

batch_size = 2
seq_len = 6
vocab_size = 8

x = torch.tensor([[2,3,4,5,8,0],[2,3,4,5,9,8]]) # 8代表‘actors’,9代表‘dedicated’
p_gen = torch.rand((batch_size,1))
p_vocab = torch.rand((batch_size,vocab_size))
attention_weights = torch.rand((batch_size,seq_len))
batch_oov_num = 2 # actors和dedicated这两个单词

final_distribution = get_final_distribution(x, p_gen, p_vocab, attention_weights,batch_oov_num)

final_distribution
tensor([[0.5410, 0.0142, 0.2903, 0.8483, 0.7934, 0.5476, 0.0270, 0.0879, 0.7804,0.0000],
        [0.0525, 0.2674, 0.7799, 0.8531, 0.6568, 0.6961, 0.1096, 0.0833, 0.2051,0.2947]])

       0.7804就表示第一个句子该cell输出的结果为‘actors’的概率为0.7804(相对概率,还没经过softmax处理)
       0.2051表示第二个句子该cell输出的结果为‘actors’的概率为0.2051,0.2947表示第二个句子该cell输出的结果为‘dedicate’的概率为0.2947。

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值