CNN のバウンディング ボックス回帰の損失関数を理解しようとしています。現在、私は Lasagne と Theano を使用しています。これにより、損失式を非常に簡単に記述できます。多くの情報源がさまざまな方法を提案しています。
境界ボックスの座標は、[left, top, right, bottom]
( を使用してT.matrix('targets', dtype=theano.config.floatX)
) 順序で正規化された座標として表されます。
これまでに次の機能を試しました。ただし、それらにはすべて欠点があります。
ユニオン上の交差点
メジャーを使用しIntersection over Union
て、2 つのバウンディング ボックスの位置合わせと重なり具合を特定するようにアドバイスされました。ただし、ボックスが重なっておらず、交差が 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()
このユースケースのバウンディングボックス回帰に最適な損失関数、またはここで何か間違ったことをしている場合のスポットについて、誰かが私を案内してくれませんか。通常、実際に使用される損失関数はどれですか?