ロジット、softmax、softmax_cross_entropy_with_logitsとは何ですか?


350

ここで tensorflow APIドキュメントを調べていました。tensorflowのドキュメントでは、と呼ばれるキーワードを使用していましたlogits。それは何ですか?APIドキュメントの多くのメソッドでは、次のように記述されています

tf.nn.softmax(logits, name=None)

書かれているのがこれらlogitsだけのTensors場合、なぜ別の名前を維持するのlogitsですか?

もう1つは、区別できない2つの方法があることです。彼らはいた

tf.nn.softmax(logits, name=None)
tf.nn.softmax_cross_entropy_with_logits(logits, labels, name=None)

それらの違いは何ですか?ドキュメントは私には明確ではありません。私は何をtf.nn.softmaxしているのか知っています。しかし、他のものではありません。例は本当に役に立ちます。

回答:


426

ロジットは単に、関数が以前のレイヤーのスケーリングされていない出力で動作し、単位を理解するための相対的なスケールが線形であることを意味します。これは、特に、入力の合計が1に等しくない可能性があることを意味します。つまり、値は確率ではありません(5の入力がある可能性があります)。

tf.nn.softmax入力テンソルにsoftmax関数を適用した結果のみを生成します。softmaxは次のように入力を「圧縮」しsum(input) = 1ます。これは正規化の方法です。ソフトマックスの出力の形状は入力と同じです。値を正規化するだけです。softmaxの出力は、確率として解釈できます。

a = tf.constant(np.array([[.1, .3, .5, .9]]))
print s.run(tf.nn.softmax(a))
[[ 0.16838508  0.205666    0.25120102  0.37474789]]

対照的に、tf.nn.softmax_cross_entropy_with_logits関数softmaxを適用した後、結果のクロスエントロピーを計算します(ただし、より数学的に慎重な方法ですべてをまとめて行います)。次の結果に似ています。

sm = tf.nn.softmax(x)
ce = cross_entropy(sm)

クロスエントロピーは要約メトリックです。要素全体で合計されます。tf.nn.softmax_cross_entropy_with_logits形状[2,5]テンソルの出力は形状です[2,1](最初の次元はバッチとして扱われます)。

クロスエントロピーを最小限に抑えるために最適化を行い、かつ最後のレイヤーの後にソフトマックスtf.nn.softmax_cross_entropy_with_logitsを実行する場合は、数学的に正しい方法で数値的に不安定なコーナーケースをカバーするため、自分で行う代わりに使用する必要があります。さもなければ、あちこちに小さなエプシロンを追加することでハッキングしてしまうでしょう。

2016年2月7日編集: オブジェクトが1つのクラスにのみ属することができる単一クラスのラベルがある場合はtf.nn.sparse_softmax_cross_entropy_with_logits、ラベルを高密度の1ホット配列に変換する必要がないように使用することを検討してください。この関数は、リリース0.6.0以降に追加されました。


1
softmax_cross_entropy_with_logitsについては、正しく使用しているかどうかわかりません。結果は、私のコードではそれほど安定していません。同じコードを2回実行すると、全体の精度が0.6から0.8に変わります。cross_entropy = tf.nn.softmax_cross_entropy_with_logits(tf.nn.softmax(tf.add(tf.matmul(x,W),b)),y) cost=tf.reduce_mean(cross_entropy)。しかし、私が別の方法を使用するとpred=tf.nn.softmax(tf.add(tf.matmul(x,W),b)) cost =tf.reduce_mean(-tf.reduce_sum(y*tf.log(pred),reduction_indices=1))、結果は安定していてより良いです。
Rida

15
あなたはあなたの最初の行でダブルソフトマックスです。softmax_cross_entropy_with_logitsは、tf.nn.softmaxの出力ではなく、スケーリングされていないロジットを想定しています。あなたtf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W, b))はあなたのケースで欲しいだけです。
dga

7
@dga私はあなたのコードにタイプミスがあると思いますb、ブラケットの外にある必要がありますtf.nn.softmax_cross_entropy_with_logits(tf.add(tf.matmul(x, W), b)
jrieke

1
「単位を理解するための相対的なスケールが線形であること」とは 最初の文の一部はどういう意味ですか?
チャーリーパーカー、

5
賛成ですが、「ソフトマックスの出力の形状は入力と同じです-値を正規化するだけです」と言ったときの答えは少し間違っています。Softmaxは、値を「押しつぶして」それらの合計が1になるようにするだけではありません。また、それらを再分配します。これが、この値が使用される主な理由である可能性があります。stackoverflow.com/questions/17187507/…、特にPiotr Czaplaの回答を参照してください。
Paolo Perrotta

282

短縮版:

2つのテンソルがありy_hat、各クラスの計算されたスコアが含まれ(たとえば、y = W * x + bから)、y_trueワンホットエンコードされた真のラベルが含まれているとします。

y_hat  = ... # Predicted label, e.g. y = tf.matmul(X, W) + b
y_true = ... # True label, one-hot encoded

のスコアy_hatを正規化されていない対数確率として解釈する場合、それらはロジットです。

さらに、この方法で計算されたクロスエントロピー損失の合計:

y_hat_softmax = tf.nn.softmax(y_hat)
total_loss = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), [1]))

