#tensorflow
#tensorflow
Вопрос:
Я написал пользовательскую метрику для специфичности и чувствительности и передал ее в качестве метрики в 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 [==============================] — 6s 59 мс / шаг — потеря: 0,2944 — категориальная точность: 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]
Ответ №1:
при вызове evaluate передайте return_dict=True . Evaluate вернет метку для каждого значения, и вы узнаете, что это такое.
Что-то вроде:
print(m.evaluate(x,y,return_dict=True))
Комментарии:
1. Судя по значениям, я могу предположить, что они находятся в том же порядке, что и напечатанные, но я спрашиваю, если это так, то почему последние два значения такие разные?
2. вы не предоставили весь код, поэтому я немного смущен. Вы использовали fit() для первого обучения своей модели, а теперь используете evaluate() . Это верно?
3. Да, я обучил свою модель, используя
model.fit()
и после этого использовалmodel.evaluate()
ее для тестирования!