def time_error_loss(model_h, model_m, label_h, label_m):
"""
Compute the time error (in minutes) of the current model.
Total time difference is expressed in minutes:
1/N sum( delta(PP, TT))
where PP and TT are the predicted and true times, expressed in number of
minutes.
The delta operator takes care of 'wraparound', so that the difference
between 9'58 and 10'02 is 4 minutes.
We also return the individual errors for hours and minutes. Just for fun.
:param model_h:
:param model_m:
:param label_h:
:param label_m:
:return: losses for (combined, hours, minutes)
"""
# Take classifier argmax for most likely hour/minute, and cast everything to
# float32.
hours_predicted = tf.cast(tf.argmax(model_h, 1), tf.float32)
hours_true = tf.cast(label_h, tf.float32)
minutes_predicted = tf.cast(tf.argmax(model_m, 1), tf.float32)
minutes_true = tf.cast(label_m, tf.float32)
delta_time = tf.sub(tf.add(60 * hours_predicted, minutes_predicted),
tf.add(60 * hours_true, minutes_true))
delta_hours = tf.sub(hours_predicted, hours_true)
delta_minutes = tf.sub(minutes_predicted, minutes_true)
# TF's mod operator returns negative values:
# -7 mod 3 = -1 (we want 2)
# so we need to do a little extra work.
def positive_mod(val, div):
# Return the positive result of the modulo operator.
# Does x = ((v % div) + div) % div
return tf.mod(tf.add(tf.mod(val, div), div), div)
# Handle time wrapping around by comparing the mod of the positive and
# negative time differences.
time_error_c = tf.minimum(positive_mod(delta_time, 720),
positive_mod(-1 * delta_time, 720))
time_error_h = tf.minimum(positive_mod(delta_hours, 12.0),
positive_mod(-1 * delta_hours, 12.0))
time_error_m = tf.minimum(positive_mod(delta_minutes, 60.0),
positive_mod(-1 * delta_minutes, 60.0))
avg_error_c = tf.reduce_mean(time_error_c)
avg_error_h = tf.reduce_mean(time_error_h)
avg_error_m = tf.reduce_mean(time_error_m)
return avg_error_c, avg_error_h, avg_error_m
评论列表
文章目录