我正在查看Caffe的代码Sigmoid 交叉熵损失层 https://github.com/BVLC/caffe/blob/master/src/caffe/layers/sigmoid_cross_entropy_loss_layer.cpp和docs http://caffe.berkeleyvision.org/doxygen/classcaffe_1_1SigmoidCrossEntropyLossLayer.html#details我有点困惑。文档将损失函数列为 logit 损失(我会在这里复制它,但如果没有 Latex,该公式将很难阅读。查看文档链接,它位于最顶部)。
然而,代码本身(Forward_cpu(...)
) 显示了不同的公式
Dtype loss = 0;
for (int i = 0; i < count; ++i) {
loss -= input_data[i] * (target[i] - (input_data[i] >= 0)) -
log(1 + exp(input_data[i] - 2 * input_data[i] * (input_data[i] >= 0)));
}
top[0]->mutable_cpu_data()[0] = loss / num;
是因为这考虑了 sigmoid 函数已经应用于输入吗?
然而,即便如此,(input_data[i] >= 0)
片段也让我感到困惑。这些似乎代替了文档中损失公式中的 p_hat,它应该是由 sigmoid 函数压缩的预测。那么为什么他们只采用二进制阈值呢?由于此损失预测 [0,1] 输出,因此变得更加混乱,因此(input_data[i] >= 0)
将是一个1
除非 100% 确定不是。
有人可以向我解释一下吗?
The SigmoidCrossEntropy
caffe 中的层结合了 2 个步骤(Sigmoid
+ CrossEntropy
)将执行input_data
到一段代码中:
Dtype loss = 0;
for (int i = 0; i < count; ++i) {
loss -= input_data[i] * (target[i] - (input_data[i] >= 0)) -
log(1 + exp(input_data[i] - 2 * input_data[i] * (input_data[i] >= 0)));
}
top[0]->mutable_cpu_data()[0] = loss / num;
事实上,无论是否input_data >= 0
无论是否,上面的代码在数学上总是等价于下面的代码:
Dtype loss = 0;
for (int i = 0; i < count; ++i) {
loss -= input_data[i] * (target[i] - 1) -
log(1 + exp(-input_data[i]);
}
top[0]->mutable_cpu_data()[0] = loss / num;
,此代码基于应用后的简单数学公式Sigmoid
and CrossEntropy
on input_data
并进行一些数学组合。
但是第一段代码(caffe使用)具有更高的数值稳定性,并且溢出的风险更小,因为它避免了计算大的exp(input_data)
(or exp(-input_data)
)当绝对值input_data
太大了。这就是您在 caffe 中看到该代码的原因。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)