При попытке реализовать Intersection over Union (IoU) я столкнулся с ошибкой python/keras, которую не могу установить. В отдельном файле я определяю следующую метрику:
def computeIoU(y_pred_batch, y_true_batch):
print y_true_batch.shape[0]
return np.mean(np.asarray([imageIoU(y_pred_batch[i], y_true_batch[i]) for i in range(y_true_batch.shape[0])]))
def imageIoU(y_pred, y_true):
y_pred = np.argmax(y_pred, axis=2)
y_true = np.argmax(y_true, axis=2)
inter = 0
union = 0
for x in range(imCols):
for y in range(imRows):
for i in range(num_classes):
inter += (y_pred[y][x] == y_true[y][x] == i)
union += (y_pred[y][x] == i or y_true[y][x] == i)
print inter
print union
return float(inter)/union
В основной файл я импортировал функцию и использую метрику следующим образом:
fcn32_model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy', computeIoU])
Выдается ошибка
TypeError: __int__ should return int object
После реализации вышеуказанного алгоритма с предложенным синтаксисом Keras/tf из ответов здесь и по другому вопросу код был изменен на:
def iou(y_pred_batch, y_true_batch):
intersection = tf.zeros(())
union = tf.zeros(())
y_pred_batch = K.argmax(y_pred_batch, axis=-1)
y_true_batch = K.argmax(y_true_batch, axis=-1)
for i in range(num_classes):
iTensor = tf.to_int64(tf.fill(y_pred_batch.shape, i))
intersection = tf.add(intersection, tf.to_float(tf.count_nonzero(tf.logical_and(K.equal(y_true_batch, y_pred_batch), K.equal(y_true_batch, iTensor)))))
union = tf.add(union, tf.to_float(tf.count_nonzero(tf.logical_or(K.equal(y_true_batch, iTensor), K.equal(y_pred_batch, iTensor)))))
return intersection/union