2017-09-20 44 views
0

Kerasでカスタム損失関数を作成しようとしています。私はKerasでカスタム損失関数を作成する

loss function

に出力の大きさを、この損失関数を作りたい

は80バッチサイズは、だから私は下のこの損失関数を構築する5000

です。しかし、これは機能しません。

def normalize_activation(y_true, y_pred): 
    nb_divide = K.reshape(K.sqrt(K.sum(K.square(y_pred), axis=1)),(5000, 1)) 
    nb_divide=numpy.tile(nb_divide,80) 
    predicted=numpy.divide(y_pred,nb_divide) 
    return K.sum(K.square(y_true-predicted)) 

ValueError:シーケンスで配列要素を設定します。

このエラーが発生します。私はy_true、y_predの形は(5000,80)だと思います。

どこで修正すればよいですか?

+0

'losses.mean_squared_error(y_true、K.l2_normalize(y_pred、axis = -1))'を使用するのと同じです。 –

+0

また、モデルの末尾に 'lambda(λx:K.l2_normalize(x、axis = -1))'レイヤーを追加し、 'loss = 'mse''を使うこともできます。 –

+0

@ゆうヤンありがとうございました!ラムダを使うとき、最後のリンクの重みは1でなければなりません。私はそれを作ることができません。私はあなたの最初のソリューションを使用しています。ありがとうございました。しかし私は軸= -1の意味を疑問に思う。私は軸= 0、軸= 1を知っています。 –

答えて

2

損失機能は、keras backendからではないすべての種類の操作を避ける必要があります。値はテンソルであり、それらをテンソルのように保つ必要があります。

実際に特定の方法で動作させたい場合を除き、変更する必要はありません。

シェイプ(5000,80)と(5000,1)がある場合は、K.repeat_elements()(numpy.tileに相当)を使わずに操作できます。

したがって、5000はバッチサイズ(サンプル数)と80サンプルに属する唯一の実際の寸法であるとすると:

def normalize_loss(yTrue,yPred): 
    nb_divide = K.sqrt(K.sum(K.square(yPred),axis=1,keepdims=True)) 
     #keepdims=True keeps the shape like (5000,1) 
     #this is not summing the entire batch, but only a single sample, is that correct? 

    predicted = yPred/nb_divide 
    return K.sum(K.square(yTrue-predicted)) 

いくつかの観察:

  • (私はここで損失関数の専門家ではない)あなたは予測された部分だけを分割しているが、真の部分は分割していない。両方の値の間に大きな違いが生じ、間違った損失関数が生じるのではないでしょうか? (ここでも私は専門家ではありません)

  • 通常、人々は損失機能の最後にK.mean()を使用しますが、私はK.sum()を使用しています。これは問題ではなく、訓練が機能するのを妨げない。しかし、異なるサイズのデータ​​に対して同じ損失関数を視覚化し、サイズを独立して比較できるようにすることができます。

+0

ありがとう!あなたの非常に親切。ありがとうございました –

関連する問題