科大讯飞2020事件抽取比赛http://challenge.xfyun.cn/topic/info?type=hotspot
-
加上query并padding成相同长度
[CLS] + query + [SEP] + context + [SEP]
(bsz, seq_len)
-
通过bert来做encoding
encode-rep (bsz,seq, bertdim)
-
通过线性层来得到,每一个token的是否是(start/end)的表示
也就是对每一个 字 做一次二分类 判断其是否为 start
自然我们还要有另一个二分类,来判断其是否为 end
所以一个字其实是通过了两个二分类
start_logits = self.start_layer(encoder_rep) # (bsz, seq, 2) end_logits = self.end_layer(encoder_rep) # (bsz, seq, 2) start_prob_seq = paddle.nn.functional.softmax(start_logits, axis=-1) # (bsz, seq, 2) end_prob_seq = paddle.nn.functional.softmax(end_logits, axis=-1) # (bsz, seq, 2)
axis = -1 等价于与 axis = 2 及对最后一个维度,做softmax
-
将start和end组合,这里他是有bug的
span1_logits = self.span1_layer(encoder_rep) # (bsz, seq, 1) span2_logits = paddle.squeeze(self.span2_layer(encoder_rep)) # (bsz, seq) span_logits = paddle.tile(span1_logits,repeat_times=[1, 1, seq_len]) + paddle.tile(span2_logits[:, None, :],repeat_times=[1, seq_len, 1]) # -1e30 是为了给在 span_mask 之外的猜测一个极小的 概率 (再通过softmax之后) span_logits = util.masked_fill(span_logits,span_mask==0,-1e30) # span_mask是一个上三角矩阵(上三角全为1) span_prob = paddle.nn.functional.softmax(span_logits,axis=1) # (bsz,seq,seq)
也就是说他这里用 span_prob 的下标来存储 了 start index和 end index (有点像邻接矩阵)
-
输入是 context 以及 start_prob_seq, end_prob_seq (bsz,seq,2) 以及 span_prob
-
先找出所有被判别为开始和结束的位置索引
-
然后 遍历 每一个 判断为end的索引
对于 每一个 end,找到所有在之前的S
-
对于一个 end 和 所有在其的之前的 S,通过 span_prob 找出最佳的 S
max_s = 0.0 t = None # 找出其中能使得发生概率最大的 S for i in s: if p_seq[i, e] > max_s: t = (i, e) max_s = p_seq[i, e] cur_end = e if t is not None: ans_index.append(t)
这个t就是找到的一个 trigger word了
-
加上query并padding成相同长度
[CLS] + query + [SEP] + context + [SEP]
(bsz, seq_len)
query = "处于位置&%d&和位置-%d-之间的触发词*%s*的%s为?" % (start, end, trigger, self.arg_map[arg])
-
通过bert来做encoding
encode-rep (bsz,seq, bertdim) cls_rep (bsz, dim)
-
cls_rep 过一个线性层变成 cls_logits (bsz,2)
-
让后通过两个 seq_len分类器,给每个token,分配其为start/end的概率
start_logits = self.start_layer(encoder_rep).squeeze(axis=-1) # (bsz, seq) end_logits = self.end_layer(encoder_rep).squeeze(axis=-1) # (bsz, seq) start_prob_seq = paddle.nn.functional.softmax(start_logits, axis=1) end_prob_seq = paddle.nn.functional.softmax(end_logits, axis=1)
start_prob_seq, end_prob_seq (bsz,seq)
-
最后返回 cls_logits (bsz,2), start_prob_seq, end_prob_seq (bsz,seq)
- 输入 cls_logits, start_prob_seq, end_prob_seq
- 通过 cls_logits 判断是否存在该类型轮元
- 如果存在该类型argument 找到一组符合 s < e 且使得 s_prob[s] + e_prob[e]最大 的 s,e组合进行返回,作为论元
transformer在paddle中是在 paddlenlp这个特殊的包中 https://paddlenlp.readthedocs.io/
而pytorch一般采用huggingface的 https://huggingface.co/docs/transformers/installation#install-with-condax
RobertaModel 传参 attention_mask 后会报错 换成bert 即可避免
好像所有的都有这个问题,只能不传attention—mask了