web-dev-qa-db-ja.com

Kerasで精度とリコールを計算する方法

Keras 2.02(Tensorflowバックエンドを使用)でマルチクラス分類器を構築しています。Kerasで精度とリコールを計算する方法がわかりません。私を助けてください。

38
Jimmy Du

Pythonパッケージ keras-metrics はこれに役立ちます(私はパッケージの作成者です)。

import keras
import keras_metrics

model = models.Sequential()
model.add(keras.layers.Dense(1, activation="sigmoid", input_dim=2))
model.add(keras.layers.Dense(1, activation="softmax"))

model.compile(optimizer="sgd",
              loss="binary_crossentropy",
              metrics=[keras_metrics.precision(), keras_metrics.recall()])
33
Yasha Bubnov

Keras 2.0では、masterブランチから精度とリコールが削除されました。それらを自分で実装する必要があります。カスタムメトリックを作成するには、このガイドに従ってください: Here

精度とリコールの方程式を見つけることができます ここ

または、削除される前にkerasのコードを再利用します Here

メトリックはバッチ単位であるため削除されたため、値は正しい場合と正しくない場合があります。

30
Dref360

私の答えは Keras GH問題のコメント に基づいています。ワンホットエンコードされた分類タスクのすべてのエポックで検証精度とリコールを計算します。また、これを見てください SO回答keras.backend機能を使用してそれを行う方法を確認してください。

import keras as keras
import numpy as np
from keras.optimizers import SGD
from sklearn.metrics import precision_score, recall_score

model = keras.models.Sequential()
# ...
sgd = SGD(lr=0.001, momentum=0.9)
model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])


class Metrics(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self._data = []

    def on_Epoch_end(self, batch, logs={}):
        X_val, y_val = self.validation_data[0], self.validation_data[1]
        y_predict = np.asarray(model.predict(X_val))

        y_val = np.argmax(y_val, axis=1)
        y_predict = np.argmax(y_predict, axis=1)

        self._data.append({
            'val_recall': recall_score(y_val, y_predict),
            'val_precision': precision_score(y_val, y_predict),
        })
        return

    def get_data(self):
        return self._data


metrics = Metrics()
history = model.fit(X_train, y_train, epochs=100, validation_data=(X_val, y_val), callbacks=[metrics])
metrics.get_data()
4
vogdb

このスレッドは少し古いですが、念のためここに着陸する誰かを助けます。 Keras v2.1.6にアップグレードする場合は、ステートフルメトリックを機能させるために多くの作業が行われていますが、さらに作業が行われているようです( https://github.com/keras -team/keras/pull/9446 )。

とにかく、精度/リコールを統合する最良の方法は、 BinaryTruePositives の例で示されているLayerをサブクラス化するカスタムメトリックを使用することです。

思い出してください。これは次のようになります。

class Recall(keras.layers.Layer):
    """Stateful Metric to count the total recall over all batches.

    Assumes predictions and targets of shape `(samples, 1)`.

    # Arguments
        name: String, name for the metric.
    """

    def __init__(self, name='recall', **kwargs):
        super(Recall, self).__init__(name=name, **kwargs)
        self.stateful = True

        self.recall = K.variable(value=0.0, dtype='float32')
        self.true_positives = K.variable(value=0, dtype='int32')
        self.false_negatives = K.variable(value=0, dtype='int32')
    def reset_states(self):
        K.set_value(self.recall, 0.0)
        K.set_value(self.true_positives, 0)
        K.set_value(self.false_negatives, 0)

    def __call__(self, y_true, y_pred):
        """Computes the number of true positives in a batch.

        # Arguments
            y_true: Tensor, batch_wise labels
            y_pred: Tensor, batch_wise predictions

        # Returns
            The total number of true positives seen this Epoch at the
                completion of the batch.
        """
        y_true = K.cast(y_true, 'int32')
        y_pred = K.cast(K.round(y_pred), 'int32')

        # False negative calculations
        y_true = K.cast(y_true, 'int32')
        y_pred = K.cast(K.round(y_pred), 'int32')
        false_neg = K.cast(K.sum(K.cast(K.greater(y_pred, y_true), 'int32')), 'int32')
        current_false_neg = self.false_negatives * 1
        self.add_update(K.update_add(self.false_negatives,
                                     false_neg),
                        inputs=[y_true, y_pred])
        # True positive  calculations
        correct_preds = K.cast(K.equal(y_pred, y_true), 'int32')
        true_pos = K.cast(K.sum(correct_preds * y_true), 'int32')
        current_true_pos = self.true_positives * 1
        self.add_update(K.update_add(self.true_positives,
                                     true_pos),
                        inputs=[y_true, y_pred])
        # Combine
        recall = (K.cast(self.true_positives, 'float32') / (K.cast(self.true_positives, 'float32') + K.cast(self.false_negatives, 'float32') + K.cast(K.epsilon(), 'float32')))
        self.add_update(K.update(self.recall,
                                     recall),
                        inputs=[y_true, y_pred])

        return recall   
1
vsocrates

これにはScikit Learnフレームワークを使用します。

from sklearn.metrics import classification_report

history = model.fit(x_train, y_train, batch_size=32, epochs=10, verbose=1, validation_data=(x_test, y_test), shuffle=True)
pred = model.predict(x_test, batch_size=32, verbose=1)
predicted = np.argmax(pred, axis=1)
report = classification_report(np.argmax(y_test, axis=1), predicted)
print(report)

このブログ は非常に便利です。

0
Jesús Utrera