keras.metrics解析
目录
- 前言
- metrics原理解析(以metrics.Mean为例)
- 创建自定义metrics
- 创建无状态 metrics
- 通过继承Metric创建有状态 metrics
- add_metric() 方法
- 参考
前言
metrics用于判断模型性能。度量函数类似于损失函数,只是度量的结果不用于训练模型。可以使用任何损失函数作为度量(如logloss等)。在训练期间监控metrics的最佳方式是通过Tensorboard。
官方提供的metrics最重要的概念就是有状态(stateful)变量,通过更新状态变量,可以不断累积统计数据,并可以随时输出状态变量的计算结果。这是区别于losses的重要特性,losses是无状态的(stateless)。
本文部分内容参考了:
- Keras-Metrics官方文档
代码运行环境为:tf.__version__==2.6.2 。
metrics原理解析(以metrics.Mean为例)
metrics是有状态的(stateful),即Metric 实例会存储、记录和返回已经累积的结果,有助于未来事务的信息。下面以tf.keras.metrics.Mean()
为例进行解释:
创建tf.keras.metrics.Mean
的实例:
m = tf.keras.metrics.Mean()
通过help(m)
可以看到MRO为:
Mean
Reduce
Metric
keras.engine.base_layer.Layer
...
可见Metric和Mean是 keras.layers.Layer
的子类。相比于类Layer,其子类Mean多出了几个方法:
- result\mathsf{result}result: 计算并返回标量度量值(tensor形式)或标量字典,即状态变量简单地计算度量值。例如,
m.result()
,就是计算均值并返回。 - total\mathsf{total}total: 状态变量
m
目前累积的数字总和 - count\mathsf{count}count: 状态变量
m
目前累积的数字个数(m.total/m.count
就是m.result()
的返回值) - update_state\mathsf{update\_state}update_state: 累积统计数字用于计算指标。每次调用
m.update_state
都会更新m.total
和m.count
; - reset_state\mathsf{reset\_state}reset_state: 将状态变量重置到初始化状态;
- reset_states\mathsf{reset\_states}reset_states: 等价于reset_state,参见keras源代码metrics.py L355
- reduction\mathsf{reduction}reduction: 目前来看,没什么用。
这也决定了Mean的特殊性质。其使用参见如下代码:
# 创建状态变量m,由于m未刚初始化,
# 所以total,count和result()均为0
m = tf.keras.metrics.Mean()
print("m.total:",m.total)
print("m.count:",m.count)
print("m.result():",m.result())"""
# 输出:
m.total: <tf.Variable 'total:0' shape=() dtype=float32, numpy=0.0>
m.count: <tf.Variable 'count:0' shape=() dtype=float32, numpy=0.0>
m.result(): tf.Tensor(0.0, shape=(), dtype=float32)
"""
# 更新状态变量,可以看到total累加了总和,
# count累积了个数,result()返回total/count
m.update_state([1,2,3])
print("m.total:",m.total)
print("m.count:",m.count)
print("m.result():",m.result())"""
# 输出:
m.total: <tf.Variable 'total:0' shape=() dtype=float32, numpy=6.0>
m.count: <tf.Variable 'count:0' shape=() dtype=float32, numpy=3.0>
m.result(): tf.Tensor(2.0, shape=(), dtype=float32)
"""
# 重置状态变量, 重置到初始化状态
m.reset_state()
print("m.total:",m.total)
print("m.count:",m.count)
print("m.result():",m.result())"""
# 输出:
m.total: <tf.Variable 'total:0' shape=() dtype=float32, numpy=0.0>
m.count: <tf.Variable 'count:0' shape=() dtype=float32, numpy=0.0>
m.result(): tf.Tensor(0.0, shape=(), dtype=float32)
"""
创建自定义metrics
创建无状态 metrics
与损失函数类似,任何带有类似于metric_fn(y_true, y_pred)
、返回损失数组(如输入一个batch的数据,会返回一个batch的损失标量)的函数,都可以作为metric传递给compile()
:
import tensorflow as tf
import numpy as npinputs = tf.keras.Input(shape=(3,))
x = tf.keras.layers.Dense(4, activation=tf.nn.relu)(inputs)
outputs = tf.keras.layers.Dense(1, activation=tf.nn.softmax)(x)
model1 = tf.keras.Model(inputs=inputs, outputs=outputs)def my_metric_fn(y_true, y_pred):squared_difference = tf.square(y_true - y_pred)return tf.reduce_mean(squared_difference, axis=-1) # shape=(None,)model1.compile(optimizer='adam', loss='mse', metrics=[my_metric_fn])x = np.random.random((100, 3))
y = np.random.random((100, 1))
model1.fit(x, y, epochs=3)
输出:
Epoch 1/3
4/4 [==============================] - 0s 667us/step - loss: 0.0971 - my_metric_fn: 0.0971
Epoch 2/3
4/4 [==============================] - 0s 667us/step - loss: 0.0958 - my_metric_fn: 0.0958
Epoch 3/3
4/4 [==============================] - 0s 1ms/step - loss: 0.0946 - my_metric_fn: 0.0946
注意,因为本例创建的是无状态的度量,所以上面跟踪的度量值(my_metric_fn后面的值)是每个batch的平均度量值,并不是一个epoch(完整数据集)的累积值。(这一点需要理解,这也是为什么要使用有状态度量的原因!)
值得一提的是,如果上述代码使用
model1.compile(optimizer='adam', loss='mse', metrics=["mse"])
进行compile,则输出的结果是累积的,在每个epoch结束时的结果就是整个数据集的结果,因为metrics=["mse"]
是直接调用了标准库的有状态度量。
通过继承Metric创建有状态 metrics
如果想查看整个数据集的指标,就需要传入有状态的metrics,这样就会在一个epoch内累加,并在epoch结束时输出整个数据集的度量值。
创建有状态度量指标,需要创建Metric的子类,它可以跨batch维护状态,步骤如下:
- 在
__init__
中创建状态变量(state variables) - 更新
update_state()
中y_true
和y_pred
的变量 - 在
result()
中返回标量度量结果 - 在
reset_states()
中清除状态
class BinaryTruePositives(tf.keras.metrics.Metric):def __init__(self, name='binary_true_positives', **kwargs):super(BinaryTruePositives, 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_true = tf.cast(y_true, tf.bool)y_pred = tf.cast(y_pred, tf.bool)values = tf.logical_and(tf.equal(y_true, True), tf.equal(y_pred, True))values = tf.cast(values, self.dtype)if sample_weight is not None:sample_weight = tf.cast(sample_weight, self.dtype)values = tf.multiply(values, sample_weight)self.true_positives.assign_add(tf.reduce_sum(values))def result(self):return self.true_positivesdef reset_states(self):self.true_positives.assign(0)m = BinaryTruePositives()
m.update_state([0, 1, 1, 1], [0, 1, 0, 0])
print('Intermediate result:', float(m.result()))m.update_state([1, 1, 1, 1], [0, 1, 1, 0])
print('Final result:', float(m.result()))
add_metric() 方法
add_metric
方法是 tf.keras.layers.Layer
类添加的方法,Layer的父类tf.Module
并没有这个方法,因此在编写Layer子类如包括自定义层、官方提供的层(Dense)或模型(tf.keras.Model也是Layer的子类)时,可以使用add_metric()
来与层相关的统计量。比如,将类似Dense的自定义层的激活平均值记录为metric。可以执行以下操作:
class DenseLike(Layer):"""y = w.x + b"""...def call(self, inputs):output = tf.matmul(inputs, self.w) + self.bself.add_metric(tf.reduce_mean(output), aggregation='mean', name='activation_mean')return output
将在名称为activation_mean的度量下跟踪output,跟踪的值为每个批次度量值的平均值。
更详细的信息,参阅官方文档The base Layer class - add_metric method。
参考
Keras-Metrics官方文档
keras.metrics解析相关推荐
- keras.metrics中的accuracy
keras.metrics有六种accuracy,其使用的场景如下: accuracy 真实标签和模型预测均为标量,如真实标签为[0,1,1,0,2,0],模型输出的预测为[0,2,1,1,2,0], ...
- TensorFlow2.0: keras.metrics的使用
keras.metrics中有两个api函数可以简化准确率acc和损失值loss的计算.其分别是metrics.Accuracy( )和metrics.Mean( ). 一.建立测量尺 #建立测量尺 ...
- tf.keras.metrics.Accuracy;tf.keras.metrics.Precision;tf.keras.metrics.Recall
tf.keras.metrics.Accuracy:tf.keras.metrics.Precision:tf.keras.metrics.Recall 当标签为0/1,而prediction为(0, ...
- keras.metrics有五种accuracy
keras.metrics有五种accuracy,其使用的场景如下: accuracy真实标签和模型预测均为标量,如真实标签为[0,1,1,0,2,0],模型输出的预测为[0,2,1,1,2,0],此 ...
- keras.metrics中各种metric的区别
(一)keras.metrics有五种accuracy https://blog.csdn.net/weixin_44866160/article/details/106437277?utm_medi ...
- keras conv2d 解析
参数解析: conv2d是创建一个卷积层,对输入数据进行卷积操作,先看一下原函数: keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), ...
- 简易的深度学习框架Keras代码解析与应用
北京 | 深度学习与人工智能研修12月23-24日 再设经典课程 重温深度学习阅读全文> 正文约12690个字,22张图,预计阅读时间:32分钟. 总体来讲keras这个深度学习框架真的很&qu ...
- keras中的loss、optimizer、metrics
用keras搭好模型架构之后的下一步,就是执行编译操作.在编译时,经常需要指定三个参数 loss optimizer metrics 这三个参数有两类选择: 使用字符串 使用标识符,如keras.lo ...
- 一文总结Keras的loss函数和metrics函数
Loss函数 定义: keras.losses.mean_squared_error(y_true, y_pred) 用法很简单,就是计算均方误差平均值,例如 loss_fn = keras.loss ...
最新文章
- 15 位学神争霸!2019 清华本科生特奖答辩入围名单公布
- Spring IOC 核心流程浓缩
- 博客园.Text技术支持移至PSP技术支持中心
- 导入依赖和加上注释后,lombok gettersetter识别不到
- [APIO2016] 划艇(dp + 组合数 + 前缀和优化)
- Prototype模式
- “预习-上课-复习”:达摩院类人学习新范式探索
- mysql增错误_使用MySQL练习增删改查时因为版本问题出现连接错误
- 内核aio_AIO 的主要内核参数
- 磁盘驱动器号的修改恢复
- 戒烟、写作、赚美金:我的2020
- 基于深度强化学习的柔性作业车间动态调度
- 从Alignment 和 Uniformity的角度理解对比表征学习
- 用一个例子说明什么是多态
- 滴滴开源基于金融场景的Vuejs组件库Mand Mobile
- 0 -1 分布(两点分布)
- 人民的名义关系可视化展示
- 机器学习核心算法各个击破
- 世界上读书最多的国家(以色列人均64本)
- 机器学习之信用卡欺诈检测(零基础,附数据及详细python代码2022年Tensorflow2)