以下代码是从回购协议Keras-Yolo-v2启发而来的,我正遇到代码问题,我试图了解Nan造成损失的可能原因。 我已经使用过诸如clipnorm之类的技术,但这没有帮助。 这是yolo v2的自定义丢失,我正在尝试在Tensorflow 2.0上实现它。 我对此有一些想法,在某个地方值变成0并导致Nan的损失,但是我可以确切地知道可能在哪里发生。任何帮助将不胜感激。
预先感谢
class YoloLossKeras:
def __init__(self, priors):
self.priors = priors
def loss(self, y_true, y_pred):
n_cells = y_pred.get_shape().as_list()[1]
y_true = tf.reshape(y_true, tf.shape(y_pred), name='y_true')
y_pred = tf.identity(y_pred, name='y_pred')
#### PROCESS PREDICTIONS ####
# get x-y coords (for now they are with respect to cell)
predicted_xy = tf.nn.sigmoid(y_pred[..., :2])
# convert xy coords to be with respect to image
cell_inds = tf.range(n_cells, dtype=tf.float32)
predicted_xy = tf.stack((
predicted_xy[..., 0] + tf.reshape(cell_inds, [1, -1, 1]),
predicted_xy[..., 1] + tf.reshape(cell_inds, [-1, 1, 1])
), axis=-1)
# compute bb width and height
predicted_wh = self.priors * tf.exp(y_pred[..., 2:4])
# compute predicted bb center and width
predicted_min = predicted_xy - predicted_wh / 2
predicted_max = predicted_xy + predicted_wh / 2
predicted_objectedness = tf.nn.sigmoid(y_pred[..., 4])
predicted_logits = tf.nn.softmax(y_pred[..., 5:])
#### PROCESS TRUE ####
true_xy = y_true[..., :2]
true_wh = y_true[..., 2:4]
true_logits = y_true[..., 5:]
true_min = true_xy - true_wh / 2
true_max = true_xy + true_wh / 2
#### compute iou between ground truth and predicted (used for objectedness) ####
intersect_mins = tf.maximum(predicted_min, true_min)
intersect_maxes = tf.minimum(predicted_max, true_max)
intersect_wh = tf.maximum(intersect_maxes - intersect_mins, 0.)
intersect_areas = intersect_wh[..., 0] * intersect_wh[..., 1]
true_areas = true_wh[..., 0] * true_wh[..., 1]
pred_areas = predicted_wh[..., 0] * predicted_wh[..., 1]
union_areas = pred_areas + true_areas - intersect_areas
iou_scores = intersect_areas / union_areas
#### Compute loss terms ####
responsibility_selector = y_true[..., 4]
xy_diff = tf.square(true_xy - predicted_xy) * responsibility_selector[..., None]
xy_loss = tf.reduce_sum(xy_diff, axis=[1, 2, 3, 4])
wh_diff = tf.square(tf.sqrt(true_wh) - tf.sqrt(predicted_wh)) * responsibility_selector[..., None]
wh_loss = tf.reduce_sum(wh_diff, axis=[1, 2, 3, 4])
obj_diff = tf.square(iou_scores - predicted_objectedness) * responsibility_selector
obj_loss = tf.reduce_sum(obj_diff, axis=[1, 2, 3])
best_iou = tf.reduce_max(iou_scores, axis=-1)
no_obj_diff = tf.square(0 - predicted_objectedness) * tf.cast(best_iou < 0.6,tf.float32)[..., None] * (1 - responsibility_selector)
no_obj_loss = tf.reduce_sum(no_obj_diff, axis=[1, 2, 3])
clf_diff = tf.square(true_logits - predicted_logits) * responsibility_selector[..., None]
clf_loss = tf.reduce_sum(clf_diff, axis=[1, 2, 3, 4])
object_coord_scale = 5
object_conf_scale = 1
noobject_conf_scale = 1
object_class_scale = 1
loss = object_coord_scale * (xy_loss + wh_loss) + \
object_conf_scale * obj_loss + noobject_conf_scale * no_obj_loss + \
object_class_scale * clf_loss
return loss