2016-11-01 8 views
6

CaffeのコードSigmoidCrossEntropyLoss layerdocsを探していましたが、ちょっと混乱しています。ドキュメントはロストロストとしてロスト関数を列挙します(私はここでそれを複製しますが、ラテックスなしではこの式は読みにくいでしょう。ドキュメントリンクをチェックしてください)。Caffe SigmoidCrossEntropyLossレイヤーロス機能

しかし、コード自体(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; 

がそれであることを示して?

しかし、それでも、(input_data[i] >= 0)スニペットも私を混乱させます。それらは、Sigmoid関数によって押しつぶされた予測であるはずのドキュメントの損失式からのp_hatの代わりにあるように見えます。では、バイナリのしきい値をとっているのはなぜですか?この損失が[0,1]の出力を予測するため、さらに混乱します。(input_data[i] >= 0)は、それが100%確実でない限り1になります。

誰かが私にこれを説明できますか?

答えて

6

カフェでSigmoidCrossEntropy層は、コードの一片にinput_dataに実行する2つの段階(+ CrossEntropySigmoid)組み合わせ:実際に

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とを適用した後input_dataのと数学でいくつかの組み合わせを作っています。

が、コードの最初の部分は、(カフェで使用)より数値的安定性を所有し、それが大きなexp(input_data)(又はexp(-input_data))を計算避けるためinput_dataの絶対値が大きすぎると、オーバーフローの少ないリスクを取ります。だからこそ、あなたはそのコードをcaffeで見たのです。

+0

一つは、(すなわち、[0,1]、むしろ{0,1}より)ソフトグランドトゥルースラベルを使用していたのであれば何も変更されなければなりませんか? – marcman

+0

グラウンドトゥルースラベルの合計が1に等しい場合、このレイヤーに変更はありません。それ以外の場合は、ネットワークの各出力にクロスエントロピーを適用する変更を加える必要があります。 @marcman – Dale

+0

私はそれがどういう場合であるのか理解していると思いますが、実際には、各ラベルを正規化したときにNaNの損失が発生しましたが、学習率の問題である可能性があります – marcman

関連する問題