使用Keras在训练深度学习模型时监控性能指标

Keras库提供了一套供深度学习模型训练时的用于监控和汇总的标准性能指标并且开放了接口给开发者使用。

除了为分类和回归问题提供标准的指标以外,Keras还允许用户自定义指标。这使我们可以在模型训练的过程中实时捕捉模型的性能变化,为训练模型提供了很大的便利。

在本教程中,我会告诉你如何在使用Keras进行深度学习时添加内置指标以及自定义指标并监控这些指标。

完成本教程后,你将掌握以下知识:

  • Keras计算模型指标的工作原理,以及如何在训练模型的过程中监控这些指标。
  • 通过实例掌握Keras为分类问题和回归问题提供的性能评估指标的使用方法。
  • 通过实例掌握Keras自定义指标的方法。

事不宜迟,让我们开始吧。

照片来源:https://www.flickr.com/photos/indi/6901400708/, 保留权利

教程概述

本教程可以分为以下4个部分:

  1. Keras指标(Metrics)
  2. Keras为回归问题提供的性能评估指标
  3. Keras为分类问题提供的性能评估指标
  4. Keras中的自定义性能评估指标

Keras指标

Keras允许你在训练模型期间输出要监控的指标。

您可以通过设定“ metrics ”参数并向模型的compile()函数提供函数名(或函数别名)列表来完成此操作。

例如:

model.compile(..., metrics=['mse'])

列出的具体指标可以是Keras函数的名称(如mean_squared_error)或这些函数的字符串别名(如' mse ')。

每当训练数据集中有一个epoch训练完成后,此时的性能参数会被记录下来。如果提供了验证数据集,验证数据集中的性能评估参数也会一并计算出来。

性能评估指标可以通过输出查看,也可以通过调用模型类的fit()方法获得。这两种方式里,性能评估函数都被当做关键字使用。如果要查看验证数据集的指标,只要在关键字前加上val_前缀即可。

损失函数和Keras明确定义的性能评估指标都可以当做训练中的性能指标使用。

Keras为回归问题提供的性能评估指标

以下是Keras为回归问题提供的性能评估指标。

  • 均方误差:mean_squared_error,MSE或mse
  • 平均绝对误差:mean_absolute_error,MAE,mae
  • 平均绝对误差百分比:mean_absolute_percentage_error,MAPE,mape
  • Cosine距离:cosine_proximity,cosine

下面通过演示来观察一下回归问题中这四个内建的性能评估指标随训练批次增加发生的变化。

from numpy import array
from keras.models import Sequential
from keras.layers import Dense
from matplotlib import pyplot
# prepare sequence
X = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
# create model
model = Sequential()
model.add(Dense(2, input_dim=1))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam', metrics=['mse', 'mae', 'mape', 'cosine'])
# train model
history = model.fit(X, X, epochs=500, batch_size=len(X), verbose=2)
# plot metrics
pyplot.plot(history.history['mean_squared_error'])
pyplot.plot(history.history['mean_absolute_error'])
pyplot.plot(history.history['mean_absolute_percentage_error'])
pyplot.plot(history.history['cosine_proximity'])
pyplot.show()

运行实例在每个epoch结束时打印性能评估指标。

...
Epoch 96/100
0s - loss: 1.0596e-04 - mean_squared_error: 1.0596e-04 - mean_absolute_error: 0.0088 - mean_absolute_percentage_error: 3.5611 - cosine_proximity: -1.0000e+00
Epoch 97/100
0s - loss: 1.0354e-04 - mean_squared_error: 1.0354e-04 - mean_absolute_error: 0.0087 - mean_absolute_percentage_error: 3.5178 - cosine_proximity: -1.0000e+00
Epoch 98/100
0s - loss: 1.0116e-04 - mean_squared_error: 1.0116e-04 - mean_absolute_error: 0.0086 - mean_absolute_percentage_error: 3.4738 - cosine_proximity: -1.0000e+00
Epoch 99/100
0s - loss: 9.8820e-05 - mean_squared_error: 9.8820e-05 - mean_absolute_error: 0.0085 - mean_absolute_percentage_error: 3.4294 - cosine_proximity: -1.0000e+00
Epoch 100/100
0s - loss: 9.6515e-05 - mean_squared_error: 9.6515e-05 - mean_absolute_error: 0.0084 - mean_absolute_percentage_error: 3.3847 - cosine_proximity: -1.0000e+00

