Keras:具有条件条件的自定义损失函数

时间:2020-10-12 16:17:33

标签: python tensorflow machine-learning keras deep-learning

我在Keras中有一个神经网络,在回归任务中需要1个输出的23个输入。 我想构建一个自定义损失函数,如果某些输入条件不满足,则有一个额外的术语,即:

loss_mse = tf.keras.losses.mean_squared_error(y_true, y_pred)
if y_pred > input23:
    loss_dyn = (y_pred - input23)^2 
loss = loss_mse + loss_dyn

到目前为止,我已经尝试使用基本的python函数和所有TensorFlow等效项(例如tf.math.square的tf.math.greater),但是两种方法都会出错。我使用了包装函数,将x_train输入到自定义损失函数中,如下所示:

def my_loss_function_wrapper(names_dict, x):
    def my_loss_function(y_true, y_pred):
        loss_mse = tf.keras.losses.mean_squared_error(y_true, y_pred) # regluar MSE
        
        def loss_dyn_true():
            return tf.math.square(
                tf.math.subtract(
                    y_pred,
                    x[:,23]
                )
            )
        def loss_dyn_false():
            return 0
        loss_dyn = tf.cond(
            tf.math.greater(
                y_pred, x[22]
            ),
            loss_dyn_true,
            loss_dyn_false
        )        
        def loss_stat_true():
            return tf.math.square(
                tf.math.subtract(
                    y_pred, x[21]
                )
            )
        def loss_stat_false():
            return 0
        loss_stat = tf.cond(
            tf.math.logical_and(
                tf.math.less(
                    x[:,6]], 0.1
                ),
                tf.math.less(
                    x[:,20]], 0.02
                ),
            ),
            loss_stat_true,
            loss_stat_false
        )
        loss = loss_mse + loss_dyn + loss_stat

        return loss
    return my_loss_function

但这会导致错误

TypeError:tf.cond的true_fn和false_fn参数必须具有相同的数字,类型和返回值的整体结构。 true_fn输出:Tensor(“ Square:0”,shape =(None,9159),dtype = float32)false_fn输出:Tensor(“ Const:0”,shape =(),dtype = int32)错误详细信息:Tensor(“ Square :0“,shape =(无,9159),dtype = float32)和Tensor(” Const:0“,shape =(),dtype = int32)具有不同的类型

9159是每个特征的输入样本数,但是为什么整数类型的Tensor(“ Const:0”,shape =(),dtype = int32)是整数,当它是我的y_pred时,应该是会漂浮吗?

而且,我是否应该仅将输入的当前样本传递给loss_function而不是输入张量的整个列(上面具有形状(None,9159))?我该怎么做,以便每次访问相应的样本而不是整个列。

修改

现在,我对其进行了更改,以将与损失函数相关的输入添加到输出中,以便可以像在y_true中一样访问它们:

def my_loss_wrapper(names_dict):
    def my_loss(y_true, y_pred):
        loss_mse = tf.keras.losses.mean_squared_error(y_true, y_pred[:, 0]) # regluar MSE
        
        def loss_dyn_true():
            return tf.math.square(
                tf.math.subtract(
                    y_pred[:, 0],
                    y_pred[:, names_dict['Sensor.IN01']]
                )
            )
        def loss_dyn_false():
            return y_pred[:, names_dict['Zeros']]
        loss_dyn = tf.cond(
            tf.math.greater(
                y_pred[:, 0], 
                y_pred[:, names_dict['Car.02']]
            ),
            loss_dyn_true,
            loss_dyn_false
        )        
        def loss_stat_true():
            return tf.math.square(
                tf.math.subtract(
                    y_pred[:, 0], 
                    y_pred[:, names_dict['Car.02_stat']]
                )
            )
        def loss_stat_false():
            return y_pred[:, names_dict['Zeros']]
        loss_stat = tf.cond(
            tf.math.logical_and(
                tf.math.less(
                    y_pred[:, names_dict['Sensor.02']], 0.1
                ),
                tf.math.less(
                    y_pred[:, names_dict['Sensor.IN01']], 0.02
                ),
            ),      
            loss_stat_true,
            loss_stat_false
        )
        loss = loss_mse + loss_dyn + loss_stat

        return loss
    return my_loss

(Names_dict指向相应值的索引) 导致

ValueError:维度1的切片索引5超出范围。对于输入形状为[?,1],[2],[2],[2]并计算输入张量的'loss_7 / output_1_loss / strided_slice_2'(op:'StridedSlice')和输入的张量计算为:input [1] = <0 5 >,输入[2] = <0 6>,输入[3] = <1 1>。

似乎形状不正确。

0 个答案:

没有答案