2016-10-23 1 views
6

Я начинаю использовать тензорный поток (исходящий от Caffe), и я использую потерю sparse_softmax_cross_entropy_with_logits. Функция принимает метки, такие как 0,1,...C-1 вместо однократных кодировок. Теперь я хочу использовать взвешивание в зависимости от метки класса; Я знаю, что это может быть сделано, возможно, с умножением матрицы, если я использую softmax_cross_entropy_with_logits (одна горячая кодировка). Есть ли способ сделать то же самое с sparse_softmax_cross_entropy_with_logits?Как реализовать взвешенную кросс-энтропийную потерю в тензорном потоке с использованием sparse_softmax_cross_entropy_with_logits

ответ

1

Вес классов умножается на логиты, поэтому все еще работает для sparse_softmax_cross_entropy_with_logits. Обратитесь к this solution за «Функция потерь для двоичного классификатора класса с дисбалансом в тензорном потоке».

В качестве примечания, вы можете передать веса непосредственно в 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], то весовые потери относятся к каждому соответствующему образцу.

+0

Мне было интересно, есть ли способ избежать горячих ярлыков, потому что в приведенной ссылке все же необходимо умножить матрицу одной горячей метки с вектором веса. Другим способом было бы использовать вектор веса длины batchsize, но тогда мне пришлось бы вычислять этот вектор для каждой партии; как я могу определить его (поскольку он зависит от ярлыков) без необходимости вычисления матрицы меток onehot? –

+3

Я не думаю, что этот ответ правильный. Весы в 'tf.contrib.losses.sparse_softmax_cross_entropy' относятся к одной выборке, а не к классу. – andong777

+0

Это правильно, это просто раздражает. Вы будете передавать вес для каждого обновления, и это будет зависеть от конкретного класса, который находится в текущем обновлении. Поэтому, если у вас была партия размером 3, а классы были 1,1,2. И вы хотели весить класс 1 на 50%, тогда вы использовали бы эту функцию потерь и передали весовой аргумент тензору со значениями [0,5,0,5,1,0]. Это будет эффективно весить ваш класс ... Элегантный? Нет. Да, да. –

2

В частности, для двоичной классификации существует weighted_cross_entropy_with_logits, которая вычисляет взвешенную кросс-энтропию softmax.

sparse_softmax_cross_entropy_with_logits является хвосты для высокоэффективных невзвешенных операций (см SparseSoftmaxXentWithLogitsOp, который использует SparseXentEigenImpl под капотом), так что это не «замены».

В случае с несколькими классами, ваш вариант либо переключается на одноразовое кодирование, либо использует функцию потерь tf.losses.sparse_softmax_cross_entropy в хакерском режиме, как уже было предложено, где вам придется передавать весы в зависимости от меток текущей партии ,

2
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() 
Смежные вопросы