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)
model.compile(optimizer='adam', loss=iou_loss, metrics=[iou, 'accuracy'])
history = model.fit(images_train, boxes_train[:,1], validation_data=(images_val, boxes_val[:, 1]), epochs=10, batch_size=32)
Update:
- data which I passed into model.fit function looks ok
- 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)
- 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)
- changing activation function from relu to sigmoid also do not help