基本的に、関数で計算されたクロスエントロピー損失の合計と同等ですsoftmax_cross_entropy_with_logits()

total_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))

ロングバージョン:

ニューラルネットワークの出力層では、計算などから、各トレーニングインスタンスのクラススコアを含む配列を計算しy_hat = W*x + bます。例として、以下を作成しy_hatました。2x 3の配列として作成しました。行はトレーニングインスタンスに対応し、列はクラスに対応しています。したがって、ここには2つのトレーニングインスタンスと3つのクラスがあります。

import tensorflow as tf
import numpy as np

sess = tf.Session()

# Create example y_hat.
y_hat = tf.convert_to_tensor(np.array([[0.5, 1.5, 0.1],[2.2, 1.3, 1.7]]))
sess.run(y_hat)
# array([[ 0.5,  1.5,  0.1],
#        [ 2.2,  1.3,  1.7]])

値は正規化されていないことに注意してください(つまり、行の合計が1になりません)。それらを正規化するために、入力を非正規化対数確率(別名logits)として解釈し、正規化線形確率を出力するsoftmax関数を適用できます。

y_hat_softmax = tf.nn.softmax(y_hat)
sess.run(y_hat_softmax)
# array([[ 0.227863  ,  0.61939586,  0.15274114],
#        [ 0.49674623,  0.20196195,  0.30129182]])

softmax出力の意味を完全に理解することが重要です。以下に、上記の出力をより明確に表す表を示しました。たとえば、インスタンス1のトレーニングが「クラス2」である確率は0.619であることがわかります。各トレーニングインスタンスのクラス確率は正規化されているため、各行の合計は1.0です。

                      Pr(Class 1)  Pr(Class 2)  Pr(Class 3)
                    ,--------------------------------------
Training instance 1 | 0.227863   | 0.61939586 | 0.15274114
Training instance 2 | 0.49674623 | 0.20196195 | 0.30129182

これで、各トレーニングインスタンスのクラス確率が得られました。各行のargmax()を取得して、最終的な分類を生成できます。上記から、トレーニングインスタンス1は「クラス2」に属し、トレーニングインスタンス2は「クラス1」に属していることが生成されます。

これらの分類は正しいですか?トレーニングセットの真のラベルに対して測定する必要があります。y_true行がトレーニングインスタンスで、列がクラスである、ワンホットエンコードされた配列が必要になります。以下にy_true、トレーニングインスタンス1の真のラベルが「クラス2」であり、トレーニングインスタンス2の真のラベルが「クラス3」である、ワンホット配列の例を作成しました。

y_true = tf.convert_to_tensor(np.array([[0.0, 1.0, 0.0],[0.0, 0.0, 1.0]]))
sess.run(y_true)
# array([[ 0.,  1.,  0.],
#        [ 0.,  0.,  1.]])

確率分布はの確率分布にy_hat_softmax近いy_trueですか?クロスエントロピー損失を使用してエラーを測定できます。

クロスエントロピー損失の式

行単位でクロスエントロピー損失を計算し、結果を確認できます。以下では、トレーニングインスタンス1の損失が0.479であるのに対し、トレーニングインスタンス2の損失は1.200と大きくなっています。上記の例でy_hat_softmaxは、トレーニングインスタンス1の最も高い確率は "クラス2"であり、これはのトレーニングインスタンス1と一致するため、この結果は理にかなっていy_trueます。ただし、トレーニングインスタンス2の予測では、「クラス1」の確率が最も高く、真のクラス「クラス3」とは一致しません。

loss_per_instance_1 = -tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1])
sess.run(loss_per_instance_1)
# array([ 0.4790107 ,  1.19967598])

私たちが本当に望んでいるのは、すべてのトレーニングインスタンスの合計損失です。したがって、以下を計算できます。

total_loss_1 = tf.reduce_mean(-tf.reduce_sum(y_true * tf.log(y_hat_softmax), reduction_indices=[1]))
sess.run(total_loss_1)
# 0.83934333897877944

softmax_cross_entropy_with_logits()の使用

代わりにtf.nn.softmax_cross_entropy_with_logits()、以下に示すように、関数を使用して合計クロスエントロピー損失を計算できます。

