2017-01-23 1 views
2

私はCaffe関数の理解に助けが必要です。SigmoidCrossEntropyLossLayerロジスティックアクティベーションによるクロスエントロピーエラーです。マルチラベルの損失のためにSigmoidCrossEntropyLossLayerのCaffeコードを理解するのに役立つ必要があります

基本的には、N個の独立ターゲットを持つ単一例えばクロスエントロピー誤差は次のように表される:

- sum-over-N(t[i] * log(x[i]) + (1 - t[i]) * log(1 - x[i]) 

tがターゲット、0または1であり、そしてxiによってインデックス付け、出力されます。 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))); 

はありがとうございます。

便宜上、この機能を以下に再現します。あなたはケースx[i]で数値的安定性が発生することがありますlog(1 + exp(x[i]))表現で

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がSigmoidal Activationを経て[0,1]にバインドされていないことを認識しています。 – auro

+0

@auroです。シグモイド活性化はこの層の一部である。 – Shai

答えて

2

は非常に大きいです。あなたが損失にsig(x)のための新しい、安定な発現を差し込む場合は、使用しているカフェと同じ表現になってしまいます、今

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

:この数値不安定性を克服するためには、このようなシグモイド関数をスケーリングします。

お楽しみください!

関連する問題