Пользовательская функция потерь, которая пропускает ввод NaN - PullRequest
0 голосов
/ 25 января 2020

Я строю автоэнкодер, в моих данных есть значения NaN. Как создать пользовательскую функцию потерь (MSE), которая не вычисляет потери, если в данных проверки встречается NaN?

Получил подсказку из Интернета:

def nan_mse(y_actual, y_predicted):
    per_instance = tf.where(tf.is_nan(y_actual),
                            tf.zeros_like(y_actual),
                            tf.square(tf.subtract(y_predicted, y_actual)))
    return tf.reduce_mean(per_instance, axis=0)

Но получите потерю NaN:

Эпоха 1/50 - 25 с - потеря: нан

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

predictions = autoencoder.predict(x_pred)
mae = (nan_mse(x_pred, predictions))

TypeError: Ввод 'e' из 'Select' Op имеет тип float32, который не соответствует типу float64 аргумента 't'.

1 Ответ

1 голос
/ 26 января 2020

Полагаю, ваша функция потерь действительно работает хорошо. Значение nan, вероятно, исходит из прогнозов. Таким образом, условие tf.is_nan(y_actual) не фильтрует его. Чтобы отфильтровать прогноз nan, необходимо сделать следующее:

import tensorflow.compat.v1 as tf
from tensorflow.compat.v1.keras import backend as K
import numpy as np


def nan_mse(y_actual, y_predicted):
    stack = tf.stack((tf.is_nan(y_actual), 
                      tf.is_nan(y_predicted)),
                     axis=1)
    is_nans = K.any(stack, axis=1)
    per_instance = tf.where(is_nans,
                            tf.zeros_like(y_actual),
                            tf.square(tf.subtract(y_predicted, y_actual)))
    print(per_instance)
    return tf.reduce_mean(per_instance, axis=0)

print(nan_mse([1.,1.,np.nan,1.,0.], [1.,1.,0.,0.,np.nan]))

Out:

tf.Tensor(0.2, shape=(), dtype=float32)
...