私はテンソルフロー(Caffeからのもの)を使い始めており、損失sparse_softmax_cross_entropy_with_logits
を使用しています。この関数は、onehotエンコーディングの代わりに0,1,...C-1
のようなラベルを受け入れます。ここで、クラスラベルに応じた重みを使用したいと思います。 softmax_cross_entropy_with_logits
(1つのホットエンコーディング)を使用する場合、これはおそらく行列の乗算で実行できることを知っています。sparse_softmax_cross_entropy_with_logits
で同じことを行う方法はありますか?
import tensorflow as tf
import numpy as np
np.random.seed(123)
sess = tf.InteractiveSession()
# let's say we have the logits and labels of a batch of size 6 with 5 classes
logits = tf.constant(np.random.randint(0, 10, 30).reshape(6, 5), dtype=tf.float32)
labels = tf.constant(np.random.randint(0, 5, 6), dtype=tf.int32)
# specify some class weightings
class_weights = tf.constant([0.3, 0.1, 0.2, 0.3, 0.1])
# specify the weights for each sample in the batch (without having to compute the onehot label matrix)
weights = tf.gather(class_weights, labels)
# compute the loss
tf.losses.sparse_softmax_cross_entropy(labels, logits, weights).eval()
特にバイナリ分類の場合、 weighted_cross_entropy_with_logits
は、重み付けされたソフトマックスクロスエントロピーを計算します。
sparse_softmax_cross_entropy_with_logits
は、高効率で重み付けされていない操作に対応しています( SparseSoftmaxXentWithLogitsOp
を参照してください SparseXentEigenImpl
を内部で使用しています)。 「プラグイン可能」ではありません。
マルチクラスの場合、オプションはワンホットエンコーディングに切り替えるか、 tf.losses.sparse_softmax_cross_entropy
すでに提案されているように、ハックな方法で損失関数を使用します。現在のバッチのラベルに応じて重みを渡す必要があります。
クラスの重みはロジットで乗算されるため、sparse_softmax_cross_entropy_with_logitsでも機能します。 「Tensorフローのクラス不均衡バイナリ分類器の損失関数」については、 このソリューション を参照してください。
補足として、重みを sparse_softmax_cross_entropy に直接渡すことができます
tf.contrib.losses.sparse_softmax_cross_entropy(logits, labels, weight=1.0, scope=None)
この方法は、次を使用したクロスエントロピー損失用です
tf.nn.sparse_softmax_cross_entropy_with_logits.
重量は損失の係数として機能します。スカラーが指定されている場合、損失は指定された値で単純にスケーリングされます。重みがサイズ[batch_size]のテンソルの場合、損失の重みは対応する各サンプルに適用されます。