Значения метрик при подборе и оценке не совпадают (tf+keras) ⇐ Python
Значения метрик при подборе и оценке не совпадают (tf+keras)
У меня возникла проблема, которую я подробно описал ниже. Возможно это моя ошибка, но я стараюсь это исправить не за один день.
Я максимально упростил задачу, подобрав модель, чтобы точно показать вам проблему.
Пусть это будет не предварительно обученная модель ResNet50. И давайте я предоставлю набор данных простым способом, где X_train и Y_train — это ndarray с соответствующими формами [N, 32, 32, 3] и [N, class_num=3].
Я установил пакетный_размер=128, перемешивание=False. Теперь я подгоняю свою модель и после последней эпохи получаю метрику, равную 0,976, НО Если я просто создам model.evaluate(X_train), где X_train — это те же данные, которые я использую при подгонке, я получу совершенно другое значение — 0,456. Вопрос - ПОЧЕМУ?
Это логи моей настройки: 263/263 [=============================] - 7 с 27 мс/шаг - потеря: 0,2063 - auc: 0,9899 - mc_f1 : 0,9326
Это после оценки: 1052/1052 [=============================] - 11 с 9 мс/шаг - потеря: 0,6186 - auc: 0,9053 - mc_f1 : 0,4993
Во избежание вопросов — mc_f1 — это специальная метрика — среднее значение f1, рассчитанное для каждого класса отдельно для случая мультикласса.
Итак, код:
Показатель:
класс MulticlassF1(tf.keras.metrics.Metric): def __init__(self, name='mc_f1', num_classes=None, **kwargs): super(MulticlassF1, self).__init__(name=name, **kwargs) self.__zero_support = tf.cast(1e-7, dtype=tf.float16) self.__cm = self.add_weight(name='fn', Initializer='zeros', shape=[num_classes, num_classes]) если num_classes не равен None: self.__num_classes = num_classes def update_state(self, y_true, y_pred, sample_weight=None): y_pred = K.argmax(y_pred, ось=1) y_true = K.argmax(y_true, ось = 1) m = tf.math.confusion_matrix(y_true, y_pred, num_classes=self.__num_classes, dtype=tf.float32) self.__cm.assign_add(м) защита reset_state (сам): self.__cm.assign(tf.zeros((self.__num_classes, self.__num_classes))) результат определения (сам): знаменатель = 0 м = сам.__см для меня в диапазоне (m.shape[0]): tp = м[я, я] fn = K.sum(m[:, i]) - tp fp = K.sum(m[i, :]) - tp tn = K.sum(K.flatten(m)) - (tp + fn + fp) tp = K.cast(tp, dtype=tf.float16) tn = K.cast(tn, dtype=tf.float16) fp = K.cast(fp, dtype=tf.float16) fn = K.cast(fn, dtype=tf.float16) точность = tp / ((tp + fp) + self.__zero_support) + self.__zero_support отзыв = tp / (tf.cast(tp + fn, dtype=tf.float16) + self.__zero_support) + self.__zero_support знаменатель += (1 / точность + 1 / отзыв) f1_combined = K.cast(2 * m.shape[0] / знаменатель, dtype=tf.float32) вернуть f1_комбинированный Объявление модели
def get_resnet50_model(window_size,classes): # Инициализация модели модель = tf.keras.applications.ResNet50V2( include_top = Ложь, веса = Нет, input_tensor = Нет, input_shape = размер_окна, пул = 'макс', классы = классы, ) # Изменить последние слои последний_слой = модель.выход вывод = tf.keras.layers.Dense(classes, active="softmax")(last_layer) модель = tf.keras.models.Model(входные данные=model.inputs, выходные данные=выходные) возвратная модель mcf1 = МультиклассF1(num_classes=3) resnet50 = get_resnet50_model([32, 32, 3], 3) resnet50.compile( оптимизатор = Адам(), loss=tf.keras.losses.CategoricalCrossentropy(), metrics=[tf.metrics.AUC(name='auc'), mcf1], ) Монтаж:
deb_metric_callback = DebugMetricCallback(resnet50, (X_train, Y_train), mcf1) resnet50.fit( X_train, Y_train, эпохи=100, размер_пакета = 128, # подробный = 0, перемешать = Ложь, обратные вызовы = [deb_metric_callback], ) Я попытался выполнить отладку и сделать обратный вызов:
класс DebugMetricCallback(Callback): def __init__(self, model, test, metr): супер().__init__() self.__model = модель self.test = тест self.metric = метр def on_epoch_end(self, epoch, logs=None): печать(self.metric.result()) x, y = самотестирование y_pred = self.model.predict(x) inline_measure = MulticlassF1 (num_classes=3) inline_measure.update_state(y, y_pred) print(self.metric.result().numpy(), inline_measure.result().numpy()) Здесь я получаю совершенно другие матрицы путаницы.
Также я думал о пакетной нормализации, но сохраняю и сравниваю модель до и после оценки, она не изменилась.
У меня возникла проблема, которую я подробно описал ниже. Возможно это моя ошибка, но я стараюсь это исправить не за один день.
Я максимально упростил задачу, подобрав модель, чтобы точно показать вам проблему.
Пусть это будет не предварительно обученная модель ResNet50. И давайте я предоставлю набор данных простым способом, где X_train и Y_train — это ndarray с соответствующими формами [N, 32, 32, 3] и [N, class_num=3].
Я установил пакетный_размер=128, перемешивание=False. Теперь я подгоняю свою модель и после последней эпохи получаю метрику, равную 0,976, НО Если я просто создам model.evaluate(X_train), где X_train — это те же данные, которые я использую при подгонке, я получу совершенно другое значение — 0,456. Вопрос - ПОЧЕМУ?
Это логи моей настройки: 263/263 [=============================] - 7 с 27 мс/шаг - потеря: 0,2063 - auc: 0,9899 - mc_f1 : 0,9326
Это после оценки: 1052/1052 [=============================] - 11 с 9 мс/шаг - потеря: 0,6186 - auc: 0,9053 - mc_f1 : 0,4993
Во избежание вопросов — mc_f1 — это специальная метрика — среднее значение f1, рассчитанное для каждого класса отдельно для случая мультикласса.
Итак, код:
Показатель:
класс MulticlassF1(tf.keras.metrics.Metric): def __init__(self, name='mc_f1', num_classes=None, **kwargs): super(MulticlassF1, self).__init__(name=name, **kwargs) self.__zero_support = tf.cast(1e-7, dtype=tf.float16) self.__cm = self.add_weight(name='fn', Initializer='zeros', shape=[num_classes, num_classes]) если num_classes не равен None: self.__num_classes = num_classes def update_state(self, y_true, y_pred, sample_weight=None): y_pred = K.argmax(y_pred, ось=1) y_true = K.argmax(y_true, ось = 1) m = tf.math.confusion_matrix(y_true, y_pred, num_classes=self.__num_classes, dtype=tf.float32) self.__cm.assign_add(м) защита reset_state (сам): self.__cm.assign(tf.zeros((self.__num_classes, self.__num_classes))) результат определения (сам): знаменатель = 0 м = сам.__см для меня в диапазоне (m.shape[0]): tp = м[я, я] fn = K.sum(m[:, i]) - tp fp = K.sum(m[i, :]) - tp tn = K.sum(K.flatten(m)) - (tp + fn + fp) tp = K.cast(tp, dtype=tf.float16) tn = K.cast(tn, dtype=tf.float16) fp = K.cast(fp, dtype=tf.float16) fn = K.cast(fn, dtype=tf.float16) точность = tp / ((tp + fp) + self.__zero_support) + self.__zero_support отзыв = tp / (tf.cast(tp + fn, dtype=tf.float16) + self.__zero_support) + self.__zero_support знаменатель += (1 / точность + 1 / отзыв) f1_combined = K.cast(2 * m.shape[0] / знаменатель, dtype=tf.float32) вернуть f1_комбинированный Объявление модели
def get_resnet50_model(window_size,classes): # Инициализация модели модель = tf.keras.applications.ResNet50V2( include_top = Ложь, веса = Нет, input_tensor = Нет, input_shape = размер_окна, пул = 'макс', классы = классы, ) # Изменить последние слои последний_слой = модель.выход вывод = tf.keras.layers.Dense(classes, active="softmax")(last_layer) модель = tf.keras.models.Model(входные данные=model.inputs, выходные данные=выходные) возвратная модель mcf1 = МультиклассF1(num_classes=3) resnet50 = get_resnet50_model([32, 32, 3], 3) resnet50.compile( оптимизатор = Адам(), loss=tf.keras.losses.CategoricalCrossentropy(), metrics=[tf.metrics.AUC(name='auc'), mcf1], ) Монтаж:
deb_metric_callback = DebugMetricCallback(resnet50, (X_train, Y_train), mcf1) resnet50.fit( X_train, Y_train, эпохи=100, размер_пакета = 128, # подробный = 0, перемешать = Ложь, обратные вызовы = [deb_metric_callback], ) Я попытался выполнить отладку и сделать обратный вызов:
класс DebugMetricCallback(Callback): def __init__(self, model, test, metr): супер().__init__() self.__model = модель self.test = тест self.metric = метр def on_epoch_end(self, epoch, logs=None): печать(self.metric.result()) x, y = самотестирование y_pred = self.model.predict(x) inline_measure = MulticlassF1 (num_classes=3) inline_measure.update_state(y, y_pred) print(self.metric.result().numpy(), inline_measure.result().numpy()) Здесь я получаю совершенно другие матрицы путаницы.
Также я думал о пакетной нормализации, но сохраняю и сравниваю модель до и после оценки, она не изменилась.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение