代码之家  ›  专栏  ›  技术社区  ›  ScalaBoy

无法为Keras模型开发自定义度量

  •  -1
  • ScalaBoy  · 技术社区  · 6 年前

    这是我的模型:

    nb_classes = 4
    
    model = Sequential()
    
    model.add(LSTM(
                    units=50,
                    return_sequences=True, 
                    input_shape=(20,18),
                    dropout=0.2, 
                    recurrent_dropout=0.2
                  )
             )
    
    model.add(Dropout(0.2))
    
    model.add(Flatten())
    
    model.add(Dense(units=nb_classes,
                   activation='softmax'))
    
    model.compile(loss="categorical_crossentropy",optimizer='adadelta')
    
    
    history = model.fit(np.array(X_train), y_train, 
                        validation_data=(np.array(X_test), y_test),
                        epochs=50,
                        batch_size=2,
                        callbacks=[model_metrics],
                        shuffle=False,
                        verbose=1)
    

    这是怎么回事 model_metrics 定义如下:

    class Metrics(Callback):
    
        def on_train_begin(self, logs={}):
            self.val_f1s = []
            self.val_recalls = []
            self.val_precisions = []
    
        def on_epoch_end(self, epoch, logs={}):
            val_predict = np.argmax((np.asarray(self.model.predict(self.validation_data[0]))).round(), axis=1)
            val_targ = np.argmax(self.validation_data[1], axis=1)
            _val_f1 = metrics.f1_score(val_targ, val_predict, average='weighted')
            _val_recall = metrics.recall_score(val_targ, val_predict, average='weighted')
            _val_precision = metrics.precision_score(val_targ, val_predict, average='weighted')
            self.val_f1s.append(_val_f1)
            self.val_recalls.append(_val_recall)
            self.val_precisions.append(_val_precision)
            print(" — val_f1: %f — val_precision: %f — val_recall %f".format(_val_f1, _val_precision, _val_recall))
            return
    
    model_metrics = Metrics() 
    

    fit ,我得到这个结果:

    Train on 400 samples, validate on 80 samples
    Epoch 1/50
    400/400 [==============================] - 7s 17ms/step - loss: 0.6892 - val_loss: 4.8016
     — val_f1: %f — val_precision: %f — val_recall %f
    Epoch 2/50
     20/400 [>.............................] - ETA: 3s - loss: 2.8010
    /Users/tau/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py:1143: UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 in labels with no predicted samples.
      'precision', 'predicted', average, warn_for)
    /Users/tau/anaconda3/lib/python3.6/site-packages/sklearn/metrics/classification.py:1143: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples.
      'precision', 'predicted', average, warn_for)
    400/400 [==============================] - 3s 9ms/step - loss: 0.7593 - val_loss: 4.5832
     — val_f1: %f — val_precision: %f — val_recall %f
    Epoch 3/50
    400/400 [==============================] - 4s 9ms/step - loss: 0.6809 - val_loss: 4.9039
     — val_f1: %f — val_precision: %f — val_recall %f
    

    你可以看到 val_f1: %f — val_precision: %f — val_recall %f . 没有度量值。为什么?我做错了什么?

    1 回复  |  直到 6 年前
        1
  •  0
  •   Dmytro Prylipko    6 年前

    你的问题不在凯拉斯。您正在使用Python string formatting 错误的以下是正确的用法:

    print(" — val_f1: {:f} — val_precision: {:f} — val_recall {:f}".format(_val_f1, _val_precision, _val_recall))
    

    或者:

    print(" — val_f1: %f — val_precision: %f — val_recall %f" % (_val_f1, _val_precision, _val_recall))