Я заинтересован в использовании пользовательской функции потерь в тензорном потоке, которая учитывает тип ошибки. Например, я хотел бы создать функцию, которая взвешивает некоторый тип ошибки (прогнозирование класса 1 с меткой, являющейся классом 3) тяжелее, чем другие (прогнозирование класса 2 с меткой, являющейся классом 3). Причина кроется в текущем проекте, над которым я работаю, где классы четко ранжированы (хотя только по порядковой шкале).
Я реализовал функцию потерь, аналогичную той, которая показана в (https://github.com/keras-team/keras/issues/2115#issuecomment-204060456) с использованием Keras. Однако я хотел бы знать, как я могу реализовать нечто подобное непосредственно в tenorflow. В настоящее время мне, к сожалению, не повезло Я попытался использовать его более или менее в его текущем из in tenorflow (вызывая K. parts с помощью tf.keras.backend), но безуспешно (см. Фрагмент кода 1). Я также попытался написать нечто похожее с умножением матриц (используя tf.matmul), но тогда моя ошибка разошлась (см. фрагмент кода 2). Обратите внимание, что Omega - это матрица K x K с весами.
Для классов K я хотел бы иметь в общей сложности K ^ 2 различных весов, учитывающих каждый тип классификации и неправильную классификацию.
Любая помощь очень ценится! Я впервые задаю вопрос по stackoverflow, поэтому, если я сделал что-то не так, обязательно дайте мне знать.
Код 1:
number_of_classes = 3
modifier = tf.keras.backend.zeros_like(output_softmax[:, 0])
y_pred_max = tf.keras.backend.max(output_softmax, axis = 1)
y_pred_max = tf.keras.backend.expand_dims(y_pred_max, 1)
y_pred_max_mat = tf.keras.backend.equal(output_softmax, y_pred_max)
for i, j in product(range(number_of_classes), range(number_of_classes)):
modifier += (tf.keras.backend.cast(Omega[j, i], tf.keras.backend.floatx()) *
tf.keras.backend.cast(y_pred_max_mat[:, i], tf.keras.backend.floatx()) * tf.keras.backend.cast(y_[:, j], tf.keras.backend.floatx()))
loss = tf.keras.backend.categorical_crossentropy(output_softmax, y_) * modifier
Проблема: теперь моя потеря за данную эпоху - не число, а матрица. При проверке ранней остановки (я отслеживаю потери для каждой эпохи и сравниваю потери тока с минимальными потерями), возникает следующая ошибка:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()`
Код 2:
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels = y_, logits = output))
mod_loss = tf.reduce_mean(tf.multiply(loss, tf.matmul(tf.matmul(y_, Omega), output_softmax, transpose_b=True)))
Проблема: теперь моя потеря увеличивается со временем.