Ошибка создания пользовательской метрики Keras

При попытке реализовать 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

person Kroshtan    schedule 16.04.2018    source источник


Ответы (1)


Похоже, проблема в том, что вы пытаетесь вычислить простое целое число, а не переменную keras.

intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
union_sum = K.sum(K.abs(y_true) + K.abs(y_pred), axis=-1)
IOU = (intersection) / (union_sum- intersection)
person thefifthjack005    schedule 16.04.2018
comment
Я не понимаю, как это производит то же самое, что и моя первоначальная функция. Размер по-прежнему двумерный, а не одно значение, и учитываются значения из всех классов, а не того класса, который доминирует в определенном пикселе. Можно поподробнее об этих вещах? - person Kroshtan; 16.04.2018
comment
@Kroshtan Помните, что функция потерь вычисляется непосредственно в вычислительном графе, поэтому код должен быть на языке тензоров. Ваш рассматриваемый код вычисляет целые числа python, он находится за пределами вычислительного графа. Это, пожалуй, самое раздражающее ограничение Keras/Tensorflow — вам нужно выражать все в терминах тензорных операций! - person FalconUA; 16.04.2018