在所有的epoch运行完毕后会创建这四个性能指标的折线图。

Keras为回归问题提供的四个性能评估指标随epoch完成个数变化的折线图

在上面的例子中,性能评估指标是通过别名'mse', 'mae', 'mape', 'cosine'指定的,通过别名对应的函数全名来作为模型对象下的键值调用对应的性能评估函数。

我们自然也可以使用函数全名来指定性能评估指标,如下所示:

model.compile(loss='mse', optimizer='adam', metrics=['mean_squared_error', 'mean_absolute_error', 'mean_absolute_percentage_error', 'cosine_proximity'])

如果我们已经从Keras的包中import了metrics类,那么就可以直接指定其下的函数。

from keras import metrics
model.compile(loss='mse', optimizer='adam', metrics=[metrics.mean_squared_error, metrics.mean_absolute_error, metrics.mean_absolute_percentage_error, metrics.cosine_proximity])

也可以使用损失函数作为度量标准。

如下所示,使用均方对数误差(mean_squared_logarithmic_errorMSLEmsle)损失函数作为度量标准:

model.compile(loss='mse', optimizer='adam', metrics=['msle'])

Keras为分类问题提供的性能评估指标

以下是Keras为分类问题提供的性能评估指标。

  • 对二分类问题,计算在所有预测值上的平均正确率:binary_accuracy,acc
  • 对多分类问题,计算再所有预测值上的平均正确率:categorical_accuracy,acc
  • 在稀疏情况下,多分类问题预测值的平均正确率:sparse_categorical_accuracy
  • 计算top-k正确率,当预测值的前k个值中存在目标类别即认为预测正确:top_k_categorical_accuracy(需要手动指定k值)
  • 在稀疏情况下的top-k正确率:sparse_top_k_categorical_accuracy(需要手动指定k值)

准确性是一个特别的性能指标。

无论您的问题是二元还是多分类问题,都可以指定“ acc ”指标来评估准确性。

下面通过实例演示来观察Keras内置的准确度指标随训练批次增加的变化情况。

from numpy import array
from keras.models import Sequential
from keras.layers import Dense
from matplotlib import pyplot
# prepare sequence
X = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
y = array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])
# create model
model = Sequential()
model.add(Dense(2, input_dim=1))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['acc'])
# train model
history = model.fit(X, y, epochs=400, batch_size=len(X), verbose=2)
# plot metrics
pyplot.plot(history.history['acc'])
pyplot.show()

运行实例在每个epoch结束时打印当前的准确度。

...
Epoch 396/400
 - 0s - loss: 0.5474 - acc: 1.0000
Epoch 397/400
 - 0s - loss: 0.5470 - acc: 1.0000
Epoch 398/400
 - 0s - loss: 0.5466 - acc: 1.0000
Epoch 399/400
 - 0s - loss: 0.5462 - acc: 1.0000
Epoch 400/400
 - 0s - loss: 0.5458 - acc: 1.0000

在所有的epoch运行完毕后会创建精确度变化的折线图。

Keras中的自定义性能评估指标

除了官方提供的标准性能评估指标之外,你还可以自定义自己的性能评估指标,然后再调用compile()函数时在metrics参数中指定函数名。

我经常喜欢增加的自定义指标是均方根误差(RMSE)。

你可以通过观察官方提供的性能评估指标函数来学习如何编写自定义指标。

下面展示的是Keras中mean_squared_error损失函数(即均方差性能评估指标)的代码。

def mean_squared_error(y_true, y_pred):
    return K.mean(K.square(y_pred - y_true), axis=-1)

K是Keras使用的后端(例如TensorFlow)。

从这个例子以及其他损失函数和性能评估指标可以看出:需要使用后端提供的标准数学函数来计算我们感兴趣的性能评估指标。

现在我们可以尝试编写一个自定义性能评估函数来计算RMSE,如下所示:

from keras import backend
 
def rmse(y_true, y_pred):
    return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))
 

你可以看到除了用sqrt()函数封装结果之外,这个函数的代码和MSE是一样的。

我们可以通过一个简单的回归问题来测试这个性能评估函数。注意这里我们不再通过字符串提供给Keras来解析为对应的处理函数,而是直接设定为我们编写的自定义函数。

from numpy import array
from keras.models import Sequential
from keras.layers import Dense
from matplotlib import pyplot
from keras import backend
 
def rmse(y_true, y_pred):
    return backend.sqrt(backend.mean(backend.square(y_pred - y_true), axis=-1))
 
