如何为空白令牌预测计算变压器损失?

问题描述

我目前正在尝试实现一个变压器,但无法理解其损耗计算。

我的编码器输入查找 batch_size=1 和 max_sentence_length=8 如下:

handleChange(evt) {
    const value = evt.target.type === "checkBox" ? evt.target.checked : evt.target.value;
    this.setState({
      [evt.target.name]: value
    });
  }

我的解码器输入看起来像(德语到英语):

[[Das,Wetter,ist,gut,<blank>,<blank>]]

假设我的转换器预测了这些类别概率(仅显示类别概率最高的类别的单词):

[[<start>,The,weather,is,good,<end>,<blank>]]

现在我使用以下方法计算损失:

[[The,<blank>]]

这是计算损失的正确方法吗?我的转换器总是预测下一个单词的空白标记,我认为这是因为我的损失计算有误,在计算损失之前必须对空白标记做一些事情。

解决方法

您需要屏蔽填充。 (你所说的 <blank> 更常被称为 <pad>。)

  • 创建一个掩码,说明有效令牌的位置(伪代码:mask = target != '<pad>')

  • 计算分类交叉熵时,不要自动减少损失并保持值。

  • 将损失值与掩码相乘,即对应于 <blank> 代币的头寸归零并在有效头寸处的损失相加。 (伪代码:loss_sum = (loss * mask).sum()

  • loss_sum除以有效位置的个数,即掩码的总和(伪代码:loss = loss_sum / mask.sum()