Как мне добавить значения пользовательской метрики из пользовательского обратного вызова в «logs», которые мне нужно использовать в tensorboard?

#python #tensorflow #keras #callback

#python #tensorflow #keras #обратный вызов

Вопрос:

Мне нужно реализовать пользовательский обратный вызов для вычисления AUC после каждой эпохи, который мне нужно использовать в качестве показателя в нейронной сети на основе LSTM. Это пользовательский обратный вызов:

 from tensorflow.keras.callbacks import Callback
class RocCallback(Callback):
    def __init__(self,training_data,validation_data):
        self.x = training_data[0]
        self.y = training_data[1]
        self.x_val = validation_data[0]
        self.y_val = validation_data[1]

        

    def on_train_begin(self, logs={}):
        self.roc_train_list = []
        self.roc_val_list = []
        self.roc_train=0
        self.roc_val=0
        logs["roc_train"] = []
        logs["roc_val"] = []
        return 


    def on_epoch_end(self, epoch, logs):
        y_pred_train = self.model.predict(self.x)
        roc_train = roc_auc_score(self.y, y_pred_train)
        y_pred_val = self.model.predict(self.x_val)
        roc_val = roc_auc_score(self.y_val, y_pred_val)
        #print('rroc-auc_train: %s - roc-auc_val: %s' % (str(round(roc_train,4)),str(round(roc_val,4))),end=100*' ' 'n')
        
        # self.history['roc_auc_train'].append(round(roc_train,4))

        # self.history['roc_auc_val'].append(round(roc_val,4))
        self.roc_train = round(roc_train,4)
        self.roc_val = round(roc_val,4) 
        self.roc_train_list.append(self.roc_train)
        self.roc_val_list.append(self.roc_val)
        print("rroc_train: %f — roc_val: %f" %(self.roc_train, self.roc_val))
        
        logs["roc_train"]= self.roc_train
        logs["roc_val"] = self.roc_val

        return logs
  

Есть две вещи, которые не работают должным образом:

  1. print("rroc_train: %f — roc_val: %f" %(self.roc_train, self.roc_val)) Печатается непосредственно перед индикатором выполнения эпохи, но его нужно распечатать сразу после, например:
 Epoch 2/20
roc_train: 0.550000 — roc_val: 0.547800
2561/2561 [==============================] - 89s 35ms/step - loss: 0.5326 - val_loss: 0.4513
Epoch 3/20
roc_train: 0.559800 — roc_val: 0.558000
2561/2561 [==============================] - 88s 34ms/step - loss: 0.5049 - val_loss: 0.4406
  
  1. Журналы в tensorboard имеют только epoch_loss в качестве метрики, но не имеют значений «roc_train» или «roc_val».
    Я пытался
 logs["roc_train"].append(self.roc_train)
logs["roc_val"].append(self.roc_val)
  

но это вызывает ошибку ключа.

Ответ №1:

В качестве быстрой альтернативы, вы пробовали использовать встроенную https://www.tensorflow.org/api_docs/python/tf/keras/metrics/AUC , метрику,

 tf.keras.metrics.AUC(
    num_thresholds=200, curve='ROC', summation_method='interpolation', name=None,
    dtype=None, thresholds=None, multi_label=False, label_weights=None
)
  

на данный момент это может решить вашу проблему.

Ваш код действительно верен; в списке обратных вызовов в model.fit() не могли бы вы, пожалуйста, поместить свой обратный вызов на первую позицию в списке; в моем случае случилось так, что я однажды захотел сохранить в .csv, а обратный вызов CustomMetric () был последним, поэтому .csv был сохранен только с loss и val_loss не с моими пользовательскими метриками.

Комментарии:

1. Частью требования этой задачи является то, что мне нужно использовать пользовательский обратный вызов. В любом случае, я бы хотел научиться делать это правильно. Было бы полезно в долгосрочной перспективе.

2. Вы сделали то, что я рекомендовал в последней части моего ответа?

3. Привет, извините, я забыл упомянуть об этом. Да, я сделал. Я поместил обратные вызовы в качестве первого аргумента в model.fit(). В результате не было никаких изменений. ‘logs’ по-прежнему имеет только epoch_loss.

4. Какую версию TensorFlow вы используете?

5. @sans_mist Я могу подтвердить, что в TensorFlow 2.3 есть какая-то проблема, журналы в моем случае всегда пусты.