2017-10-31 3 views
1

私はKerasでモデルを作成していて、独自のメトリック(perplexity)を計算したいと思っています。これには、非正規化確率/ロジットを使用する必要があります。しかし、kerasモデルは、ソフトマックスprobabiltiesを返す:Keras - 確率ではなく正規化されていないログを取得する方法

 model = Sequential() 
     model.add(embedding_layer) 
     model.add(LSTM(n_hidden, return_sequences=False)) 
     model.add(Dropout(dropout_keep_prob)) 
     model.add(Dense(vocab_size)) 
     model.add(Activation('softmax')) 
     optimizer = RMSprop(lr=self.lr) 

     model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy') 

Kerasよくある中間層hereの出力を取得するためのソリューションを持っています。もう1つの解はhereです。しかし、これらの答えは、中間の出力を私が必要としない別のモデルに保存します。 カスタムメトリックのログを使用したいとします。カスタムメトリックは、トレーニング中に評価および表示されるように、model.compile()関数に含める必要があります。だから、私はDense層の出力を別のモデルではなく、元のモデルの一部として分離する必要はありません。要するに

、私の質問は以下のとおりです。

  • def custom_metric(y_true, y_pred)を使用して概説hereなどのカスタムメトリックを定義し、y_predがlogitsまたは正規化された確率が含まれていますか?

  • 正規化された確率を含む場合、正規化されていない確率、つまりDense層によって出力されるログを得るにはどうすればよいですか?

+0

このモデルを保持したいのですが、変更することはできますか? sparse_categorical_crossentropyを損失として保持しますか? –

+0

同じ最終結果を得られる代替手段は何でしょうか? – Lemon

答えて

2

私は溶液

最初に発見したと思い、私は@loannis Nasiosによって概説されるように、私はlogitsを受け取るように線形する活性層を変更します。

第2に、まだ損失関数としてsparse_categorical_crossentropyを取得するには、自分自身の損失関数を定義し、from_logitsパラメータをtrueに設定します。

model.add(embedding_layer) 
model.add(LSTM(n_hidden, return_sequences=False)) 
model.add(Dropout(dropout_keep_prob)) 
model.add(Dense(vocab_size)) 
model.add(Activation('linear')) 
optimizer = RMSprop(lr=self.lr) 


def my_sparse_categorical_crossentropy(y_true, y_pred): 
    return K.sparse_categorical_crossentropy(y_true, y_pred, from_logits=True) 

model.compile(optimizer=optimizer,loss=my_sparse_categorical_crossentropy) 
+0

あなたは*有用な答えを明示的に認めていますが、それをアップヴォートしても気にしませんか? – desertnaut

+0

他のユーザーを間違って非難している理由がわかりません。私はloannis Naosisの答えをすぐにupvoted。しかし、他の誰かがそれを下降させていたはずなので、私のupvoteは表示されません。 – Lemon

+0

私のお詫び... – desertnaut

0

は、あなたがトレーニングや予測のための別のためのモデルを作ることができ

model = Sequential() 
model.add(embedding_layer) 
model.add(LSTM(n_hidden, return_sequences=False)) 
model.add(Dropout(dropout_keep_prob)) 
model.add(Dense(vocab_size)) 
model.add(Activation('linear')) 
optimizer = RMSprop(lr=self.lr) 

model.compile(optimizer=optimizer, loss='sparse_categorical_crossentropy') 
+0

しかし、私は最後にsoftmax確率が必要なので、最終的なモデル出力は確率でなければなりません – Lemon

-1

を線形するソフトマックスからの最後の活性化を変更してみてください。訓練のための

、あなたは、機能的なAPIモデルを使用して、単純に既存のモデルの一部を取り、脇にアクティベーションを残すことができます。

model = yourExistingModelWithSoftmax 
modelForTraining = Model(model.input,model.layers[-2].output) 

#use your loss function in this model: 
modelForTraining.compile(optimizer=optimizer,loss=my_sparse_categorical_crossentropy, metrics=[my_custom_metric]) 

あなたが別の一環として、一つのモデルを持っているので、彼らの両方がします同じ重みを共有する。

  • あなたは、あなたが訓練確率を予測する場合modelForTraining.fit()
  • を使用し、model.predict()を使用したいです。
+0

私が上で見つけた解決策はもっと簡単だと思います。しかし、カスタムビルドメトリックの作成時に、y_predがKerasにあるかどうかはまだ分かりません。それは常に最後のネットワーク層の出力ですか? – Lemon

+0

はい、 'y_pred'はモデルの出力ですが、' y_true'は 'fit'に渡す真のデータです。 ---私の解決策では、後でsoftmax確率が必要になると考えています。 –

+0

softmax確率を後で使用することはできますか?私はいつもsoftmaxを追加していますか?たとえば、model.predict(input)を呼び出すと、出力は正規化されない確率(= logits)になります。 probs = K.nn.softmax(model.predict(input))を追加すると、必要なsoftmax確率が得られます。正しい? – Lemon

関連する問題