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

时间:2022-04-26
本文章向大家介绍使用Keras在训练深度学习模型时监控性能指标,主要内容包括教程概述、Keras指标、Keras为回归问题提供的性能评估指标、Keras为分类问题提供的性能评估指标、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为分类问题和回归问题提供的性能评估指标。
  • 如何有效地定义和使用自定义性能指标。