Как рассчитать матрицу точности, отзыва, оценки f1, точности и путаницы в одном кадре с использованием тензорного потока - PullRequest
0 голосов
/ 21 марта 2020

Я пытался рассчитать эти метрики, как показано ниже, но я не уверен, что все эти метрики рассчитываются за один раз или нет.

Похоже, что каждая из этих метрик рассчитывается при запуске модели отдельно.

Примечание: «Один раз», я имею в виду тестирование модели только один раз для расчета всех этих метрик.

У меня есть пара запросов: 1> Прежде всего, я хочу знать, вычисляю ли я все эти метрики правильно или нет (независимо от одного короткого замыкания или нет), если нет, пожалуйста, укажите мою ошибку здесь.

2> если эти расчеты метрик верны, то как рассчитать их в одном коротком замыкании?

3> Как интерпретировать вывод матрицы путаницы?

Пример: это проблема классификации с использованием модели CNN. Они пытаются классифицировать сигналы знаков (0, 1, 2, 3, 4, 5). Общее количество классов 6.

def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.009,
      num_epochs = 100, minibatch_size = 64, print_cost = True):
ops.reset_default_graph()                        
tf.set_random_seed(1)                            
seed = 3                                         
(m, n_H0, n_W0, n_C0) = X_train.shape             
n_y = Y_train.shape[1]                            
costs = []                                       

X, Y = create_placeholders(n_H0,n_W0,n_C0,n_y)
parameters = initialize_parameters()
Z3 = forward_propagation(X,parameters)
cost = compute_cost(Z3,Y)
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

init = tf.global_variables_initializ
er()
with tf.Session() as sess:
    sess.run(init)

    # Do the training loop
    for epoch in range(num_epochs):

        minibatch_cost = 0.
        num_minibatches = int(m / minibatch_size) 
        seed = seed + 1
        minibatches = random_mini_batches(X_train, Y_train, minibatch_size, seed)

        for minibatch in minibatches:

            (minibatch_X, minibatch_Y) = minibatch

            _ , temp_cost = sess.run([optimizer,cost],feed_dict={X:minibatch_X,Y:minibatch_Y})

            minibatch_cost += temp_cost / num_minibatches


        # Print the cost every epoch
        if print_cost == True and epoch % 5 == 0:
            print ("Cost after epoch %i: %f" % (epoch, minibatch_cost))
        if print_cost == True and epoch % 1 == 0:
            costs.append(minibatch_cost)


    # plot the cost
    plt.plot(np.squeeze(costs))
    plt.ylabel('cost')
    plt.xlabel('iterations (per tens)')
    plt.title("Learning rate =" + str(learning_rate))
    plt.show()

    # Calculate the correct predictions
    predict_op = tf.argmax(Z3, 1)
    correct_prediction = tf.equal(predict_op, tf.argmax(Y, 1))

    # Calculate accuracy on the test set
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

    # 6 here is class for classifier.
    onehot_prediction = tf.one_hot(predict_op, 6)
    onehot_y = tf.one_hot(tf.argmax(Y, 1), 6)

    TP = tf.count_nonzero(onehot_prediction * onehot_y, dtype=tf.float32)
    TN = tf.count_nonzero((onehot_prediction - 1) * (onehot_y - 1), dtype=tf.float32)
    FP = tf.count_nonzero(onehot_prediction * (onehot_y - 1), dtype=tf.float32)
    FN = tf.count_nonzero((onehot_prediction - 1) * onehot_y, dtype=tf.float32)

    precision = TP / (TP + FP)
    recall = TP / (TP + FN)
    f1 = 2 * precision * recall / (precision + recall)

    confusion_mat = tf.confusion_matrix(labels=tf.argmax(Y, 1), predictions=predict_op)


    (train_accuracy, train_precision, train_recall, 
     train_f1_score, train_conf_matrix) = sess.run([accuracy, precision, recall, 
                                                    f1, confusion_mat], 
                                                   ({X: X_train, Y: Y_train}))
    (test_accuracy, test_precision, test_recall, 
     test_f1_score, test_conf_matrix) = sess.run([accuracy, precision, recall, 
                                                 f1, confusion_mat], 
                                                 ({X: X_test, Y: Y_test}))
    print("==== Train Report ========")
    print("Train Accuracy: {}".format(train_accuracy))
    print("Test Accuracy: {}:".format(train_accuracy))
    print("F1 score : {}".format(train_f1_score))
    print("precision: {}".format(train_precision))
    print("recall: {}".format(train_recall))
    print("confusion_matrix: {}".format(train_conf_matrix))

    print("==== Test Report ========")
    print("Train Accuracy: {}".format(test_accuracy))
    print("Test Accuracy: {}:".format(test_accuracy))
    print("F1 score : {}".format(test_f1_score))
    print("precision: {}".format(test_precision))
    print("recall: {}".format(test_recall))
    print("confusion_matrix: {}".format(test_conf_matrix))

    return train_accuracy, test_accuracy, parameters




