Функция потерь для регрессии ограничивающей рамки с использованием CNN

Я пытаюсь понять функции потерь для регрессии ограничивающей рамки в CNN. В настоящее время я использую Lasagne и Theano, что очень упрощает написание выражений потерь. Многие источники предлагают разные методы, и я задаюсь вопросом, какой из них обычно используется на практике.

Координаты ограничивающих рамок представлены как нормализованные координаты в порядке [left, top, right, bottom] (используя T.matrix('targets', dtype=theano.config.floatX)).

До сих пор я пробовал следующие функции; однако все они имеют свои недостатки.

Пересечение через Союз

Мне посоветовали использовать меру Intersection over Union, чтобы определить, насколько хорошо выравниваются и перекрываются две ограничивающие рамки. Однако возникает проблема, когда поля не перекрываются, а пересечение равно 0; тогда все частное становится равным 0 независимо от того, насколько далеко друг от друга расположены ограничивающие рамки. Я реализовал это как:

def get_area(A):
    return (A[:,2] - A[:,0]) * (A[:,1] - A[:,3])

def get_intersection(A, B):
    return (T.minimum(A[:,2], B[:,2]) - T.maximum(A[:,0], B[:,0])) \
        * (T.minimum(A[:,1], B[:,1]) - T.maximum(A[:,3], B[:,3]))

def bbox_overlap_loss(A, B):
    """Computes the bounding box overlap using the
    Intersection over union"""
    intersection = get_intersection(A, B)
    union = get_area(A) + get_area(B) - intersection
    # Turn into loss
    l = 1.0 - intersection / union
    return l.mean()

Квадрат разницы диаметров

Чтобы создать меру ошибки для неперекрывающихся ограничивающих рамок, я попытался вычислить квадрат разницы диаметра ограничивающей рамки. Кажется, это работает, но я почти уверен, что есть гораздо лучший способ сделать это. Я реализовал это как:

def squared_diameter_loss(A, B):
    # Represent the squared distance from the real diameter
    # in normalized pixel coordinates
    l = (abs(A[:,0:2]-B[:,0:2]) + abs(A[:,2:4]-B[:,2:4]))**2
    return l.mean()

Евклидова потеря

Простейшей функцией будет Euclidean Loss, которая вычисляет квадратный корень из разницы квадратов параметров ограничивающей рамки. Однако при этом не учитывается площадь перекрывающейся ограничивающей рамки, а учитывается только разница параметров слева, справа, сверху, снизу. Я реализовал это как:

def euclidean_loss(A, B):
    l = lasagne.objectives.squared_error(A, B)
    return l.mean()

Может ли кто-нибудь указать мне, какая функция потерь будет лучшей для регрессии ограничивающей рамки для этого варианта использования или определить, если я делаю что-то неправильно здесь. Какая функция потерь обычно используется на практике?


person Christoph Körner    schedule 01.06.2016    source источник
comment
Примечание: я не думаю, что ваша долговая расписка работает. Вы можете рассчитать IOU с помощью shapely, и это даст другой ответ (0,33 против 0,4). boxA=shapely.geometry.box(0,0,10,5);boxB=shapely.geometry.box(5,0,10,10);iou = boxA.intersection(boxB).area/boxA.union(boxB).area   -  person wassname    schedule 11.09.2016
comment
В этой статье есть хорошо разработанная дифференцируемая функция потерь IoU: arxiv.org/pdf/1608.01471.pdf   -  person Ian Chu Te    schedule 30.11.2017


Ответы (1)


Говоря из личного опыта внедрения, у меня были гораздо лучшие результаты при обучении CNN с использованием IOU в качестве функции потерь, а не с евклидовой (MSE или L2) потерей. Не использовали потери разницы в квадрате диаметра. В общем, функция потерь, которая явно представляет качество ваших выходных данных для задач, которые вы надеетесь выполнить, вероятно, лучше всего.

Что касается долговой расписки, имеющей нулевое значение, вы можете ввести в формулировку некоторый дополнительный термин, чтобы он плавно стремился к 0, возможно, на основе нормализованного расстояния между центрами bbox. Это может дать дополнительный эффект, помогая центрировать ограничивающие прямоугольники относительно истинного положения.

Этот ответ в основном концептуальный, но я был бы рад предоставить примеры кода, если это необходимо.

person DerekG    schedule 04.09.2019