Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A question in crf.py #365

Closed
tyistyler opened this issue Apr 25, 2021 · 5 comments
Closed

A question in crf.py #365

tyistyler opened this issue Apr 25, 2021 · 5 comments

Comments

@tyistyler
Copy link

tyistyler commented Apr 25, 2021

您好,我发现在decoder的crf.py的代码中,第263行是这样写的
score = trans_score + emit_score[:seq_len - 1, :]
其中的trans_score大小为[seq_len-1, batch_size],trans_score[0][0]代表第0个句子的第0个字符到第1个字符的转移得分
而emit_score[:seq_len - 1, :]的大小为[seq_len-1, batch_size],emit_score[0, 0]代表第0个句子第0个字符的发射得分
但是第0个句子第0个字符的转移得分不应该是start字符到第0个字符的score么?请问这里为什么不写成
score = trans_score + emit_score[1:, :]
感谢您的解答~

@yhcc
Copy link
Member

yhcc commented Apr 26, 2021

start字符和end字符的分数是单独通过start_scores和end_scores来计算的,因为在include_start_end_trans参数为False的时候,我们不考虑start和end字符,如果采用您说的这种方式,实现这个比较麻烦。所以我们就把start和end的分数计算从trans_scores中单独分离出来了。

@tyistyler
Copy link
Author

tyistyler commented Apr 26, 2021

谢谢您的回复。
可能是我没有表述清楚问题,
score = trans_score + emit_score[:seq_len - 1, :]
trans_score[0][0]代表第0个句子的第0个字符到第1个字符的转移得分
emit_score[0][0] 代表第0个句子的第0个字符的发射得分
二者相加时,我感觉十分困惑,因为trans_score[0][0]我理解的是第1个字符的转移得分(从位置为0的字符转移到位置为1的字符),将二者相加时,感觉错位了,将0号字符的发射得分与1号字符的转移得分进行了相加,但是第264行的score.sum(0)加法缓解了这个问题。
我个人的看法是,将263和264行的
score = trans_score + emit_score[:seq_len - 1, :]
score = score.sum(0) + emit_score[-1].masked_fill(flip_mask[-1], 0)

替换为
score_new = trans_score + emit_score[1:, :]
score_new = score1.sum(0) + emit_score[0]
是否更好理解?(二者的结果,我用两个例子验证了一下,是相同的)

@yhcc
Copy link
Member

yhcc commented Apr 27, 2021

感觉没有错位。这里应该是由于有两种不同的视角造成的,第一个视角是(我们的实现):[第i个字符的发射分数+第i个字符转移到第1个字符的分数]来得到第i个字符的分数,然后sum所有的i,这种做法会在最后一个时刻无法计算,因为最后一个时刻不再有i+1的跳转分数。第二个视角是(您的做法),就是[第i个字符的发射分数+(第i+1个字符的分数+第i个字符跳转到第i+1个字符的分数)],但实作的时候是通过把第0个单独拿出来(也就是您做法里面的emit_score[0]),然后sum所有的第i+1个字符的分数+第i个字符跳转到第i+1个字符的分数。这两种应该是等价的。

@choosewhatulike
Copy link
Member

补充一下 @yhcc 的回答。对于一个长度为N的序列,有 N 个发射分数和 N-1 个转移分数 (N个点和中间N-1条边)。而我们求的 score 其实就是这些分数求和。因为是求和,所以先加谁后加谁都是可以的。您这里使用另一种方式实现了这个求和,理论上可以有很多种实现方式,都是等价的。

@tyistyler
Copy link
Author

感谢您的解答

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants