【问题标题】:How to handle log(0) when using cross entropy使用交叉熵时如何处理 log(0)
【发布时间】:2018-10-05 17:09:55
【问题描述】:

为了使案例简单直观,我将使用二进制(0和1)分类进行说明。

损失函数

loss = np.multiply(np.log(predY), Y) + np.multiply((1 - Y), np.log(1 - predY)) #cross entropy
cost = -np.sum(loss)/m #num of examples in batch is m

Y的概率

predY 是使用 sigmoid 计算的,logits 可以被认为是到达分类步骤之前神经网络的结果

predY = sigmoid(logits) #binary case

def sigmoid(X):
    return 1/(1 + np.exp(-X))

问题

假设我们正在运行一个前馈网络。

输入:[3, 5]:3 是示例数,5 是特征大小(制造数据)

隐藏单元数:100(只有 1 个隐藏层)

迭代次数:10000

这样的安排被设置为过拟合。当它过拟合时,我们可以完美地预测训练样本的概率;换句话说,sigmoid 输出 1 或 0,精确的数字,因为指数会爆炸。如果是这种情况,我们将有 np.log(0)undefined。您通常如何处理这个问题?

【问题讨论】:

  • 对于二元分类,Y 是否只包含值 0 和 1?
  • @WarrenWeckesser 正确。

标签: numpy machine-learning deep-learning


【解决方案1】:

如果你不介意对 scipy 的依赖,可以使用scipy.special.xlogy。您将替换表达式

np.multiply(np.log(predY), Y) + np.multiply((1 - Y), np.log(1 - predY))

xlogy(Y, predY) + xlogy(1 - Y, 1 - predY)

如果您希望 predY 包含非常小的值,则在第二项中使用 scipy.special.xlog1py 可能会获得更好的数值结果:

xlogy(Y, predY) + xlog1py(1 - Y, -predY)

或者,知道Y 中的值是0 或1,您可以用完全不同的方式计算成本:

Yis1 = Y == 1
cost = -(np.log(predY[Yis1]).sum() + np.log(1 - predY[~Yis1]).sum())/m

【讨论】:

  • 事实上 tensorflow 确实提供了它自己的函数版本为tf.math.xlogy。也许它是新的,但在发布此答案时并未添加。
【解决方案2】:

处理 log(x) 和 y / x 的一种常用方法是添加一个小常数(如 Jakub 所写),其中 x 始终为非负但可以变为 0。 p>

您还可以剪辑值(例如tf.clip_by_valuenp.clip)。

【讨论】:

    【解决方案3】:

    您通常如何处理这个问题?

    predY 中添加一个小数字(例如 1e-15) - 这个数字不会使预测产生太大影响,它解决了 log(0) 问题。

    顺便说一句,如果您的算法输出 0 和 1,检查返回概率的直方图可能很有用 - 当算法确定某事正在发生时,它可能是过度拟合的迹象。

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-07-13
      • 2020-01-03
      • 2020-10-09
      • 2016-12-06
      • 2017-03-04
      • 2021-02-15
      相关资源
      最近更新 更多