В чем разница между тем, что вычисляет печать, и тем, что она возвращает?

#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() ее для тестирования!