我为特异性和敏感性编写了一个自定义度量,并将其作为度量传递给model.compile()。这是我写的代码(我从tensorflow的网站上复制了大部分):
import tensorflow as tf
from tensorflow.keras import backend as K
class MulticlassSensitivity(tf.keras.metrics.Metric):
def __init__(self, name='Sensitivity', **kwargs):
super(MulticlassSensitivity, self).__init__(name=name, **kwargs)
self.true_positive = self.add_weight(name='tp', shape=(2,), initializer='zeros')
self.true_negative = self.add_weight(name='tn', shape=(2,), initializer='zeros')
self.false_positive = self.add_weight(name='fp', shape=(2,), initializer='zeros')
self.false_negative = self.add_weight(name='fn', shape=(2,), initializer='zeros')
self.sensitivity = self.add_weight(name='sensitivity', shape=(2,), initializer='zeros')
self.true_class = tf.Variable([False, True])
self.false_class = tf.Variable([True, False])
def update_state(self, y_true, y_pred, sample_weight=None):
threshold = tf.reduce_max(y_pred, axis=-1, keepdims=True)
y_pred = tf.logical_and(y_pred >= threshold, tf.abs(y_pred) > 1e-12)
y_true = tf.cast(y_true, tf.bool)
y_pred = tf.cast(y_pred, tf.bool)
values = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, True))
values = tf.cast(values, self.dtype)
self.true_positive.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, False), tf.equal(y_pred, True))
values = tf.cast(values, self.dtype)
self.false_positive.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, False), tf.equal(y_pred, False))
values = tf.cast(values, self.dtype)
self.true_negative.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, False))
values = tf.cast(values, self.dtype)
self.false_negative.assign_add(tf.reduce_sum(values, axis=0))
def result(self):
self.sensitivity.assign(tf.math.divide_no_nan(self.true_positive,tf.math.add(self.true_positive,self.false_negative)))
return self.sensitivity[1]
def get_config(self):
"""Returns the config"""
config = {
'num_classes':2
}
base_config = super().get_config()
return {**base_config, **config}
def reset_states(self):
reset_value = tf.zeros(2, dtype=self.dtype)
K.batch_set_value([(v, reset_value) for v in self.variables])
class MulticlassSpecificity(tf.keras.metrics.Metric):
def __init__(self, name='Specificity', **kwargs):
super(MulticlassSpecificity, self).__init__(name=name, **kwargs)
self.true_positive = self.add_weight(name='tp', shape=(2,), initializer='zeros')
self.true_negative = self.add_weight(name='tn', shape=(2,), initializer='zeros')
self.false_positive = self.add_weight(name='fp', shape=(2,), initializer='zeros')
self.false_negative = self.add_weight(name='fn', shape=(2,), initializer='zeros')
self.specificity = self.add_weight(name='specificity', shape=(2,), initializer='zeros')
self.true_class = tf.Variable([False, True])
self.false_class = tf.Variable([True, False])
def update_state(self, y_true, y_pred, sample_weight=None):
threshold = tf.reduce_max(y_pred, axis=-1, keepdims=True)
y_pred = tf.logical_and(y_pred >= threshold, tf.abs(y_pred) > 1e-12)
y_true = tf.cast(y_true, tf.bool)
y_pred = tf.cast(y_pred, tf.bool)
values = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, True))
values = tf.cast(values, self.dtype)
self.true_positive.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, False), tf.equal(y_pred, True))
values = tf.cast(values, self.dtype)
self.false_positive.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, False), tf.equal(y_pred, False))
values = tf.cast(values, self.dtype)
self.true_negative.assign_add(tf.reduce_sum(values, axis=0))
values = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, False))
values = tf.cast(values, self.dtype)
self.false_negative.assign_add(tf.reduce_sum(values, axis=0))
def result(self):
self.specificity.assign(tf.math.divide_no_nan(self.true_negative,tf.math.add(self.true_negative, self.false_positive)))
return self.specificity[1]
def get_config(self):
"""Returns the config"""
config = {
'num_classes':2
}
base_config = super().get_config()
return {**base_config, **config}
def reset_states(self):
reset_value = tf.zeros(2, dtype=self.dtype)
K.batch_set_value([(v, reset_value) for v in self.variables])
当我使用model.evaluate()
评估模型时,我得到的结果如下:
对测试集的测试:86/86 [==============================] - 6 s 59女士/步骤——损失:0.2944 - categorical_accuracy: 0.4465 - f1_score: 0.4415 -特异性:0.2740 - 0.8057灵敏度:
(0.29457294940948486,0.4528070390224457,Array ([0.4514866, 0.45412117], dtype=float32),0.33382710814476013,0.6994695663452148)
调用evaluate时,传递return_dict=True。Evaluate将为每个值返回一个标签,您将知道它们是什么。
类似:
print(m.evaluate(x,y,return_dict=True))