赞
踩
一篇19年的微软论文,老规矩先放论文链接:https://arxiv.org/abs/1905.03197
最近开始尝试做长文本的摘要生成任务,因此要拿出了几篇 Transformer 时代的文本生成相关的经典论文参考。当我看到UniLM这个Bert的变体模型(甚至连变体都算不上),口中只能叹出,“相见恨晚” 四个字。接着回顾了之前辛苦辛苦手敲的LSTM+Attention的seq2seq模型,脸上浮现出了嫌弃的表情。文本生成在Self-Attention的加持下从未如此简单。
这里只阐述论文的关键思路,具体细节还是看论文来的实在啦~
Tensorflow-GPU 2.0.0
Transformers 3.1.0
def unilm_mask_single(s): ''' s = np.array([0,0,0,0,1,1,1,0,0,0]) unilm_mask_single(s) = <tf.Tensor: shape=(10, 10), dtype=float32, numpy= array([[1., 1., 1., 1., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 0., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 1., 0., 0., 0., 0., 0.], [1., 1., 1., 1., 1., 1., 0., 0., 0., 0.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]], dtype=float32)> ''' idxs = K.cumsum(s, axis=0) mask = idxs[None, :] <= idxs[:, None] mask = K.cast(mask, K.floatx()) return mask ids = np.zeros((self.batch_size,self.Max_len),dtype='int32') seg_id = np.zeros((self.batch_size,self.Max_len),dtype='int32') mask_att = np.zeros((self.batch_size,self.Max_len,self.Max_len),dtype='int32') input_dict = self.tokenizer(content,title,max_length=self.Max_len,truncation=True,padding=True) len_ = len(input_dict['input_ids']) token_ids = input_dict['input_ids'] segment_ids = input_dict['token_type_ids'] ids[index][:len_] = token_ids seg_id[index][:len_] = segment_ids mask_id = unilm_mask_single(seg_id[index]) mask_att[index] = mask_id
class TFBertMainLayer(tf.keras.layers.Layer):
def call(……)
if len(attention_mask.shape) == 2:
extended_attention_mask = attention_mask[:, tf.newaxis, tf.newaxis, :]
elif len(attention_mask.shape) == 3:
extended_attention_mask = attention_mask[:, tf.newaxis, :, :]
else:
raise NotImplementedError
extended_attention_mask = tf.cast(extended_attention_mask, embedding_output.dtype)
extended_attention_mask = (1.0 - extended_attention_mask) * -10000.0
数据处理部分只需要将新闻文本和标题同时传给BertTokenizer实例,并通过返回的Segment_id构建attention_mask矩阵即可。
class Loss(tf.keras.layers.Layer): """特殊的层,用来定义复杂loss """ def __init__(self, output_axis=None, **kwargs): super(Loss, self).__init__(**kwargs) self.output_axis = output_axis def call(self, inputs, mask=None): loss = self.compute_loss(inputs, mask) self.add_loss(loss) if self.output_axis is None: return inputs elif isinstance(self.output_axis, list): return [inputs[i] for i in self.output_axis] else: return inputs[self.output_axis] def compute_loss(self, inputs, mask=None): raise NotImplementedError class CrossEntropy(Loss): """交叉熵作为loss,并mask掉输入部分 """ def compute_loss(self
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。