常 用 评 估 函 数 和 自 定 义 评 估 函 数 常用评估函数和自定义评估函数 常用评估函数和自定义评估函数
1.通用图像分割评价指标
2.自定义模型中自定义评价指标的添加问题
3.Keras模型中自定义评价指标的添加问题
一 常用评估函数
- tf.keras.metrics (tf.metrics的接口均移到这里)
参考网站: https://www.tensorflow.org/versions/r2.0/api_docs/python/tf/keras/metrics
- tf.keras.metrics.BinaryAccuracy
- tf.keras.metrics.binary_accuracy
有什么区别?
前者是类的实现形式,后者是函数的实现形式。
- tf.keras.metrics.MeanAbsoluteError(平方差误差,用于回归,可以简写为MSE,函数形式为mse)
- tf.keras.metrics.MeanAbsoluteError(绝对值误差,用于回归,可以简写为MAE,函数形式为mae)
- tf.keras.metrics.MeanAbsolutePercentageError(平均百分比误差,用于回归,可以简写为MAPE,函数形式为mape)
- tf.keras.metrics.RootMeanSquaredError(均方根误差,用于回归)。
- tf.keras.metrics.Accuracy(准确率,用于分类,可以用字符串"Accuracy"表示,Accuracy=(TP+TN)/(TP+TN+FP+FN),要求y_true和y_pred都为类别序号编码)
- tf.keras.metrics.AUC(ROC曲线(TPR vs FPR)下的面积,用于二分类,直观解释为随机抽取一个正样本和一个负样本,正样本的预测值大于负样本的概率)
- tf.keras.metrics.Precision(精确率,用于二分类,Precision = TP/(TP+FP))
- tf.keras.metrics.Recall(召回率,用于二分类,Recall = TP/(TP+FN))
- tf.keras.metrics.TopKCategoricalAccuracy(多分类TopK准确率,要求y_true(label)为onehot编码形式)
- tf.keras.metrics.CategoricalAccuracy(分类准确率,与Accuracy含义相同,要求y_true(label)为onehot编码形式)
- tf.keras.metrics.SparseCategoricalAccuracy(稀疏分类准确率,与Accuracy含义相同,要求y_true(label)为序号编码形式)
import tensorflow as tf
# 评估函数使用原理
m=tf.keras.metrics.Accuracy()
m.update_state([1,2,3,4],[0,2,3,4])
print('Final result: ',m.result().numpy())
# Final result: 0.75
m.update_state([1,2,3,4],[0,2,3,1])
print('Final result: ',m.result().numpy())
m=tf.keras.metrics.Accuracy()
m([1,2,3,4],[0,2,3,4])
print('Final result: ',m.result().numpy())
# Final result: 0.75
m([1,2,3,4],[0,2,3,1])
print('Final result: ',m.result().numpy())
m.reset_states()
m.update_state([1,2,3,4],[0,2,3,4])
print('Final result: ',m.result().numpy())
二 自定义评估函数
两种实现形式: 基于类的实现和基于函数的实现
大部分使用基于类的实现
自定义损失函数:
自定义评估指标需要继承tf.keras.metrics.Metric类,并重写__init__、update_state和result 三个方法。
update_state():对状态变量进行所有更新
result():根据状态变量计算并返回指标值。__init__()
:所有状态变量都应通过以下方法在此方法中创建self.add_weight()
class SparseCategoricalAccuracy_(tf.keras.metrics.Metric):
def __init__(self, name='SparseCategoricalAccuracy', **kwargs):
super(SparseCategoricalAccuracy_, self).__init__(name=name, **kwargs)
self.total = self.add_weight(name='total', dtype=tf.int32, initializer=tf.zeros_initializer())
self.count = self.add_weight(name='count', dtype=tf.int32, initializer=tf.zeros_initializer())
def update_state(self, y_true, y_pred,sample_weight=None):
values = tf.cast(tf.equal(y_true, tf.argmax(y_pred, axis=-1, output_type=tf.int32)), tf.int32)
self.total.assign_add(tf.shape(y_true)[0])
self.count.assign_add(tf.reduce_sum(values))
def result(self):
return self.count / self.total
def reset_states(self):
# The state of the metric will be reset at the start of each epoch.
self.total.assign(0)
self.count.assign(0)
s = SparseCategoricalAccuracy_()
# s.reset_states()
s.update_state(tf.constant([2, 1]), tf.constant([[0.1, 0.9, 0.8], [0.05, 0.95, 0]]))
print('Final result: ', s.result().numpy()) # Final result: 0.5
m = tf.keras.metrics.SparseCategoricalAccuracy()
m.update_state([2,1], [[0.1, 0.9, 0.8], [0.05, 0.95, 0]])
print('Final result: ', m.result().numpy()) # Final result: 0.5
class CatgoricalTruePositives(tf.keras.metrics.Metric):
def __init__(self, name='categorical_true_positives', **kwargs):
super(CatgoricalTruePositives, self).__init__(name=name, **kwargs)
self.true_positives = self.add_weight(name='tp', initializer='zeros')
def update_state(self, y_true, y_pred, sample_weight=None):
y_pred = tf.argmax(y_pred,axis=-1)
values = tf.equal(tf.cast(y_true, 'int32'), tf.cast(y_pred, 'int32'))
values = tf.cast(values, 'float32')
if sample_weight is not None:
sample_weight = tf.cast(sample_weight, 'float32')
values = tf.multiply(values, sample_weight)
self.true_positives.assign_add(tf.reduce_sum(values))
def result(self):
return self.true_positives
def reset_states(self):
# The state of the metric will be reset at the start of each epoch.
self.true_positives.assign(0.)
y_pred = tf.nn.softmax(tf.random.uniform((4,3)))
tf.argmax(y_pred,axis=-1)
y_true = tf.constant([2,0,0,0])
m=CatgoricalTruePositives()
m.update_state(y_true,y_pred)
print('Final result: ',m.result().numpy())
m.reset_states()