Я работаю над задачей двоичной семантической сегментации, в которой распределение одного класса очень мало по любому входному изображению, следовательно, только несколько пикселей помечены. При использовании sparse_softmax_cross_entropy общая ошибка легко уменьшается при игнорировании этого класса. Теперь я ищу способ взвешивания классов с помощью коэффициента, который штрафует за неправильную классификацию для определенного класса выше по сравнению с другим классом.
Док функции потерь заявляет:
Вес действует как коэффициент потерь. Если скаляр предоставлен, тогда потеря просто масштабируется данным значением. Если весовые коэффициенты представляют собой тензор формы [batch_size], то весовые коэффициенты потерь применяются к каждому соответствующему образцу.
Если я правильно понимаю, это говорит о том, что конкретный образец в партии взвешивается по-разному по сравнению с другими. Но это на самом деле не то, что я ищу. Кто-нибудь знает, как реализовать взвешенную версию этой функции потерь, где веса масштабируют важность определенного класса, а не выборок?
Чтобы ответить на мой собственный вопрос:
Авторы статьи U-Net использовали предварительно вычисленную карту весов для обработки несбалансированных классов.
Институт анстрономии ETH Zurich предоставил пакет U-Net на основе Tensorflow, который содержит взвешенную версию функции Softmax (не редкую, но сначала сплющивающую метки и логиты):
class_weights = tf.constant(np.array(class_weights, dtype=np.float32))
weight_map = tf.multiply(flat_labels, class_weights)
weight_map = tf.reduce_sum(weight_map, axis=1)
loss_map = tf.nn.softmax_cross_entropy_with_logits_v2(logits=flat_logits, labels=flat_labels)
weighted_loss = tf.multiply(loss_map, weight_map)
loss = tf.reduce_mean(weighted_loss)