Я пытаюсь понять функции потерь для регрессии ограничивающей рамки в 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()
Может ли кто-нибудь указать мне, какая функция потерь будет лучшей для регрессии ограничивающей рамки для этого варианта использования или определить, если я делаю что-то неправильно здесь. Какая функция потерь обычно используется на практике?
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