自定义 keras 真阳性指标是否应始终 return 整数?
Should a custom keras true positive metric always return an integer?
我正在使用非标准数据集,其中我的 y_true
是(批次 x 5 x 1),y_pred
是(批次 x 5 x 1)。如果 y_true[i] > 0.
的任何值,则批处理样本 i
为“真”,如果 y_pred[i] >= b
其中 b
是介于 0 和 1 之间的阈值,则预测为“真”。
我已经定义了这个自定义 keras 指标来计算一批中的真阳性数:
def TP(threshold=0.0):
def TP_(Y_true, Y_pred):
Y_true = tf.where(Y_true > 0., tf.ones(tf.shape(Y_true)), tf.zeros(tf.shape(Y_true)))
Y_pred_true = tf.where(Y_pred >= threshold, tf.ones(tf.shape(Y_pred)), tf.zeros(tf.shape(Y_pred)))
Y_true = K.sum(Y_true, axis=1)
Y_pred_true = K.sum(Y_pred_true, axis=1)
Y_true = tf.where(Y_true > 0., tf.ones(tf.shape(Y_true)), tf.zeros(tf.shape(Y_true)))
Y_pred_true = tf.where(Y_pred_true > 0., tf.ones(tf.shape(Y_pred_true)), tf.zeros(tf.shape(Y_pred_true)))
Y = tf.math.add(Y_true, Y_pred_true)
tp = tf.where(Y == 2, tf.ones(tf.shape(Y)), tf.zeros(tf.shape(Y)))
tp = K.sum(tp)
return tp
return TP_
训练时,我有时会得到非整数值。这是因为 keras 正在对所有批次的值取平均值吗?
我对真阴性、假阳性和假阴性有类似的自定义指标。训练期间所有这四个值的总和应该是整数吗?
两部分回答:是的,指标是批次的平均值。您将看到与内置指标相同的行为,例如 tensorflow.keras.metrics.TruePositive
,但在每个纪元结束时它将是一个整数。
但是,您没有为您的指标保留状态,因此 TensorFlow 只是采用您返回的指标的平均值。考虑像这样子类化 tf.keras.metrics.Metric
:
class TP(tf.keras.metrics.Metric):
def __init__(self, threshold=0.5, **kwargs):
super().__init__(**kwargs)
self.threshold = threshold
self.true_positives = self.add_weight(name='true_positives', initializer='zeros',
dtype=tf.int32)
def update_state(self, y_true, y_pred, sample_weight=None):
y_true = tf.where(y_true > self.threshold,
tf.ones(tf.shape(y_true)),
tf.zeros(tf.shape(y_true)))
y_pred_true = tf.where(y_pred >= self.threshold,
tf.ones(tf.shape(y_pred)),
tf.zeros(tf.shape(y_pred)))
y_true = K.sum(y_true, axis=1)
y_pred_true = K.sum(y_pred_true, axis=1)
y_true = tf.where(y_true > self.threshold, tf.ones(tf.shape(y_true)),
tf.zeros(tf.shape(y_true)))
y_pred_true = tf.where(y_pred_true > self.threshold,
tf.ones(tf.shape(y_pred_true)),
tf.zeros(tf.shape(y_pred_true)))
Y = tf.math.add(y_true, y_pred_true)
tp = tf.where(Y == 2, tf.ones(tf.shape(Y), dtype=tf.int32),
tf.zeros(tf.shape(Y), dtype=tf.int32))
tp = K.sum(tp)
self.true_positives.assign_add(tp)
def result(self):
return self.true_positives
def get_config(self):
return {'threshold': self.threshold}
我正在使用非标准数据集,其中我的 y_true
是(批次 x 5 x 1),y_pred
是(批次 x 5 x 1)。如果 y_true[i] > 0.
的任何值,则批处理样本 i
为“真”,如果 y_pred[i] >= b
其中 b
是介于 0 和 1 之间的阈值,则预测为“真”。
我已经定义了这个自定义 keras 指标来计算一批中的真阳性数:
def TP(threshold=0.0):
def TP_(Y_true, Y_pred):
Y_true = tf.where(Y_true > 0., tf.ones(tf.shape(Y_true)), tf.zeros(tf.shape(Y_true)))
Y_pred_true = tf.where(Y_pred >= threshold, tf.ones(tf.shape(Y_pred)), tf.zeros(tf.shape(Y_pred)))
Y_true = K.sum(Y_true, axis=1)
Y_pred_true = K.sum(Y_pred_true, axis=1)
Y_true = tf.where(Y_true > 0., tf.ones(tf.shape(Y_true)), tf.zeros(tf.shape(Y_true)))
Y_pred_true = tf.where(Y_pred_true > 0., tf.ones(tf.shape(Y_pred_true)), tf.zeros(tf.shape(Y_pred_true)))
Y = tf.math.add(Y_true, Y_pred_true)
tp = tf.where(Y == 2, tf.ones(tf.shape(Y)), tf.zeros(tf.shape(Y)))
tp = K.sum(tp)
return tp
return TP_
训练时,我有时会得到非整数值。这是因为 keras 正在对所有批次的值取平均值吗?
我对真阴性、假阳性和假阴性有类似的自定义指标。训练期间所有这四个值的总和应该是整数吗?
两部分回答:是的,指标是批次的平均值。您将看到与内置指标相同的行为,例如 tensorflow.keras.metrics.TruePositive
,但在每个纪元结束时它将是一个整数。
但是,您没有为您的指标保留状态,因此 TensorFlow 只是采用您返回的指标的平均值。考虑像这样子类化 tf.keras.metrics.Metric
:
class TP(tf.keras.metrics.Metric):
def __init__(self, threshold=0.5, **kwargs):
super().__init__(**kwargs)
self.threshold = threshold
self.true_positives = self.add_weight(name='true_positives', initializer='zeros',
dtype=tf.int32)
def update_state(self, y_true, y_pred, sample_weight=None):
y_true = tf.where(y_true > self.threshold,
tf.ones(tf.shape(y_true)),
tf.zeros(tf.shape(y_true)))
y_pred_true = tf.where(y_pred >= self.threshold,
tf.ones(tf.shape(y_pred)),
tf.zeros(tf.shape(y_pred)))
y_true = K.sum(y_true, axis=1)
y_pred_true = K.sum(y_pred_true, axis=1)
y_true = tf.where(y_true > self.threshold, tf.ones(tf.shape(y_true)),
tf.zeros(tf.shape(y_true)))
y_pred_true = tf.where(y_pred_true > self.threshold,
tf.ones(tf.shape(y_pred_true)),
tf.zeros(tf.shape(y_pred_true)))
Y = tf.math.add(y_true, y_pred_true)
tp = tf.where(Y == 2, tf.ones(tf.shape(Y), dtype=tf.int32),
tf.zeros(tf.shape(Y), dtype=tf.int32))
tp = K.sum(tp)
self.true_positives.assign_add(tp)
def result(self):
return self.true_positives
def get_config(self):
return {'threshold': self.threshold}