# My loss function returns 0 - what I do wrong?

hi all
I’m learning tenserflow and trying to write custom loss and metric functions, but instead of numbers I got 0. Could somebody point me what I do wrong.
Note that my data is # x1, y1 - left top, x2, y2 - right bottom
it looks like iou = tf.math.divide_no_nan(intersect_area, union_area) return 0 but should not.

``````def iou(y_true, y_pred):
# x1, y1 - left top, x2, y2 - right bottom
y_true = tf.cast(y_true, dtype=tf.float32)
y_pred = tf.cast(y_pred, dtype=tf.float32)

true_area = (y_true[..., 2] - y_true[..., 0]) * (y_true[..., 3] - y_true[..., 1])
pred_area = (y_pred[..., 2] - y_pred[..., 0]) * (y_pred[..., 3] - y_pred[..., 1])

tf.print("(iou)------>true_area:",true_area, output_stream=sys.stdout)
tf.print("(iou)------>pred_area", pred_area, output_stream=sys.stdout)

intersect_mins = tf.maximum(y_pred[..., :2], y_true[..., :2])
intersect_maxes = tf.minimum(y_pred[..., 2:4], y_true[..., 2:4])
intersect_wh = tf.maximum(intersect_maxes - intersect_mins, 0.)
intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]

union_area = pred_area + true_area - intersect_area
iou = tf.math.divide_no_nan(intersect_area, union_area)
tf.print("(iou)------>iou", iou, output_stream=sys.stdout)

return iou

def iou_loss(y_true, y_pred):
i = iou(y_true, y_pred)
l = 1.0 - i
return l

import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import Flatten, Dense
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Dropout

base_model = VGG16(include_top=False, input_shape=(224, 224, 3))
x = base_model.output
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
x = Dense(256, activation='relu')(x)
x = Dropout(0.5)(x)
predictions = Dense(4, activation='relu')(x)

model = Model(inputs=base_model.input, outputs=predictions)
history = model.fit(images_train, boxes_train[:,1], validation_data=(images_val, boxes_val[:, 1]), epochs=10, batch_size=32)
``````

Update:

1. data which I passed into model.fit function looks ok
2. data normalization does not help
``````boxes_train_normalized = boxes_train[:, 1] / [224, 224, 224, 224]
boxes_val_normalized = boxes_val[:, 1] / [224, 224, 224, 224]
history = model.fit(images_train, boxes_train_normalized, validation_data=(images_val, boxes_val_normalized), epochs=10, batch_size=32)
``````
1. trick with tiny number also does not help
``````epsilon = 1e-7
union_area = pred_area + true_area - intersect_area + epsilon
iou = tf.math.divide_no_nan(intersect_area, union_area)
``````
1. changing activation function from relu to sigmoid also do not help

As per my understanding from the above code , the problem is that you are dividing by zero in the `iou` function. This is because the `union_area` can be zero if the two boxes do not overlap.

To handle the scenario where the `union_area` is zero and avoid returning a zero value for the IoU, you can use a conditional statement to handle this case separately or you can add a small epsilon to the `union_area` before dividing.

Hope this helps.

Thanks.

thanks for reply, but I don’t think it is real cause of my issue because to avoid that divide by 0 I added this code

``````epsilon = 1e-7
union_area = pred_area + true_area - intersect_area + epsilon
iou = tf.math.divide_no_nan(intersect_area, union_area)
``````

and it doesn’t solve my problem.