私は最近遭遇しました tf.nn.sparse_softmax_cross_entropy_with_logits そして、その違いが tf.nn.softmax_cross_entropy_with_logits と比較されるものを理解できません。
sparse_softmax_cross_entropy_with_logits
を使用する場合、トレーニングベクトルy
を one-hot encoded にする必要があるという唯一の違いはありますか?
APIを読んで、softmax_cross_entropy_with_logits
と比較して他の違いを見つけることができませんでした。しかし、なぜ追加の機能が必要なのでしょうか?
ワンホットエンコードされたトレーニングデータ/ベクトルが提供されている場合、softmax_cross_entropy_with_logits
はsparse_softmax_cross_entropy_with_logits
と同じ結果を生成すべきではありませんか?
2つの異なる関数を使用すると、同じ結果が得られるため、便利です。
違いは簡単です:
sparse_softmax_cross_entropy_with_logits
の場合、ラベルの形状は[batch_size]で、dtypeはint32またはint64でなければなりません。各ラベルは[0, num_classes-1]
の範囲のintです。softmax_cross_entropy_with_logits
の場合、ラベルの形状は[batch_size、num_classes]およびdtype float32またはfloat64でなければなりません。softmax_cross_entropy_with_logits
で使用されるラベルは、sparse_softmax_cross_entropy_with_logits
で使用されるラベルの1つのホットバージョンです。
もう1つの小さな違いは、sparse_softmax_cross_entropy_with_logits
を使用すると、-1をラベルとして指定して、このラベルで0
を失うことができることです。
TFのドキュメントにも記載されている受け入れられた回答に2つのことを追加したいと思います。
最初:
tf.nn.softmax_cross_entropy_with_logits
注:クラスは相互に排他的ですが、確率はそうである必要はありません。必要なのは、ラベルの各行が有効な確率分布であることだけです。そうでない場合、勾配の計算は不正確になります。
第二:
tf.nn.sparse_softmax_cross_entropy_with_logits
注:この操作では、特定のラベルの確率は排他的と見なされます。つまり、ソフトクラスは許可されず、ラベルベクトルは、ロジットの各行(各ミニバッチエントリ)の真のクラスに単一の特定のインデックスを提供する必要があります。
両方の関数は同じ結果を計算し、 sparse_softmax_cross_entropy_with_logits は、スパースラベルを one-hot encoding で変換するのではなく、スパースラベルで直接クロスエントロピーを計算します。
これを確認するには、次のプログラムを実行します。
import tensorflow as tf
from random import randint
dims = 8
pos = randint(0, dims - 1)
logits = tf.random_uniform([dims], maxval=3, dtype=tf.float32)
labels = tf.one_hot(pos, dims)
res1 = tf.nn.softmax_cross_entropy_with_logits( logits=logits, labels=labels)
res2 = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=tf.constant(pos))
with tf.Session() as sess:
a, b = sess.run([res1, res2])
print a, b
print a == b
ここで、長さlogits
のランダムなdims
ベクトルを作成し、ワンホットエンコードラベルを生成します(pos
の要素は1で、他は0です)。
その後、softmaxとスパースsoftmaxを計算し、それらの出力を比較します。数回再実行して、常に同じ出力が生成されるようにします