zoukankan      html  css  js  c++  java
  • [code] Transformer For Summarization Source Code Reading [3]

    1. Label Smoothing

    对于分类问题,我们希望模型输出的标签上概率分布,逼近于真实标签的one-hot representation。带来的问题是:

    1. 无法保证泛化
    2. one-hot表示鼓励将真实类别和其他类别之间的差距尽可能拉大,造成模型过分相信预测的类别

    论文 When Does Label Smoothing Help? 中对label smoothing的数学描述:

    1. (多标签)交叉熵损失公式不变,源码中也有利用KL散度作为损失函数的,实际上最小化两种损失函数是等价的(多了一个常量,熵)
    2. 通常是利用真实y的one-hot representation预测y的概率分布进行交叉熵计算;label smoothing用smooth过的y,与预测y的概率分布进行交叉熵计算
    3. 常引入uniform distribution作为u(k),进行label smoothing

    引入一个与分布无关的u(k),可由先验概率充当,可以是均匀分布:

    其中有两步操作:

    1. 确定真实标签的Dirac分布,以及分布u(k)
    2. 以(1-epsilon),epsilon分别作为两者的权重进行加权求和

    对应代码实现:

    
    def label_smoothing(inputs, epsilon=0.1):
        K = inputs.get_shape().as_list()[-1]    # number of labels
        return ((1-epsilon) * inputs) + (epsilon / K)
    

    效果就是,将原本one-hot的表示变得不那么绝对化,分出了一些概率给其他标签,留个模型泛化的空间。由于其主要的作用是防止过拟合,在过拟合严重的训练情况下,可以考虑加入label smoothing

    2. Copy Mechanism

    本实现中用到的copy mechanism与类似论文 Get To The Point: Summarization with Pointer-Generator Networks 一致。

    Copy mechanism的流程:

    1. copy-mode:利用当前时间步的decoder-encoder attention weight来计算input article word list上概率分布的

    2. generate-mode:利用decoder hidden states、decoder input、decoder-encoder context三者,来计算fixed vocabulary上的概率分布

    3. gate:用于选择上述两种模式,利用decoder hidden states、decoder input、decoder-encoder context三者,来计算当前选择generate-mode的概率

    4. 计算联合概率(如下图):

    单词的属性有如下几种:

    1. fixed vocabulary V
    2. input word list X
    3. OOV (X - V)
    4. extended vocabulary X + V

    从上图可以看出如何计算单词的概率分布:

    X中单词的概率由copy mode计算(乘上权重),V中单词的概率由generate-mode计算(乘上权重),X∩V中的单词的概率是两种模式下的概率的加权和。其中权重由另外一个神经网络计算得到gate。

    原本我们只能得到fixed vocabulary中单词的概率分布,现在得到extend vocabulary上的概率分布(并且由于输入不同,X是动态的)。我们就可以解码输出在固定词表中没有出现,但是在输入此表中出现过的单词。

    如果在解码的时候,从X中拷贝了一个单词y,但是是属于X-V集合中,即OOV单词。因为只有V中的单词有embedding,所以y单词并没有embedding,那么下一时刻的解码输入应该如何处理?参考李丕绩前辈的实现:

    next_y = []
    for e in last_traces:
        eid = e[-1].item()
        if eid in modules["i2w"]:
            next_y.append(eid)
            else:
                next_y.append(modules["lfw_emb"]) # unk for copy mechanism
    

    如果当前解码时刻的输出是从input word list中拷贝出来的OOV word的数,那么下一时刻的解码输入,就是对应的embedding,但是当前输出就不是UNK了,而是copy的词。

    3. Recurrent Decoder?

    在没有看Transformer在sequence generation任务上的具体实现的时候,一直好奇Decoder如果也是auto-regressive的话,那么是不是也是recurrent的?

    在进行解码的时候(training 阶段使用teacher forcing,inference逐词输出),每次解码一个单词。在copy(pointer-generator network)机制下,当前decoder的输入如下:

    y_pred, attn_dist = model.decode(ys, tile_x_mask, None, tile_word_emb, tile_padding_mask, tile_x, max_ext_len)
    
    
    def decode(self, inp, mask_x, mask_y, src, src_padding_mask, xids=None, max_ext_len=None):
        	pass
        
    

    可以看出decoder的输入对应关系:

    1. 解码输入就是[seq_len, beam_width],其中seq_len是beam search已经得到的部分解码序列的长度

    2. 不对input_y进行mask,计算attention的时候,考虑全部的input_y序列中的元素;故mask_y=None

    3. src 是 tile_word_emb,输入序列的embedding,[max_x_len, beam_width, embedding_dim]

    4. src_padding_mask 是 tile_padding_mask,[max_x_len, beam_width]

    5. xid 是 tile_x,[max_x_len, beam_width]

      x = torch.tensor([1, 2, 3])
      
      x.shape
      Out[7]: torch.Size([3])
      x.repeat(4,2).shape
      Out[8]: torch.Size([4, 6])
      x.repeat(4,2,1).shape
      Out[9]: torch.Size([4, 2, 3])
      

      torch.Tensor.repeat函数,可以将指定维度进行复制。x的维度为[dx_0],x.repeat(dy_3, dy_2, dy_1, dy_0),需要先进行unsequeeze操作,将x的维度数目拓展到与repeat函数中的参数数目相同。再对应每个维度进行repeat。

    decoder内部需要进行基于解码输入的self-attention,以及基于编码输出的external attention,输出有二:

    1. y_dec 解码器的解码输出,形状为 [seq_y_len, beam_width, vocab_size]。
      通过y_pred = y_pred[-1, :, :] ,取最后一个隐含状态作为当前的解码输出。
    2. attn_dist 是 word_prob_layer 计算出的,external attention的注意力权重,形状为 [seq_y_len, beam_width, max_x_len]

    * Beam Search的Inference阶段,按照batch读取数据,进行编码,但是按照每个样本分别进行解码

    In a nutshell,这不算recurrent,但还是auto-regressive的解码模式。recurrent指的是,当前时刻的解码,接受来自上一时刻的隐含状态。而Transformer decoder在解码每一个词的时候,不仅考虑了前一个词,还考虑了之前已经生成了的所有单词,并且利用其进行self-attention计算。

    4. 参考资料

    1. 【Network】优化问题——Label Smoothing
    2. 【机器学习基础】熵、KL散度、交叉熵
    3. github repository: lipiji/TranSummar
  • 相关阅读:
    匿名变量
    Vue父子组件传值与非父子传值
    TCP三次握手分析
    @media screen 响应式布局
    H5新增多媒体标签
    npm+node+vue配置一套带走
    vue+echarts全国疫情地图
    js本地时间格式化
    vue iview分页
    Vue打包后访问静态资源路径问题
  • 原文地址:https://www.cnblogs.com/lauspectrum/p/11237421.html
Copyright © 2011-2022 走看看