Часть пользовательской функции потери не различима - PullRequest
1 голос
/ 02 мая 2019

Для моей проблемы я хочу предсказать оценки клиентов в диапазоне от 1 до 5. Я подумал, что было бы неплохо реализовать это как регрессионную проблему, потому что предсказанное 1 из модели, в то время как 5 является истинным значением, должно быть "худший прогноз, чем 4. Также желательно, чтобы модель выполняла как-то одинаково хорошо для всех классов оценки .Поскольку мой набор данных сильно разбалансирован, я хочу создать собственную функцию потерь.При нормальной реализации MSE модель будет хороша только для прогнозирования большинства класса.Поэтому я хочу оценить MSE для каждого класса обзора (1,2,3,4 и 5-звездочных обзоров), а затем взять среднее из этих пяти оценок MSE.Вот как модель должна быть стимулирована, чтобы также хорошо выполнять прогнозирование меньших классов.

Следующий код показывает мою функцию потери тензорного потока:

def custom_loss_function(y_true, y_pred):
    y_true_t = tf.cast(tf.Variable(y_true, validate_shape=False),dtype="float16")
    y_pred_t = tf.cast(tf.Variable(y_pred, validate_shape=False),dtype="float16")

    one = tf.cast(tf.Variable([1]),dtype="float16")
    two = tf.cast(tf.Variable([2]),dtype="float16")
    three = tf.cast(tf.Variable([3]),dtype="float16")
    four = tf.cast(tf.Variable([4]),dtype="float16")
    five = tf.cast(tf.Variable([5]),dtype="float16")

    # index for a given review class
    i_one = tf.where(tf.equal(y_true_t, one))
    i_two = tf.where(tf.equal(y_true_t, two))
    i_three = tf.where(tf.equal(y_true_t, three))
    i_four = tf.where(tf.equal(y_true_t, four))
    i_five = tf.where(tf.equal(y_true_t, five))

    # predictions for the found indicies for a review class
    y_pred_one=tf.gather(y_pred_t,i_one)
    y_pred_two=tf.gather(y_pred_t,i_two)
    y_pred_three=tf.gather(y_pred_t,i_three)
    y_pred_four=tf.gather(y_pred_t,i_four)
    y_pred_five=tf.gather(y_pred_t,i_five)

    y_true_one=tf.gather(y_true_t,i_one)
    y_true_two=tf.gather(y_true_t,i_two)
    y_true_three=tf.gather(y_true_t,i_three)
    y_true_four=tf.gather(y_true_t,i_four)
    y_true_five=tf.gather(y_true_t,i_five)

    mse1 = tf.reduce_mean(tf.cast(tf.square(y_true_one-y_pred_one),dtype="float"))
    mse2 = tf.reduce_mean(tf.cast(tf.square(y_true_two-y_pred_two),dtype="float"))
    mse3 = tf.reduce_mean(tf.cast(tf.square(y_true_three-y_pred_three),dtype="float"))
    mse4 = tf.reduce_mean(tf.cast(tf.square(y_true_four-y_pred_four),dtype="float"))
    mse5 = tf.reduce_mean(tf.cast(tf.square(y_true_five-y_pred_five),dtype="float"))

    mse = (mse1+mse2+mse3+mse4+mse5)/5

    return mse

Когда я пытаюсь использовать эту функцию потери в моем NN, я получаю следующее сообщение:

ValueError: Операция имеет None для градиента.Пожалуйста, убедитесь, что все ваши операции имеют определенный градиент (то есть являются дифференцируемыми).Обычные операции без градиента: K.argmax, K.round, K.eval.

Я не мог понять, почему возникает эта ошибка.Я думал, что все операции TF должны быть дифференцируемыми, но я также могу ошибаться.

Спасибо за любую помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...