loss_per_instance_2 = tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true)
sess.run(loss_per_instance_2)
# array([ 0.4790107 ,  1.19967598])

total_loss_2 = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(y_hat, y_true))
sess.run(total_loss_2)
# 0.83934333897877922

total_loss_1total_loss_2最後の桁に若干の違いがある基本的に同等の結果を生成することに注意してください。ただし、2番目の方法を使用することもできます。softmaxはの内部で行われるため、コードの行数が1つ減り、蓄積される数値エラーが少なくなりますsoftmax_cross_entropy_with_logits()


上記のすべてを確認します。単純なコード:M = tf.random.uniform([100, 10], minval=-1.0, maxval=1.0); labels = tf.one_hot(tf.random.uniform([100], minval=0, maxval=10 , dtype='int32'), 10); tf.nn.softmax_cross_entropy_with_logits(labels=labels, logits=M) - tf.reduce_sum(-tf.nn.log_softmax(M)*tf.one_hot(labels, 10), -1)どこにでも0に近い値を返す
Sami A. Haija

51

tf.nn.softmaxsoftmax層を通過する順方向伝播を計算します。評価中に使用しますしますが、モデル出力という確率を計算する際のモデルの。

tf.nn.softmax_cross_entropy_with_logitssoftmaxレイヤーのコストを計算します。トレーニング中にのみ使用されますます。

ロジットは、モデルを出力する非正規化ログ確率です(softmax 正規化が適用される前に出力される値)。


2
わかった。関数tf.nn.softmax_cross_entropy_sans_normalizationを呼び出さないのはなぜですか?
auro

8
@auroは、クロスエントロピー計算中に(内部で)値を正規化するためです。のポイントはtf.nn.softmax_cross_entropy_with_logits、モデルがゴールドラベルからどれだけ逸脱しているかを評価することであり、正規化された出力を提供することではありません。
erickrf

1
tf.nn.sparse_softmax_cross_entropy_with_logits()を使用する場合は、スパースソフトマックスレイヤーのコストを計算するため、新しいデータに対してモデルを実行する場合の代替案をトレーニング中にのみ使用する必要があります。これから確率を取得することは可能ですか? 1。
SerialDev 2017年

2
@SerialDev、から確率を取得することはできませんtf.nn.sparse_softmax_cross_entropy_with_logits。確率を取得するには、を使用しますtf.nn.softmax
ナンディーシュ

4

上記の回答には、質問に対する十分な説明があります。

これに加えて、Tensorflowは、アクティベーション関数を適用し、独自のアクティベーションとそれに続くコスト関数を使用してコストを計算する操作を最適化しました。したがって、以下を使用することをお勧めします。tf.nn.softmax_cross_entropy()以上tf.nn.softmax(); tf.nn.cross_entropy()

リソースを集中的に使用するモデルでは、両者の顕著な違いを見つけることができます。


1
上記の答えは明らかに質問を読んでいません。彼らはすべて同じことを言っていますが、それは知られていますが、質問自体には答えません
Euler_Salter

@abhishもしかして、tf.nn.softmaxその後にtf.losses.softmax_cross_entropy
ankurrc

4

これまでに行ったのsoftmaxはロジットです。これは、J。ヒントンがコースラビデオで常に繰り返していることです。


1

Tensorflow 2.0互換性のある回答:Logitsと関連する関数の説明dgastackoverflowuser2010非常に詳細です。

これらすべての関数は、で使用するTensorflow 1.xと正常に動作しますが、コードを1.x (1.14, 1.15, etc)から2.x (2.0, 2.1, etc..)、それらの関数を使用するとエラーが発生します。

したがって、上で説明したすべての関数に2.0互換呼び出しを指定すると、 1.x to 2.xコミュニティの利益のために、します。

1.xの関数

  1. tf.nn.softmax
  2. tf.nn.softmax_cross_entropy_with_logits
  3. tf.nn.sparse_softmax_cross_entropy_with_logits

1.xから2.xに移行した場合の各機能

  1. tf.compat.v2.nn.softmax
  2. tf.compat.v2.nn.softmax_cross_entropy_with_logits
  3. tf.compat.v2.nn.sparse_softmax_cross_entropy_with_logits

1.xから2.x への移行の詳細については、この移行ガイドを参照してください。


0

ロジットとして強調したいもう1つのことは、生の出力、一般的には最後のレイヤーの出力です。これは負の値になることもあります。下記の「クロスエントロピー」評価用にそのまま使用した場合:

-tf.reduce_sum(y_true * tf.log(logits))

その後、それは機能しません。-veのログが定義されていないため。したがって、o softmaxアクティベーションを使用すると、この問題を克服できます。

これは私の理解です。間違っている場合は訂正してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.