【问题标题】:Intuition behind categorical cross entropy分类交叉熵背后的直觉
【发布时间】:2021-04-21 21:07:15
【问题描述】:

我正在尝试制作分类交叉熵损失函数,以更好地理解其背后的直觉。 到目前为止,我的实现如下所示:

# Observations
y_true = np.array([[0, 1, 0], [0, 0, 1]])
y_pred = np.array([[0.05, 0.95, 0.05], [0.1, 0.8, 0.1]])

# Loss calculations
def categorical_loss():
  loss1 = -(0.0 * np.log(0.05) + 1.0 * np.log(0.95) + 0 * np.log(0.05))
  loss2 = -(0.0 * np.log(0.1) + 0.0 * np.log(0.8) + 1.0 * np.log(0.1))
  loss = (loss1 + loss2) / 2 # divided by 2 because y_true and y_pred have 2 observations and 3 classes
  return loss

# Show loss
print(categorical_loss()) # 1.176939193690798

但是我不明白函数在以下情况下应该如何返回正确的值:

  • y_pred 中至少有一个数字是01,因为log 函数返回-inf0 以及在这种情况下代码实现的样子
  • y_true 中至少有一个数字是0,因为乘以0 总是返回0,然后np.log(0.95) 的值将被丢弃,以及在这种情况下代码实现应该是什么样子李>

【问题讨论】:

    标签: python numpy machine-learning cross-entropy


    【解决方案1】:

    关于y_pred 为0 或1,挖掘binary_crossentropycategorical_crossentropy 的Keras 后端源代码,我们得到:

    def binary_crossentropy(target, output, from_logits=False):
        if not from_logits:
            output = np.clip(output, 1e-7, 1 - 1e-7)
            output = np.log(output / (1 - output))
        return (target * -np.log(sigmoid(output)) +
                (1 - target) * -np.log(1 - sigmoid(output)))
    
    
    def categorical_crossentropy(target, output, from_logits=False):
        if from_logits:
            output = softmax(output)
        else:
            output /= output.sum(axis=-1, keepdims=True)
        output = np.clip(output, 1e-7, 1 - 1e-7)
        return np.sum(target * -np.log(output), axis=-1, keepdims=False)
    

    您可以清楚地看到,在这两个函数中,output 都有一个剪裁操作(即预测),以避免对数的无穷大:

    output = np.clip(output, 1e-7, 1 - 1e-7)
    

    因此,这里的y_pred 在基础计算中永远不会正好是 0 或 1。其他框架的处理方式类似。

    y_true 为 0,不涉及任何问题 - 相应的术语设置为 0,因为它们应该根据数学定义。

    【讨论】:

      猜你喜欢
      • 2020-01-03
      • 2019-07-13
      • 2021-07-17
      • 2021-03-19
      • 2018-11-03
      • 2019-12-18
      • 2021-02-15
      • 2021-03-19
      • 2018-12-23
      相关资源
      最近更新 更多