layer output 激活函数_深入理解YOLO v3实现细节 - 第3篇 构建v3的Loss_layer
深入理解YOLO v3實現細節系列文章,是本人根據自己對YOLO v3原理的理解,結合開源項目tensorflow-yolov3,寫的學習筆記。如有不正確的地方,請大佬們指出,謝謝!
目錄
第1篇 數據預處理
第2篇 backbone&network
第3篇 構建v3的 Loss_layer
1. 解讀YOLOv3 的損失函數
在分析yolo v3的損失函數之前,先來回顧一下yolo v1的損失函數。
一般來說系統設計需要平衡邊界框坐標損失、置信度損失和分類損失。論文中設計的損失函數如下:
對于 YOLOv3 的損失函數, Redmon J 在論文中并沒有進行講解。從darknet 源代碼中的forward_yolo_layer函數中找到 l.cost ,通過解讀,總結得到 YOLOv3 的損失函數如下:
與v1 Loss類似,主要分為三大部分: 邊界框坐標損失, 分類損失和置信度損失。
邊界框坐標損失 表示置信度,判斷網格內有無物體。與yolo v1的邊界框坐標損失類似,v3中使用誤差平方損失函數分別計算(x, y, w, h)的Loss,然后加在一起。v1中作者對寬高(w, h)做了開根號處理,為了弱化邊界框尺寸對損失值的影響。在v3中作者沒有采取開根號的處理方式,而是增加1個與物體框大小有關的權重,權重=2 - 相對面積,取值范圍(1~2)。
分類損失 表示置信度,判斷網格內有無物體。使用誤差平方損失函數計算類別class 的Loss。置信度損失使用誤差平方損失函數計算置信度conf 的Loss。
YOLO v3網絡輸出yolo v3三種不同尺度的輸出,一共產生了(13*13*3+26*26*3+52*52*3)=10647個預測框。
這個10647就是這么來的。
最終Loss采用和的形式而不是平均Loss, 主要原因為預測的特殊機制, 造成正負樣本比巨大, 尤其是置信度損失部分, 以一片包含一個目標為例, 置信度部分的正負樣本比可以高達1:10646, 如果采用平均損失, 會使損失趨近于0, 網絡預測變為全零, 失去預測能力。
參考上述原始的損失函數,加以優化。開始動手構建v3的Loss_layer!
2. 邊界框損失
對IoU和GIoU不了解的讀者可以看我寫的另外一篇文章: 目標檢測中的IOU&升級版GIOU
目前目標檢測中主流的邊界框優化采用的都是BBox的回歸損失(MSE loss, L1-smooth loss等),這些方式計算損失值的方式都是檢測框的“代理屬性”—— 距離,而忽略了檢測框本身最顯著的性質——IoU。由于IOU有2個致命缺點,導致它不太適合作為損失函數。GIoU延續了IoU的優良特性,并消除了IoU的致命缺點。以下使用GIoU Loss作為邊界框損失。
2.1 GIoU的計算
def bbox_giou(self, boxes1, boxes2):# 將boxes[x,y,w,h]化為[x_min, y_min, x_max, y_max]的形式boxes1 = tf.concat([boxes1[..., :2] - boxes1[..., 2:] * 0.5,boxes1[..., :2] + boxes1[..., 2:] * 0.5], axis=-1)boxes2 = tf.concat([boxes2[..., :2] - boxes2[..., 2:] * 0.5,boxes2[..., :2] + boxes2[..., 2:] * 0.5], axis=-1)boxes1 = tf.concat([tf.minimum(boxes1[..., :2], boxes1[..., 2:]),tf.maximum(boxes1[..., :2], boxes1[..., 2:])], axis=-1)boxes2 = tf.concat([tf.minimum(boxes2[..., :2], boxes2[..., 2:]),tf.maximum(boxes2[..., :2], boxes2[..., 2:])], axis=-1)# 計算boxes1、boxes2的面積boxes1_area = (boxes1[..., 2] - boxes1[..., 0]) * (boxes1[..., 3] - boxes1[..., 1])boxes2_area = (boxes2[..., 2] - boxes2[..., 0]) * (boxes2[..., 3] - boxes2[..., 1])# 計算boxes1和boxes2交集的左上角坐標和右下角坐標left_up = tf.maximum(boxes1[..., :2], boxes2[..., :2])right_down = tf.minimum(boxes1[..., 2:], boxes2[..., 2:])# 計算交集區域的寬高,如果right_down - left_up < 0,沒有交集,寬高設置為0inter_section = tf.maximum(right_down - left_up, 0.0)# 交集面積等于交集區域的寬 * 高inter_area = inter_section[..., 0] * inter_section[..., 1]# 計算并集面積union_area = boxes1_area + boxes2_area - inter_area# 計算IOUiou = inter_area / union_area# 計算最小閉合凸面 C 左上角和右下角的坐標enclose_left_up = tf.minimum(boxes1[..., :2], boxes2[..., :2])enclose_right_down = tf.maximum(boxes1[..., 2:], boxes2[..., 2:])# 計算最小閉合凸面 C的寬高enclose = tf.maximum(enclose_right_down - enclose_left_up, 0.0)# 計算最小閉合凸面 C的面積 = 寬 * 高enclose_area = enclose[..., 0] * enclose[..., 1]# 計算GIoUgiou = iou - 1.0 * (enclose_area - union_area) / enclose_areareturn giou2.2 GIoU loss 的計算
還記得label是怎么來嗎?在 第1篇 數據預處理 的4.3章節中有詳細說明,這里不再多說。當你清楚了label是什么,表示什么,respond_bbox就容易理解了。
respond_bbox = label[:, :, :, :, 4:5] # 置信度,判斷網格內有無物體 ... giou = tf.expand_dims(self.bbox_giou(pred_xywh, label_xywh), axis=-1) # 2 - 相對面積 bbox_loss_scale = 2.0 - 1.0 * label_xywh[:, :, :, :, 2:3] * label_xywh[:, :, :, :, 3:4] / (input_size ** 2)giou_loss = respond_bbox * bbox_loss_scale * (1 - giou)- respond_bbox 的意思是如果網格單元中包含物體,那么就會計算邊界框損失;
- box_loss_scale = 2 - 相對面積,值的范圍是(1~2),邊界框的尺寸越小,bbox_loss_scale 的值就越大。box_loss_scale可以弱化邊界框尺寸對損失值的影響;
- 兩個邊界框之間的 GIoU 值越大,giou 的損失值就會越小, 因此網絡會朝著預測框與真實框重疊度較高的方向去優化。
3. 置信度損失
3.1 引入Focal Loss
論文發現,密集檢測器訓練過程中,所遇到的極端前景背景類別不均衡(extreme foreground-background class imbalance)是核心原因。為了解決 one-stage 目標檢測器在訓練過程中出現的極端前景背景類不均衡的問題,引入Focal Loss。Focal Loss, 通過修改標準的交叉熵損失函數,降低對能夠很好分類樣本的權重(down-weights the loss assigned to well-classified examples),解決類別不均衡問題.
Focal Loss的計算公式:
是不同類別的分類概率, 權重因子 是個[0,1]間的小數,縮放因子 是個大于0的值。 和都是固定值,不參與訓練。 和 的最優值是相互影響的,所以在評估準確度時需要把兩者組合起來調節。作者在論文中給出 = 0.25 (即正負樣本比例為1:3)、 = 2 時性能最佳。此外,實驗結果表面在計算 時用sigmoid方法比softmax準確度更高。講了這么多,我們來看代碼吧!
先定義權重因子
和縮放因子 。target分為前景類和背景類,當target是前景類時為1,背景類時為0。 def focal(self, target, actual, alpha=0.25, gamma=2):focal_loss = tf.abs(alpha + target - 1) * tf.pow(tf.abs(target - actual), gamma)return focal_loss鑒于論文實驗結果表明sigmoid方法比softmax準確度更高,下面選用sigmoid_cross_entropy交叉熵來計算置信度損失
3.2 計算置信度損失
conf_loss的計算公式:
計算置信度損失必須清楚conv_raw_conf和pred_conf是怎么來的。還記得上一篇文章提到的邊界框預測decode函數嗎?對,就是從那來的。
def decode(self, conv_output, anchors, stride):"""return tensor of shape [batch_size, output_size, output_size, anchor_per_scale, 5 + num_classes]contains (x, y, w, h, score, probability)""" conv_shape = tf.shape(conv_output)batch_size = conv_shape[0]output_size = conv_shape[1]anchor_per_scale = len(anchors) # 3# 將v3網絡最終輸出的255維特征向量的形狀變為anchor_per_scale, x + y + w + h + score + num_classconv_output = tf.reshape(conv_output, (batch_size, output_size, output_size, anchor_per_scale, 5 + self.num_class))# v3網絡輸出的scoreconv_raw_conf = conv_output[:, :, :, :, 4:5]# 計算預測框里object的置信度pred_conf = tf.sigmoid(conv_raw_conf)conv_raw_conf 對應計算公式中的
, pred_conf 對應公式中的 。nice,開始動手構建conf_loss!
iou = bbox_iou(pred_xywh[:, :, :, :, np.newaxis, :], bboxes[:, np.newaxis, np.newaxis, np.newaxis, :, :]) # 找出與真實框 iou 值最大的預測框 max_iou = tf.expand_dims(tf.reduce_max(iou, axis=-1), axis=-1) # 如果最大的 iou 小于閾值,那么認為該預測框不包含物體,則為背景框 respond_bgd = (1.0 - respond_bbox) * tf.cast( max_iou < IOU_LOSS_THRESH, tf.float32 )conf_focal = self.focal(respond_bbox, pred_conf) # 計算置信度的損失(我們希望假如該網格中包含物體,那么網絡輸出的預測框置信度為 1,無物體時則為 0) conf_loss = conf_focal * (respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits(labels=respond_bbox, logits=conv_raw_conf)+respond_bgd * tf.nn.sigmoid_cross_entropy_with_logits(labels=respond_bbox, logits=conv_raw_conf))4.分類損失
這里分類損失采用的是二分類的交叉熵,即把所有類別的分類問題歸結為是否屬于這個類別,這樣就把多分類看做是二分類問題。
prob_loss = respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits(labels=label_prob, logits=conv_raw_prob)5. 最終Loss計算
將各部分損失值的和,除以均值,累加,作為最終的圖片損失值。
giou_loss = tf.reduce_mean(tf.reduce_sum(giou_loss, axis=[1,2,3,4]))conf_loss = tf.reduce_mean(tf.reduce_sum(conf_loss, axis=[1,2,3,4]))prob_loss = tf.reduce_mean(tf.reduce_sum(prob_loss, axis=[1,2,3,4]))return giou_loss, conf_loss, prob_loss補充
tf.pow函數具體使用方法:
TensorFlow冪值計算函數:tf.pow_w3cschool?www.w3cschool.cntf.nn.sigmoid_cross_entropy_with_logits函數使用方法:
TensorFlow函數教程:tf.nn.sigmoid_cross_entropy_with_logits_w3cschool?www.w3cschool.cntf.expand_dims函數使用方法:
TensorFlow函數教程:tf.keras.backend.expand_dims_w3cschool?www.w3cschool.cnFocal Loss詳細講解和公式推導過程可以參考這篇文章:
Focal Loss 論文理解及公式推導?www.aiuai.cnsoftmax_cross_entropy和sigmoid_cross_entropy之間的區別可以參考這篇文章:
損失函數softmax_cross_entropy、binary_cross_entropy、sigmoid_cross_entropy之間的區別與聯系?www.jianshu.com謝謝觀看,覺得好就點個贊唄!
總結
以上是生活随笔為你收集整理的layer output 激活函数_深入理解YOLO v3实现细节 - 第3篇 构建v3的Loss_layer的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: aspose.words 表格内容水平居
- 下一篇: 矩形变弧度角_在上海做下颌角整形这些医生