# prepare sequence
X = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
# create model
model = Sequential()
model.add(Dense(2, input_dim=1, activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='adam', metrics=[rmse])
# train model
history = model.fit(X, X, epochs=500, batch_size=len(X), verbose=2)
# plot metrics
pyplot.plot(history.history['rmse'])
pyplot.show()

同样地,在每个epoch结束时会打印均方误差值。

...
Epoch 496/500
0s - loss: 1.2992e-06 - rmse: 9.7909e-04
Epoch 497/500
0s - loss: 1.2681e-06 - rmse: 9.6731e-04
Epoch 498/500
0s - loss: 1.2377e-06 - rmse: 9.5562e-04
Epoch 499/500
0s - loss: 1.2079e-06 - rmse: 9.4403e-04
Epoch 500/500
0s - loss: 1.1788e-06 - rmse: 9.3261e-04

在运行结束时可以得到自定义性能评估指标——均方误差的折线图。

自定义性能评估指标——均方误差的折线图

你的自定义性能评估函数必须在Keras的内部数据结构上进行操作而不能直接在原始的数据进行操作,具体的操作方法取决于你使用的后端(如果使用TensorFlow,那么对应的就是tensorflow.python.framework.ops.Tensor)。

由于这个原因,我建议最好使用后端提供的数学函数来进行计算,这样可以保证一致性和运行速度。

延伸阅读

如果你想继续深入了解,下面有我推荐的一些资源以供参考。

总结

在本教程中,你应该已经了解到了如何在训练深度学习模型时使用Keras提供的性能评估指标接口。

具体来说,你应该掌握以下内容:

  • Keras的性能评估指标的工作原理,以及如何配置模型在训练过程中输出性能评估指标。
  • 如何使用Keras为分类问题和回归问题提供的性能评估指标。
  • 如何有效地定义和使用自定义性能指标。

本文的版权归 ArrayZoneYour 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏LhWorld哥陪你聊算法

【Keras篇】---利用keras改写VGG16经典模型在手写数字识别体中的应用

VGG16是由16层神经网络构成的经典模型,包括多层卷积,多层全连接层,一般我们改写的时候卷积层基本不动,全连接层从后面几层依次向前改写,因为先改参数较小的。

2142
来自专栏机器之心

资源 | 十倍模型计算时间仅增20%:OpenAI开源梯度替换插件

3259
来自专栏企鹅号快讯

深入机器学习系列7-Random Forest

1 Bagging   采用自助采样法()采样数据。给定包含个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时,样本仍...

4946
来自专栏云计算教程系列

如何使用TensorFlow构建神经网络来识别手写数字

神经网络被用作深度学习的方法,深度学习是人工智能的许多子领域之一。它们大约在70年前首次提出,试图模拟人类大脑的工作方式,尽管它的形式要简化得多。各个“神经元”...

1762
来自专栏人工智能

机器学习入门之HelloWorld(Tensorflow)

本文介绍一些机器学习的入门知识,从安装环境到跑通机器学习入门程序MNIST demo。

2.6K40
来自专栏技术翻译

回归问题的深层神经网络

众所周知,神经网络可用于解决分类问题,例如,它们被用于手写体数字分类,但问题是,如果我们将它们用于回归问题,它会有效果吗?

9892
来自专栏用户2442861的专栏

Caffe学习系列(6):Blob,Layer and Net以及对应配置文件的编写

http://www.cnblogs.com/denny402/p/5073427.html

871
来自专栏人工智能

展开计算图与循环神经网络

计算图是形式化一组计算结构的方式,如那些涉及将输入和参数映射到输出和损失计算。我们对展开(unfolding) 递归或循环计算得到的重复结构进行解释,这些重复结...

2379
来自专栏ATYUN订阅号

马尔可夫链文本生成的简单应用:不足20行的Python代码生成鸡汤文

提到自然语言的生成时,人们通常认为要会使用高级数学来思考先进的AI系统,然而,并不一定要这样。在这篇文章中,我将使用马尔可夫链和一个小的语录数据集来产生新的语录...

2826
来自专栏新智元

【信息图】神经网络动物园前序:Cell与层之间如何连接

【新智元导读】 此前介绍的神经网络动物园让大家大饱眼福,看到了各种各样的神经网络模型。今天带来更为基础的介绍:组成神经网络模型的基本单元和层是怎么样的?通过信...

3346

扫码关注云+社区

领取腾讯云代金券