之前再看Fast R-CNN的時候,網絡bounding boxes迴歸使用的smooth L1 loss,當時並沒有去細想爲什麼用這個loss而不是l2 loss,這個loss有什麼好?直到昨天看別的論文的時候提到smooth L1具有更強的魯棒性,爲什麼smooth L1 loss具有更好的魯棒性呢?上網查了下,下面是知乎的一個回答,感覺非常通俗易懂,所以就轉了過來,原文——請問faster rcnn和ssd 中爲什麼用smooth l1 loss,和l2有什麼區別?
smooth L1 loss能從兩個方面限制梯度:
- 當預測框與 ground truth 差別過大時,梯度值不至於過大;
- 當預測框與 ground truth 差別很小時,梯度值足夠小。
觀察 (4),當 x 增大時 L2 損失對 x 的導數也增大。這就導致訓練初期,預測值與 groud truth 差異過於大時,損失函數對預測值的梯度十分大,訓練不穩定。
根據方程 (5),L1 對 x 的導數爲常數。這就導致訓練後期,預測值與 ground truth 差異很小時, L1 損失對預測值的導數的絕對值仍然爲 1,而 learning rate 如果不變,損失函數將在穩定值附近波動,難以繼續收斂以達到更高精度。
最後觀察 (6),smooth L1 在 x 較小時,對 x 的梯度也會變小,而在 x 很大時,對 x 的梯度的絕對值達到上限 1,也不會太大以至於破壞網絡參數。 smooth L1 完美地避開了 L1 和 L2 損失的缺陷。其函數圖像如下:
由圖中可以看出,它在遠離座標原點處,圖像和 L1 loss 很接近,而在座標原點附近,轉折十分平滑,不像 L1 loss 有個尖角,因此叫做 smooth L1 loss。
參考:
請問faster rcnn和ssd 中爲什麼用smooth l1 loss,和l2有什麼區別?
keras實現smooth L1:
HUBER_DELTA = 0.5
def smoothL1(y_true, y_pred):
x = K.abs(y_true - y_pred)
x = K.switch(x < HUBER_DELTA, 0.5 * x ** 2, HUBER_DELTA * (x - 0.5 * HUBER_DELTA))
return K.sum(x)