920232796 / bert_seq2seq

pytorch实现 Bert 做seq2seq任务,使用unilm方案,现在也可以做自动摘要,文本分类,情感分析,NER,词性标注等任务,支持t5模型,支持GPT2进行文章续写。
Apache License 2.0
1.28k stars 208 forks source link

咨询下文本生成的几个细节 #27

Open renjunxiang opened 3 years ago

renjunxiang commented 3 years ago

非常感谢您开源这个项目,让我学习了bert做文本生成的思想方法,还有几个问题想请教一下。

1.训练的数据的生成,一种是文本对[cls] source [sep] target [eos] [sep],另一种是拼在一起[cls] source target [eos] [sep],您认为这两种那种更合理呢?我倾向前者

2.预测下一个字符,是采用[cls]的分类吗。比如输入1234,我要预测 5678,[cls] 1 2 3 4 [sep] 5 6 [sep],是[cls]预测 7 吗?还是6这个位置的tensor预测7?

3.我看了前面的issue,如果只做文本生成,重点应该是target,训练的时候没必要计算source 的loss吧,应该是只需要对target位置进行attention mask然后计算target部分的loss就可以了吧。

4.Seq2SeqModel中的forward函数我看到了tril下三角函数,还有修改了BertModel中的extended_attention_mask。训练过程中,source =1234,target = 5678。传进去12345678,是可以一次自动mask5678后面位置字符,一起预测概率计算损失;还是要手动处理做四次不同的mask,1234mmmm->5、12345mmm->6、123456mm->7、1234567m->8

感谢您的解答!

920232796 commented 3 years ago
  1. 前者
  2. 6预测7
  3. 一次mask
renjunxiang commented 3 years ago

非常感谢您的解答。 由于transformer更新了,我看最新的代码,BERT支持mask三维输入[batch_size, from_seq_length, to_seq_length]. 但是我遇到一个问题,不知道我的用法对不对,您有空的话希望能解答一下。

text=['[CLS]', '我', '爱', '北', '京']
attention_mask = [[[1., 0., 0., 0., 0.],
                   [1., 1., 0., 0., 0.],
                   [1., 1., 1., 0., 0.],
                   [1., 1., 1., 1., 0.],
                   [1., 1., 1., 1., 1.]]]

输出 tensor([ 0.4774, -0.2218, -0.7759, 0.4029]) tensor([ 0.3816, -0.7229, 0.2674, -0.9279]) tensor([ 0.9864, -0.1028, -0.4651, -0.6575]) tensor([ 0.3494, -0.0724, -0.0241, 0.2510]) tensor([ 0.6949, -0.5249, -0.1485, -0.1998])

text=['[CLS]', '我', '爱', '北', '京']
attention_mask = [[[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.]]]

输出 tensor([-0.3266, -0.0141, 0.2546, 0.4039]) tensor([ 0.3885, -0.4314, 1.6947, -0.7774]) tensor([ 0.4243, 0.1053, -0.1677, -0.8712]) tensor([-0.5455, 0.4176, 0.5948, 0.4746]) tensor([-0.1268, -0.2284, -0.3128, -0.2293]) 最后'京'位置的tensor是否应该一样?按道理这里都是[1., 1., 1., 1., 1.]的mask。还是说前面屏蔽后面位置计算,也会影响到后面的词语?我这里前后'京'的tensor并不一样

感谢您的解答

920232796 commented 3 years ago

使用eval了么,没用的话 每次输出肯定是不一样的。

renjunxiang commented 3 years ago

我知道了,刚才逐层dubug发现,第一个BertSelfAttention输出的最后一个字符tensor是一样的。 但是因为前面的字符attention_mask不一样,导致前面四个字符的向量不同。后面再次走BertSelfAttention的时候,hiddenstate肯定不同,导致注意力权重和分数在2-12层BertSelfAttention的输出发生变化。

920232796 commented 3 years ago

ok

renjunxiang commented 3 years ago

比如说: 第一层 [1,2,3,4,5]->[1.1,2.1,3.1,4.1,5] [1,2,3,4,5]->[1,2,3,4,5] 第二层 [1.1,2.1,3.1,4.1,5]->[1.2,2.2,3.2,4.2,5.1] [1,2,3,4,5]->[1,2,3,4,5] 我这样的理解应该对吧。所以说就算是文本生成,在训练的时候 [cls] source [sep] target [sep]中,是否对source也执行下三角mask同样会对target的效果造成影响,因为attention会逐层叠加。

920232796 commented 3 years ago

是的