我需要帮助来理解 Caffe 函数,SigmoidCrossEntropyLossLayer
它是逻辑激活的交叉熵误差。
基本上,具有 N 个独立目标的单个示例的交叉熵误差表示为:
- sum-over-N( t[i] * log(x[i]) + (1 - t[i]) * log(1 - x[i] )
其中t
是目标,0 或 1,x
是输出,由 索引i
。x
,当然要经过逻辑激活。
用于更快交叉熵计算的代数技巧将计算减少到:
-t[i] * x[i] + log(1 + exp(x[i]))
您可以从此处的第 3 节验证这一点。
问题是,如何将上面的代码转换为下面的损失计算代码:
loss -= input_data[i] * (target[i] - (input_data[i] >= 0)) -
log(1 + exp(input_data[i] - 2 * input_data[i] * (input_data[i] >= 0)));
谢谢你。
为方便起见,将功能复制如下。
template <typename Dtype>
void SigmoidCrossEntropyLossLayer<Dtype>::Forward_cpu(
const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
// The forward pass computes the sigmoid outputs.
sigmoid_bottom_vec_[0] = bottom[0];
sigmoid_layer_->Forward(sigmoid_bottom_vec_, sigmoid_top_vec_);
// Compute the loss (negative log likelihood)
// Stable version of loss computation from input data
const Dtype* input_data = bottom[0]->cpu_data();
const Dtype* target = bottom[1]->cpu_data();
int valid_count = 0;
Dtype loss = 0;
for (int i = 0; i < bottom[0]->count(); ++i) {
const int target_value = static_cast<int>(target[i]);
if (has_ignore_label_ && target_value == ignore_label_) {
continue;
}
loss -= input_data[i] * (target[i] - (input_data[i] >= 0)) -
log(1 + exp(input_data[i] - 2 * input_data[i] * (input_data[i] >= 0)));
++valid_count;
}
normalizer_ = get_normalizer(normalization_, valid_count);
top[0]->mutable_cpu_data()[0] = loss / normalizer_;
}