2016-10-06 4 views
0

У меня есть два класса: положительный (1) и отрицательный (0).TensorFlow: как реализовать функцию потери класса для двоичной классификации

Набор данных очень неуравновешен, поэтому в настоящий момент мои мини-партии содержат в основном 0s. Фактически, многие партии будут содержать только 0. Я хотел поэкспериментировать с наличием отдельной стоимости для положительных и отрицательных примеров; см. код ниже.

Проблема с моим кодом заключается в том, что я получаю много nan, потому что список bound_index будет пустым. Каков элегантный способ решить эту проблему?

def calc_loss_debug(logits, labels): 
    logits = tf.reshape(logits, [-1]) 
    labels = tf.reshape(labels, [-1]) 
    index_bound = tf.where(tf.equal(labels, tf.constant(1, dtype=tf.float32))) 
    index_unbound = tf.where(tf.equal(labels, tf.constant(0, dtype=tf.float32))) 
    entropies = tf.nn.sigmoid_cross_entropy_with_logits(logits, labels) 
    entropies_bound = tf.gather(entropies, index_bound) 
    entropies_unbound = tf.gather(entropies, index_unbound) 
    loss_bound = tf.reduce_mean(entropies_bound) 
    loss_unbound = tf.reduce_mean(entropies_unbound) 
+0

Нанки происходят из-за того, что я принимаю среднее значение пустого списка (entropies_bound будет пустым) – Stackd

ответ

1

Поскольку у вас есть 0 и 1 этикетки, вы можете легко избежать tf.where с конструкцией, как этот

labels = ... 
entropies = ... 
labels_complement = tf.constant(1.0, dtype=tf.float32) - labels 
entropy_ones = tf.reduce_sum(tf.mul(labels, entropies)) 
entropy_zeros = tf.reduce_sum(tf.mul(labels_complement, entropies)) 

Чтобы получить средние потери, вам нужно разделить на число 0 и 1 в партия, которая может быть легко вычислена как

num_ones = tf.reduce_sum(labels) 
num_zeros = tf.reduce_sum(labels_complement) 

конечно, вы все равно должны остерегаться деления на 0, когда нет 1s в пакете. Я бы предложил использовать tf.cond(tf.equal(num_ones, 0), ...).

+0

Спасибо. Должно ли 0 в tf.conf быть tt.constant (0)? – Stackd

Смежные вопросы