【问题标题】:Custom loss function that skips the NaN input跳过 NaN 输入的自定义损失函数
【发布时间】:2020-05-11 16:24:42
【问题描述】:

我正在构建一个自动编码器,我的数据中有 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 - 25s - 损失:nan

当我尝试在回调函数中使用自定义损失函数时,在每个 epoch 之后:

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

TypeError: 'Select' Op 的输入 'e' 的 float32 类型与参数 't' 的 float64 类型不匹配。

【问题讨论】:

    标签: python tensorflow keras autoencoder


    【解决方案1】:

    我猜,您的损失函数实际上运行良好。 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]))
    

    输出:

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

    【讨论】:

    • 确实回调函数的错误来自预测数据。但是所有 y_prediction 都由 NaN 组成。这是一个自动编码器,我希望这种损失能帮助我忽略输入中的 NaN,并产生非 NaN 预测。但它会创建所有 NaN 预测。
    • @Geeocode 我有两个问题要尊重您的回答:I)如果 0 具有与其他值一样的含义(例如,当我们处理温度时间序列时)将 NAN 替换为 0 确实似乎并不完全正确。 II)如果目标是过滤 NAN,当我们进行平均时,我们不应该将 sum 除以张量的非 NAN 元素的数量吗?您能否根据这两个问题更新您的答案?非常感谢。
    猜你喜欢
    • 2021-07-21
    • 2018-06-25
    • 2020-03-02
    • 1970-01-01
    • 2019-08-22
    • 2019-05-19
    • 2020-01-24
    • 2020-01-21
    • 2020-08-06
    相关资源
    最近更新 更多