我在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>。
似乎形状不正确。