【问题标题】:Finding precision and recall for MNIST dataset using TensorFlow使用 TensorFlow 查找 MNIST 数据集的精度和召回率
【发布时间】:2021-08-16 04:14:30
【问题描述】:

我正在使用本教程来学习如何在 MNIST 数据集上训练模型:https://www.tensorflow.org/tutorials/quickstart/beginner

目前,模型只训练准确率,但我想计算模型的 F1-score(从准确率开始,首先是召回率)。

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(128, activation='relu'),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10)
])
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam',
              loss=loss_fn,
              metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5)
Epoch 1/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.2895 - accuracy: 0.9151
Epoch 2/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.1393 - accuracy: 0.9586
...

显然,该模型还使用了对数奇数分数,这些分数也通过 softmax 转换为概率。

不过,这是我的问题。我尝试将model.compile 中的指标更改为metrics=[tf.keras.metrics.Precision()],但出现错误 ValueError: Shapes (32, 10) and (32, 1) are incompatible

我也尝试通过 scikit-learn 计算precisiona和recall,但我的预测与真实标签不一致。

y_pred = model.predict(x_test)
print(y_pred)
precision_score(y_test, y_pred)

输出:

[[ -4.7507367   -7.4252934   -2.8428416  ...   8.855136    -5.937388
   -2.1762638 ]
 [ -5.0433793    5.554433    12.963128   ... -18.583       -1.6025407
  -18.721622  ]
 [ -7.623428     6.3951      -1.8510209  ...   0.37932196  -1.2399373
   -6.59459   ]
 ...
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-44-a82c4d76f544> in <module>()
      1 y_pred = model.predict(x_test)
      2 print(y_pred)
----> 3 precision_score(y_test, y_pred)

ValueError: Classification metrics can't handle a mix of multiclass and continuous-multioutput targets

我想我可能需要转换 y_pred,但我不确定如何。或者,如果有一种方法可以为指标增加精确度和召回率,那就更好了。如何获得此模型的准确率和召回率?

【问题讨论】:

  • 我很确定用于精度和召回率的 tf 指标只能处理单类目标。你有一个多类问题。 y_pred 和 y_test 的形状是什么? y_test 是一组二进制 (0,1) 数?
  • 这是我遇到的问题,但幸运的是,您可以添加一个平均参数,如下面的解决方案所示 @kjans_tbme

标签: python tensorflow mnist


【解决方案1】:

假设您使用代码进行预测:

predicted_result=model.predict(x_test)

输出层有数字0到9的概率,即10。因此需要从预测结果中识别类。

import numpy as np
class_preds = np.argmax(predicted_result, axis=-1)

现在,y_test 和 class_preds 在类中,所以可以运行precision_score。

from sklearn.metrics import precision_score
precision_score(y_test, class_preds,average='macro')

from sklearn.metrics import recall_score
recall_score(y_test, class_preds,average='macro')

甚至可以将此自定义函数提供给指标:

from sklearn.metrics import precision_score
def custom_prec_score(y_true, y_pred):
    y_true=y_true.numpy()
    y_pred=y_pred.numpy()
    y_pred=np.argmax(y_pred, axis=-1)
    return precision_score(y_true, y_pred,average='macro')
model.compile(optimizer='adam',
              loss=loss_fn,run_eagerly=True,
              metrics=["accuracy",custom_prec_score])
model.fit(x_train, y_train, epochs=5)

【讨论】:

  • 啊,argmax 和平均参数很有意义!谢谢!
猜你喜欢
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 2023-02-01
  • 2023-04-07
  • 2011-11-01
  • 2020-02-25
  • 2012-11-26
  • 2014-02-20
相关资源
最近更新 更多