Python 如何在Tensorflow 2.0中获得其他指标(不仅仅是准确性)?
我是Tensorflow领域的新手,正在研究mnist数据集分类的简单示例。我想知道,除了准确度和损失(并可能显示)之外,我如何获得其他指标(例如精度、召回率等)。这是我的密码:Python 如何在Tensorflow 2.0中获得其他指标(不仅仅是准确性)?,python,tensorflow,machine-learning,keras,tensorflow2.x,Python,Tensorflow,Machine Learning,Keras,Tensorflow2.x,我是Tensorflow领域的新手,正在研究mnist数据集分类的简单示例。我想知道,除了准确度和损失(并可能显示)之外,我如何获得其他指标(例如精度、召回率等)。这是我的密码: from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf from tensorflow.keras.callbacks import ModelCheckpoin
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.callbacks import TensorBoard
import os
#load mnist dataset
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#create and compile the model
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, activation='softmax')
])
model.summary()
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
#model checkpoint (only if there is an improvement)
checkpoint_path = "logs/weights-improvement-{epoch:02d}-{accuracy:.2f}.hdf5"
cp_callback = ModelCheckpoint(checkpoint_path, monitor='accuracy',save_best_only=True,verbose=1, mode='max')
#Tensorboard
NAME = "tensorboard_{}".format(int(time.time())) #name of the model with timestamp
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME))
#train the model
model.fit(x_train, y_train, callbacks = [cp_callback, tensorboard], epochs=5)
#evaluate the model
model.evaluate(x_test, y_test, verbose=2)
既然我只得到准确度和损失,我怎么能得到其他指标?
提前感谢您,如果这是一个简单的问题,或者已经在某个地方得到了回答,我很抱歉。文档中有可用指标的列表。它包括
召回
,精度
等
例如:
从TensorFlow 2.X开始,
precision
和recall
都是内置的度量标准
因此,您不需要手动实现它们。除此之外,在Keras 2.X版本中,它们被删除是因为它们具有误导性——因为它们是以批处理方式计算的,精确性和召回率的全局(真实)值实际上是不同的
您可以在这里查看:
现在他们有了一个内置的累加器,可以确保正确计算这些指标
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy',tf.keras.metrics.Precision(),tf.keras.metrics.Recall()])
有关受支持指标的列表,请参阅:
我无法得到Timbus的工作答案,我发现了一个非常有趣的解释 它说:
准确度的含义取决于损失函数。与稀疏分类交叉熵相对应的是tf.keras.metrics.SparseCategoricalAccuracy(),而不是tf.metrics.accurity()。
这很有道理
因此,您可以使用什么标准取决于您选择的损失。例如,在SparseCategoricalAccuracy的情况下,使用度量“真正数”不起作用,因为这种损失意味着您使用的是多个类,这反过来意味着不能定义真正数,因为它仅用于二进制分类问题
像tf.keras.metrics.CategoricalCrossentropy()
这样的损失将起作用,因为它在设计时考虑了多个类!例如:
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.callbacks import TensorBoard
import time
import os
#load mnist dataset
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#create and compile the model
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, activation='softmax')
])
model.summary()
# This will work because it makes sense
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=[tf.keras.metrics.SparseCategoricalAccuracy(),
tf.keras.metrics.CategoricalCrossentropy()])
# This will not work because it isn't designed for the multiclass classification problem
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=[tf.keras.metrics.SparseCategoricalAccuracy(),
tf.keras.metrics.TruePositives()])
#model checkpoint (only if there is an improvement)
checkpoint_path = "logs/weights-improvement-{epoch:02d}-{accuracy:.2f}.hdf5"
cp_callback = ModelCheckpoint(checkpoint_path,
monitor='accuracy',
save_best_only=True,
verbose=1,
mode='max')
#Tensorboard
NAME = "tensorboard_{}".format(int(time.time())) # name of the model with timestamp
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME))
#train the model
model.fit(x_train, y_train, epochs=5)
#evaluate the model
model.evaluate(x_test, y_test, verbose=2)
在我的例子中,其他两个答案给了我形状不匹配的问题。我添加了另一个答案,因为这是在测试集上正确计算这些度量的最干净的方法(截至2020年3月22日) 您需要做的第一件事是创建一个自定义回调,在其中发送测试数据:
import tensorflow as tf
from tensorflow.keras.callbacks import Callback
from sklearn.metrics import classification_report
class MetricsCallback(Callback):
def __init__(self, test_data, y_true):
# Should be the label encoding of your classes
self.y_true = y_true
self.test_data = test_data
def on_epoch_end(self, epoch, logs=None):
# Here we get the probabilities
y_pred = self.model.predict(self.test_data))
# Here we get the actual classes
y_pred = tf.argmax(y_pred,axis=1)
# Actual dictionary
report_dictionary = classification_report(self.y_true, y_pred, output_dict = True)
# Only printing the report
print(classification_report(self.y_true,y_pred,output_dict=False)
在main中,加载数据集并添加回调:
您提供的链接指向Keras文档,这与TensorFlow中的Keras文档不同。此外,实现它们的一个例子清楚地表明,它们更多的是误导,而不是帮助。为其他内置指标创建自定义的
回调对我来说没有任何意义。我想这应该是公认的答案。谢谢你的帮助,它起作用了!我尝试了其他人的评论,但我得到了一个错误,因为我的不是一个二进制分类问题,因为我有10个类,因此我在精确度和召回率方面得到了一个错误。是否有机会计算它们?感谢you@Diane.95今天工作日结束后,我会带着一个好的答案回来。@Victor Sonck顺便说一句,如果你想查看的话,我上面的答案现在适用于multiclass(简短的提醒,因为我不知道你的线程在哪里):谢谢!在这种情况下,我的问题不是二进制分类,因为我有10个类,所以我得到一个错误。是否有一种方法可以计算多类问题的精确度/召回率或其他有用指标?感谢you@Diane.95今天,在工作日结束后,我会回来给你一个答案。这不起作用,因为你不能用稀疏分类交叉熵计算精度和召回率,因为(我认为)它们是为二进制分类问题设计的。谢谢你的时间和答案!我检查了代码,创建了对象metrics\u callback=MetricsCallback(test\u data=x\u train,y\u true=y\u train)。但是,当我拟合模型时,我得到一个错误:“report\u dictionary=classification\u report(y\u true,y\u pred,output\u dict=true)”上的“name'y\u true'未定义”,即使我正在传递参数:(我们忘了通过“self”。:D.所以应该是self.y_-True谢谢Timbus!这非常有帮助,你是最棒的。很高兴看到你解决了你的问题。既然你接受了答案,请你也投票好吗?谢谢你,很高兴帮助了你。@TimbusCalin,我正在尝试使用metrics_回调作为我的用例,但当我尝试model.fit时我收到“名称错误:名称‘分类报告’未定义”。请帮助我。
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.callbacks import TensorBoard
import time
import os
#load mnist dataset
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#create and compile the model
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, activation='softmax')
])
model.summary()
# This will work because it makes sense
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=[tf.keras.metrics.SparseCategoricalAccuracy(),
tf.keras.metrics.CategoricalCrossentropy()])
# This will not work because it isn't designed for the multiclass classification problem
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=[tf.keras.metrics.SparseCategoricalAccuracy(),
tf.keras.metrics.TruePositives()])
#model checkpoint (only if there is an improvement)
checkpoint_path = "logs/weights-improvement-{epoch:02d}-{accuracy:.2f}.hdf5"
cp_callback = ModelCheckpoint(checkpoint_path,
monitor='accuracy',
save_best_only=True,
verbose=1,
mode='max')
#Tensorboard
NAME = "tensorboard_{}".format(int(time.time())) # name of the model with timestamp
tensorboard = TensorBoard(log_dir="logs/{}".format(NAME))
#train the model
model.fit(x_train, y_train, epochs=5)
#evaluate the model
model.evaluate(x_test, y_test, verbose=2)
import tensorflow as tf
from tensorflow.keras.callbacks import Callback
from sklearn.metrics import classification_report
class MetricsCallback(Callback):
def __init__(self, test_data, y_true):
# Should be the label encoding of your classes
self.y_true = y_true
self.test_data = test_data
def on_epoch_end(self, epoch, logs=None):
# Here we get the probabilities
y_pred = self.model.predict(self.test_data))
# Here we get the actual classes
y_pred = tf.argmax(y_pred,axis=1)
# Actual dictionary
report_dictionary = classification_report(self.y_true, y_pred, output_dict = True)
# Only printing the report
print(classification_report(self.y_true,y_pred,output_dict=False)
metrics_callback = MetricsCallback(test_data = my_test_data, y_true = my_y_true)
...
...
#train the model
model.fit(x_train, y_train, callbacks = [cp_callback, metrics_callback,tensorboard], epochs=5)