mar*_*man 6 c++ neural-network deep-learning caffe
我正在查看Caffe的SigmoidCrossEntropyLoss图层 和文档的代码,我有点困惑.文档将损失函数列为logit loss(我在这里复制它,但是没有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;
Run Code Online (Sandbox Code Playgroud)
是因为这是因为已经应用于输入的sigmoid函数?
然而,即便如此,这些(input_data[i] >= 0)片段也让我感到困惑.那些似乎代替了文档中损失公式的p_hat,这应该是由sigmoid函数压缩的预测.那么为什么他们只是采取二进制阈值?由于这种损失会预测[0,1]输出,所以它(input_data[i] >= 0)会变得更加混乱,因此1除非100%确定它不是,否则它将是一个输出.
有人可以向我解释一下吗?
SigmoidCrossEntropycaffe中的图层将两个步骤(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;
Run Code Online (Sandbox Code Playgroud)
实际上,无论是否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;
Run Code Online (Sandbox Code Playgroud)
,这个代码基于简单的数学公式,在应用Sigmoid和CrossEntropy开始input_data并在数学中进行一些组合之后.
但是第一段代码(caffe使用)拥有更多的数值稳定性并且减少了溢出的风险,因为它避免了在绝对值太大时计算大exp(input_data)(或exp(-input_data))input_data.这就是你在caffe中看到代码的原因.