2017-01-23 1 views
2

мне нужно помощь в понимании функции Caffe, SigmoidCrossEntropyLossLayer, который является кросс-энтропия ошибки логистической активации.Нужна помощь понимания кода 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 here.

Вопрос заключается в том, как выше переводятся на потери вычислительного код ниже:

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_; 
    } 
+0

Это сообщение http://stackoverflow.com/q/40353672/6281477 может вам помочь. – Dale

+0

Спасибо. Теперь я думаю, что input_data имеет диапазон [-inf, + inf], и в этом случае я вижу сценарий переполнения. Это верно? Раньше я думал, что input_data имеет диапазон [0,1]. Теперь я понимаю, input_data не прошла через сигмоидальную активацию, чтобы связать ее с [0,1]. – auro

+0

@auro это правильно. сигмоидная активация является частью этого слоя. – Shai

ответ

2

В выражении log(1 + exp(x[i])) вы можете столкнуться числовую нестабильность в случае x[i] очень велико. Чтобы преодолеть эту числовую нестабильность, один масштабирует функцию сигмовидной так:

sig(x) = exp(x)/(1+exp(x)) 
     = [exp(x)*exp(-x(x>=0))]/[(1+exp(x))*exp(-x(x>=0))] 

Теперь, если вы подключите новое и стабильное выражение для sig(x) в убыток вы будете в конечном итоге с тем же выражением, как CAFFE используется.

Наслаждайтесь!

Смежные вопросы