`# Call model     
 _, _, parameters = model(X_train, Y_train, X_test, Y_test)

 **Output:**
 ==== Train Report ========
 Train Accuracy: 0.6731481552124023
 Test Accuracy: 0.6731481552124023:
 F1 score : 0.6731481552124023
 precision: 0.6731481552124023
 recall: 0.6731481552124023
 confusion_matrix: [[150   5   2   3  14   6]
 [  2 100  36   7  26   9]
 [  3  20 113  12  28   4]
 [  4   5  23 120  17  11]
 [  9  12  34   6 103  16]
 [ 11   1  11   4  12 141]]
 ==== Test Report ========
 Train Accuracy: 0.5333333611488342
 Test Accuracy: 0.5333333611488342:
 F1 score : 0.5333333611488342
 precision: 0.5333333611488342
 recall: 0.5333333611488342
 confusion_matrix: [[16  1  0  1  1  1]
 [ 0 10  3  2  5  0]
 [ 3  3  6  3  4  1]
 [ 0  1  6 10  3  0]
 [ 2  0  2  5  9  2]
 [ 2  0  2  1  2 13]]

 In [39]`

1 Ответ

0 голосов
/ 03 апреля 2020

Для классификации по мультиклассу вы можете следовать следующим образом:

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
import numpy as np
from tensorflow.keras.callbacks import Callback 
from sklearn.metrics import classification_report

(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

train_images = train_images.reshape((60000, 28, 28, 1))
test_images = test_images.reshape((10000, 28, 28, 1))

train_images, test_images = train_images / 255.0, test_images / 255.0

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))

model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

class MetricsCallback(Callback):
    def __init__(self, test_data, y_true):
        self.y_true = y_true
        self.test_data = test_data

    def on_epoch_end(self, epoch, logs=None):
         y_pred = self.model.predict(self.test_data)
         y_pred = tf.argmax(y_pred,axis=1)
         report_dictionary = classification_report(self.y_true, y_pred, output_dict = True)
         print(classification_report(self.y_true,y_pred,output_dict=False)) 

metrics_callback = MetricsCallback(test_data=test_images, y_true=test_labels)

model.fit(train_images, 
            train_labels, 
            epochs=1, 
            validation_data=(test_images, test_labels), callbacks=[metrics_callback])

Выход:

59904/60000 [============================>.] - ETA: 0s - loss: 0.0049 - accuracy: 0.9984    

                precision    recall  f1-score   support    
           0       1.00      1.00      1.00       980
           1       0.99      1.00      1.00      1135
           2       0.99      0.99      0.99      1032
           3       0.99      1.00      0.99      1010
           4       0.98      0.99      0.99       982
           5       0.99      0.99      0.99       892
           6       1.00      0.98      0.99       958
           7       0.99      0.99      0.99      1028
           8       0.99      0.99      0.99       974
           9       0.99      0.98      0.99      1009

    accuracy                           0.99     10000
   macro avg       0.99      0.99      0.99     10000
weighted avg       0.99      0.99      0.99     10000

Где для двоичной классификации вы можете использовать встроенный аккумулятор, как показано ниже

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy',tf.keras.metrics.Precision(),tf.keras.metrics.Recall()])
...