为了使案例简单直观,我将使用二元分类(0和1)进行说明。
损失函数
loss = np.multiply(np.log(predY), Y) + np.multiply((1 - Y), np.log(1 - predY)) #cross entropycost = -np.sum(loss)/m #num of examples in batch is m
Y的概率
predY
使用sigmoid函数计算,logits
可以被认为是神经网络在达到分类步骤之前的输出
predY = sigmoid(logits) #binary casedef sigmoid(X): return 1/(1 + np.exp(-X))
问题
假设我们正在运行一个前馈网络。
输入: [3, 5]: 3是样本数,5是特征大小(虚构数据)
隐藏单元数: 100(只有1个隐藏层)
迭代次数: 10000
这样的设置是为了过拟合。当过拟合时,我们可以完美预测训练样本的概率;换句话说,sigmoid输出要么是1要么是0,因为指数会变得非常大。如果发生这种情况,我们会遇到np.log(0)
未定义的问题。你通常如何处理这个问题?
回答:
如果你不介意依赖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 == 1cost = -(np.log(predY[Yis1]).sum() + np.log(1 - predY[~Yis1]).sum())/m