我們将度量定義為一個性能度量,而不是損失函數(損失在訓練期間直接進行優化),但是我們仍然對他在評估模型方面感興趣。例如,我們可能希望盡量減少對數損失,但我們的興趣度量可能是F1分(測試準确度)或交彙分數(不可區分,是以不能用作損失)。
TF-Slim提供了一系列度量操作,使評估模型變得簡單。抽象地說,計算度量的值可以分為三部分:
- 初始化:初始化用于計算度量的變量。
- 聚合:執行用于計算度量的操作(總和等)。
- 完成:(可選)執行任何最終操作來計算度量标準值。例如,計算手段,分鐘,最大值等
例如,為了計算mean_absolute_error,計數和總變量這兩個變量被初始化為零。在聚合過程中,我們觀察了一些預測和标簽集合,計算它們的絕對差異并将總數加到總數上。每次我們觀察另一個值時,計數都會遞增。最後,在定稿過程中,總數除以數量得到平均值。
以下示例示範了用于聲明metrics的API。由于度量标準通常是在與訓練集不同的測試集上進行評估的,是以我們假定我們使用的是測試資料:
images, labels = LoadTestData(...)
predictions = MyModel(images)
mae_value_op, mae_update_op = slim.metrics.streaming_mean_absolute_error(predictions, labels)
mre_value_op, mre_update_op = slim.metrics.streaming_mean_relative_error(predictions, labels)
pl_value_op, pl_update_op = slim.metrics.percentage_less(mean_relative_errors, 0.3)
如示例所示,建立度量标準會傳回兩個值:value_op和update_op。 value_op是一個幂等操作,傳回度量的目前值。 update_op是執行上述聚合步驟以及傳回路徑成本的操作。
跟蹤每個value_op和update_op可能會很費力。 為了解決這個問題,TF-Slim提供了兩個便利功能:
# Aggregates the value and update ops in two lists:
value_ops, update_ops = slim.metrics.aggregate_metrics(
slim.metrics.streaming_mean_absolute_error(predictions, labels),
slim.metrics.streaming_mean_squared_error(predictions, labels))
# Aggregates the value and update ops in two dictionaries:
names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({
"eval/mean_absolute_error": slim.metrics.streaming_mean_absolute_error(predictions, labels),
"eval/mean_squared_error": slim.metrics.streaming_mean_squared_error(predictions, labels),
})
Working example: Tracking Multiple Metrics
Putting it all together:
import tensorflow as tf
slim = tf.contrib.slim
vgg = tf.contrib.slim.nets.vgg
# Load the data
images, labels = load_data(...)
# Define the network
predictions = vgg.vgg_16(images)
# Choose the metrics to compute:
names_to_values, names_to_updates = slim.metrics.aggregate_metric_map({
"eval/mean_absolute_error": slim.metrics.streaming_mean_absolute_error(predictions, labels),
"eval/mean_squared_error": slim.metrics.streaming_mean_squared_error(predictions, labels),
})
# Evaluate the model using 1000 batches of data:
num_batches = 1000
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
for batch_id in range(num_batches):
sess.run(names_to_updates.values())
metric_values = sess.run(names_to_values.values())
for metric, value in zip(names_to_values.keys(), metric_values):
print('Metric %s has value: %f' % (metric, value))
請注意,可以單獨使用metric_ops.py,而不使用layers.py或loss_ops.py