<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          YOLOv4損失函數(shù)全面解析

          共 10712字,需瀏覽 22分鐘

           ·

          2021-05-30 01:49

          點(diǎn)擊上方小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時(shí)間送達(dá)

          本文轉(zhuǎn)自:計(jì)算機(jī)視覺(jué)聯(lián)盟

          AI博士筆記系列推薦
          周志華《機(jī)器學(xué)習(xí)》手推筆記正式開(kāi)源!可打印版本附pdf下載鏈接


          1.前言


          如果您對(duì)YOLO V4的結(jié)構(gòu)比較感興趣,建議您可以結(jié)合代碼以及我的這篇文章進(jìn)行消化。代碼是基于Keras版本的,結(jié)構(gòu)很清晰,鏈接如下:

          YOLO V4 Keras:https:github.com/Ma-Dan/keras-yolo4

          YOLO V4相較于YOLO V3做了很多小創(chuàng)新,堪稱目標(biāo)檢測(cè)tricks萬(wàn)花筒。既然YOLO V4結(jié)構(gòu)大家都懂了,根據(jù)網(wǎng)絡(luò)的輸出標(biāo)簽信息進(jìn)行損失函數(shù)的設(shè)定,實(shí)現(xiàn)網(wǎng)絡(luò)參數(shù)的更新,一個(gè)完整的YOLO V4模型訓(xùn)練過(guò)程就可以被復(fù)現(xiàn)了。

          YOLO V4原文中提到,在進(jìn)行bounding box regression的時(shí)候,傳統(tǒng)的目標(biāo)檢測(cè)模型(比如YOLO V3)等,都是直接根據(jù)預(yù)測(cè)框真實(shí)框中心點(diǎn)坐標(biāo)以及寬高信息設(shè)定MSE(均方誤差)損失函數(shù)的。為了方便大家理解,下面給出了YOLO V3的總損失函數(shù)。

          YOLO V3的損失函數(shù)

          可以看出,第一行的兩個(gè),就是用在bounding box regression的損失函數(shù)MSE。有關(guān)該損失函數(shù)的具體解析可以見(jiàn)我文章《YOLO V3 深度解析 (下)》(https://zhuanlan.zhihu.com/p/138857662),這里就不進(jìn)行贅述。


          2. IOU損失函數(shù)理論部分


          鑒于MSE存在的一些問(wèn)題,比如原文中提到

          However, to directly estimate the coordinate values of each point of the BBox is to treat these points as independent variables, but in fact does not consider the integrity of the object itself.

          意思就是MSE損失函數(shù)將檢測(cè)框中心點(diǎn)坐標(biāo)寬高等信息作為獨(dú)立的變量對(duì)待的,但是實(shí)際上他們之間是有關(guān)系的。從直觀上來(lái)說(shuō),框的中心點(diǎn)和寬高的確存在著一定的關(guān)系。所以解決方法是使用IOU損失代替MSE損失。

          接著作者就IOU損失依次提到了以下的一些的損失函數(shù)。

          • (1)IOU損失
          • (2)GIOU損失
          • (3)DIOU損失
          • (4)CIOU損失

          (1)IOU損失

          其中IOU損失定義非常簡(jiǎn)單,即1與預(yù)測(cè)框A和真實(shí)框B之間交并比的差值

          但是這樣該損失函數(shù)會(huì)有一些問(wèn)題,該損失函數(shù)只在bounding box重疊的時(shí)候才管用,在他們沒(méi)有重疊情況下,將不會(huì)提供滑動(dòng)梯度。(這句話摘自論文《Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression》)

          (2)GIOU損失

          其實(shí)GIOU的全稱叫做 :generalized IoU loss。提出來(lái)是為了緩解上述IOU損失在檢測(cè)框不重疊時(shí)出現(xiàn)的梯度問(wèn)題。定義也是比較簡(jiǎn)單的,就在在原來(lái)的IOU損失的基礎(chǔ)上加上一個(gè)懲罰項(xiàng),公式如下:


          上式中A是預(yù)測(cè)框,B是真實(shí)框,C是A和B的最小包圍框,A,B,C的關(guān)系具體如下圖所示。

          A,B,C含義

          那么該懲罰項(xiàng)的意思就是下圖右邊黃色區(qū)域的比值。

          懲罰項(xiàng)含義

          雖然GIOU可以解決檢測(cè)框非重疊造成的梯度消失問(wèn)題,但是他還存在以下的限制,這里我們依舊是參考CIOU論文中的內(nèi)容。

          GIOU回歸過(guò)程

          上圖中綠色真實(shí)框黑色先驗(yàn)框Anchor藍(lán)色預(yù)測(cè)框。預(yù)測(cè)框是以先驗(yàn)框?yàn)榛A(chǔ)進(jìn)行位置移動(dòng)和大小縮放的。可以看出來(lái),GIOU首先嘗試增大預(yù)測(cè)框的大小,使得它能夠與真實(shí)框有所重疊(如上圖中間所示),然后才能進(jìn)行上述公式中  的計(jì)算。那么這樣做的話,會(huì)消耗大量的時(shí)間在預(yù)測(cè)框嘗試與真實(shí)框接觸上,這會(huì)影響損失的收斂速度。所以DIOU和GIOU的提出解決了上述GIOU的問(wèn)題。

          (3)DIOU

          DIOU和CIOU都出自論文《Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression》(https://link.zhihu.com/?target=https%3A//arxiv.org/abs/1911.08287)。作者說(shuō)他直接在IOU損失的基礎(chǔ)上加了一個(gè)簡(jiǎn)單的懲罰項(xiàng),用來(lái)最小化兩個(gè)檢測(cè)框中心點(diǎn)的標(biāo)準(zhǔn)化距離, 這樣可以加速損失的收斂過(guò)程。如下圖所示為GIOU和DIOU的對(duì)比。

          紅色框是DIOU損失中的預(yù)測(cè)框。可以很明顯的看出,DIOU的收斂速度較GIOU更快。

          那么有關(guān)DIOU的定義是怎么樣的呢?下面給出公式定義:


          相比于IOU損失,DIOU損失也多出了一個(gè)懲罰項(xiàng)  。該懲罰項(xiàng)具體的參數(shù)含義為

          • A : 預(yù)測(cè)框 B:真實(shí)框
          •  : 預(yù)測(cè)框中心點(diǎn)坐標(biāo)  :真實(shí)框中心點(diǎn)坐標(biāo)
          •  是歐式距離的計(jì)算
          • c 為 A , B 最小包圍框對(duì)角線長(zhǎng)度

          我給出了下圖,便于大家理解。

          所以兩個(gè)框距離越遠(yuǎn),DIOU越接近2,距離越近,DIOU越接近0

          提出DIOU還不夠,作者進(jìn)一步地提出了CIOU(Complete IoU Loss)。

          (4)CIOU

          CIOU作者考慮的更加全面一些,DIOU考慮到了兩個(gè)檢測(cè)框的中心距離。而CIOU考慮到了三個(gè)幾何因素,分別為

          • (1)重疊面積
          • (2)中心點(diǎn)距離
          • (3)長(zhǎng)寬比

          這里仔細(xì)觀察,會(huì)發(fā)現(xiàn),CIOU比DIOU多了一個(gè)長(zhǎng)寬比的信息,那么CIOU的公式定義如下:


          那么這個(gè)  對(duì)長(zhǎng)寬比的懲罰項(xiàng)了。論文中提到,  是一個(gè)正數(shù),  用來(lái)測(cè)量長(zhǎng)寬比的一致性(v measures the consistency of aspect ratio)。具體定義如下:

          上述公式中,參數(shù)說(shuō)明如下:

          •  和  為真實(shí)框的寬、高
          •  和  為預(yù)測(cè)框的寬、高

          若真實(shí)框和預(yù)測(cè)框的寬高相似,那么  為0,該懲罰項(xiàng)就不起作用了。所以很直觀地,這個(gè)懲罰項(xiàng)作用就是控制預(yù)測(cè)框的寬高能夠盡可能快速地與真實(shí)框的寬高接近。

          那么至此,有關(guān)YOLO V4損失函數(shù)的理論部分就說(shuō)完了。

          3.IOU損失函數(shù)的實(shí)戰(zhàn)部分

          說(shuō)完了上述四個(gè)IOU理論部分,我們回歸其在YOLO V4框架中的位置并進(jìn)行解析。結(jié)合keras的代碼,如下為CIOU損失函數(shù)的定義。

          def bbox_ciou(boxes1, boxes2):'''    計(jì)算ciou = iou - p2/c2 - av    :param boxes1: (8, 13, 13, 3, 4)   pred_xywh    :param boxes2: (8, 13, 13, 3, 4)   label_xywh    :return:


             舉例時(shí)假設(shè)pred_xywh和label_xywh的shape都是(1, 4)    '''


          # 變成左上角坐標(biāo)、右下角坐標(biāo)    boxes1_x0y0x1y1 = tf.concat([boxes1[..., :2] - boxes1[..., 2:] * 0.5,                                 boxes1[..., :2] + boxes1[..., 2:] * 0.5], axis=-1)    boxes2_x0y0x1y1 = tf.concat([boxes2[..., :2] - boxes2[..., 2:] * 0.5,                                 boxes2[..., :2] + boxes2[..., 2:] * 0.5], axis=-1)'''    逐個(gè)位置比較boxes1_x0y0x1y1[..., :2]和boxes1_x0y0x1y1[..., 2:],即逐個(gè)位置比較[x0, y0]和[x1, y1],小的留下。    比如留下了[x0, y0]    這一步是為了避免一開(kāi)始w h 是負(fù)數(shù),導(dǎo)致x0y0成了右下角坐標(biāo),x1y1成了左上角坐標(biāo)。    '''    boxes1_x0y0x1y1 = tf.concat([tf.minimum(boxes1_x0y0x1y1[..., :2], boxes1_x0y0x1y1[..., 2:]),                                 tf.maximum(boxes1_x0y0x1y1[..., :2], boxes1_x0y0x1y1[..., 2:])], axis=-1)    boxes2_x0y0x1y1 = tf.concat([tf.minimum(boxes2_x0y0x1y1[..., :2], boxes2_x0y0x1y1[..., 2:]),                                 tf.maximum(boxes2_x0y0x1y1[..., :2], boxes2_x0y0x1y1[..., 2:])], axis=-1)


          # 兩個(gè)矩形的面積    boxes1_area = (boxes1_x0y0x1y1[..., 2] - boxes1_x0y0x1y1[..., 0]) * (                boxes1_x0y0x1y1[..., 3] - boxes1_x0y0x1y1[..., 1])    boxes2_area = (boxes2_x0y0x1y1[..., 2] - boxes2_x0y0x1y1[..., 0]) * (                boxes2_x0y0x1y1[..., 3] - boxes2_x0y0x1y1[..., 1])


          # 相交矩形的左上角坐標(biāo)、右下角坐標(biāo),shape 都是 (8, 13, 13, 3, 2)    left_up = tf.maximum(boxes1_x0y0x1y1[..., :2], boxes2_x0y0x1y1[..., :2])    right_down = tf.minimum(boxes1_x0y0x1y1[..., 2:], boxes2_x0y0x1y1[..., 2:])


          # 相交矩形的面積inter_area。iou    inter_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    iou = inter_area / (union_area + K.epsilon())


          # 包圍矩形的左上角坐標(biāo)、右下角坐標(biāo),shape 都是 (8, 13, 13, 3, 2)    enclose_left_up = tf.minimum(boxes1_x0y0x1y1[..., :2], boxes2_x0y0x1y1[..., :2])    enclose_right_down = tf.maximum(boxes1_x0y0x1y1[..., 2:], boxes2_x0y0x1y1[..., 2:])


          # 包圍矩形的對(duì)角線的平方    enclose_wh = enclose_right_down - enclose_left_up    enclose_c2 = K.pow(enclose_wh[..., 0], 2) + K.pow(enclose_wh[..., 1], 2)


          # 兩矩形中心點(diǎn)距離的平方    p2 = K.pow(boxes1[..., 0] - boxes2[..., 0], 2) + K.pow(boxes1[..., 1] - boxes2[..., 1], 2)


          # 增加av。加上除0保護(hù)防止nan。    atan1 = tf.atan(boxes1[..., 2] / (boxes1[..., 3] + K.epsilon()))    atan2 = tf.atan(boxes2[..., 2] / (boxes2[..., 3] + K.epsilon()))    v = 4.0 * K.pow(atan1 - atan2, 2) / (math.pi ** 2)    a = v / (1 - iou + v)


             ciou = iou - 1.0 * p2 / enclose_c2 - 1.0 * a * v    return ciou

          以上,代碼原作者也是做了一個(gè)非常詳細(xì)的代碼注釋呀。可以看出,該函數(shù)定義和理論部分一致,特別是最后一行代碼,和我們理論部分說(shuō)的一模一樣哈。

          ciou = iou - 1.0 * p2 / enclose_c2 - 1.0 * a * v

          該CIOU函數(shù)定義被用在求解總損失函數(shù)上了,我們知道YOLO V3的損失函數(shù)主要分為三部分,分別為:

          • (1)bounding box regression損失
          • (2)置信度損失
          • (3)分類損失

          YOLO V4相較于YOLO V3,只在bounding box regression做了創(chuàng)新,用CIOU代替了MSE,其他兩個(gè)部分沒(méi)有做實(shí)質(zhì)改變。其代碼分別定義如下:

          (1)bounding box regression損失

          def loss_layer(conv, pred, label, bboxes, stride, num_class, iou_loss_thresh):    conv_shape = tf.shape(conv)    batch_size = conv_shape[0]    output_size = conv_shape[1]    input_size = stride * output_size    conv = tf.reshape(conv, (batch_size, output_size, output_size,                             3, 5 + num_class))    conv_raw_prob = conv[:, :, :, :, 5:]


             pred_xywh = pred[:, :, :, :, 0:4]    pred_conf = pred[:, :, :, :, 4:5]


             label_xywh = label[:, :, :, :, 0:4]    respond_bbox = label[:, :, :, :, 4:5]    label_prob = label[:, :, :, :, 5:]


             ciou = tf.expand_dims(bbox_ciou(pred_xywh, label_xywh), axis=-1)  # (8, 13, 13, 3, 1)    input_size = tf.cast(input_size, tf.float32)


             # 每個(gè)預(yù)測(cè)框xxxiou_loss的權(quán)重 = 2 - (ground truth的面積/圖片面積)    bbox_loss_scale = 2.0 - 1.0 * label_xywh[:, :, :, :, 2:3] * label_xywh[:, :, :, :, 3:4] / (input_size ** 2)    ciou_loss = respond_bbox * bbox_loss_scale * (1 - ciou)  # 1. respond_bbox作為mask,有物體才計(jì)算xxxiou_loss

          (2)置信度損失

              
          # 2. respond_bbox作為mask,有物體才計(jì)算類別loss    prob_loss = respond_bbox * tf.nn.sigmoid_cross_entropy_with_logits(labels=label_prob, logits=conv_raw_prob)


          (3)分類損失    # 3. xxxiou_loss和類別loss比較簡(jiǎn)單。重要的是conf_loss,是一個(gè)focal_loss    # 分兩步:第一步是確定 grid_h * grid_w * 3 個(gè)預(yù)測(cè)框 哪些作為反例;第二步是計(jì)算focal_loss。    expand_pred_xywh = pred_xywh[:, :, :, :, np.newaxis, :]  # 擴(kuò)展為(?, grid_h, grid_w, 3,   1, 4)    expand_bboxes = bboxes[:, np.newaxis, np.newaxis, np.newaxis, :, :]  # 擴(kuò)展為(?,      1,      1, 1, 150, 4)    iou = bbox_iou(expand_pred_xywh, expand_bboxes)  # 所有格子的3個(gè)預(yù)測(cè)框 分別 和 150個(gè)ground truth  計(jì)算iou。(?, grid_h, grid_w, 3, 150)    max_iou = tf.expand_dims(tf.reduce_max(iou, axis=-1), axis=-1)  # 與150個(gè)ground truth的iou中,保留最大那個(gè)iou。(?, grid_h, grid_w, 3, 1)


             # respond_bgd代表  這個(gè)分支輸出的 grid_h * grid_w * 3 個(gè)預(yù)測(cè)框是否是 反例(背景)    # label有物體,respond_bgd是0。沒(méi)物體的話:如果和某個(gè)gt(共150個(gè))的iou超過(guò)iou_loss_thresh,respond_bgd是0;如果和所有g(shù)t(最多150個(gè))的iou都小于iou_loss_thresh,respond_bgd是1。    # respond_bgd是0代表有物體,不是反例;權(quán)重respond_bgd是1代表沒(méi)有物體,是反例。    # 有趣的是,模型訓(xùn)練時(shí)由于不斷更新,對(duì)于同一張圖片,兩次預(yù)測(cè)的 grid_h * grid_w * 3 個(gè)預(yù)測(cè)框(對(duì)于這個(gè)分支輸出)  是不同的。用的是這些預(yù)測(cè)框來(lái)與gt計(jì)算iou來(lái)確定哪些預(yù)測(cè)框是反例。    # 而不是用固定大小(不固定位置)的先驗(yàn)框。    respond_bgd = (1.0 - respond_bbox) * tf.cast(max_iou < iou_loss_thresh, tf.float32)


             # 二值交叉熵?fù)p失    pos_loss = respond_bbox * (0 - K.log(pred_conf + K.epsilon()))    neg_loss = respond_bgd  * (0 - K.log(1 - pred_conf + K.epsilon()))


             conf_loss = pos_loss + neg_loss    # 回顧respond_bgd,某個(gè)預(yù)測(cè)框和某個(gè)gt的iou超過(guò)iou_loss_thresh,不被當(dāng)作是反例。在參與“預(yù)測(cè)的置信位 和 真實(shí)置信位 的 二值交叉熵”時(shí),這個(gè)框也可能不是正例(label里沒(méi)標(biāo)這個(gè)框是1的話)。這個(gè)框有可能不參與置信度loss的計(jì)算。    # 這種框一般是gt框附近的框,或者是gt框所在格子的另外兩個(gè)框。它既不是正例也不是反例不參與置信度loss的計(jì)算。(論文里稱之為ignore)

          最后對(duì)上述的三個(gè)損失取個(gè)平均即可,如下

              ciou_loss = tf.reduce_mean(tf.reduce_sum(ciou_loss, axis=[1, 2, 3, 4]))  # 每個(gè)樣本單獨(dú)計(jì)算自己的ciou_loss,再求平均值    conf_loss = tf.reduce_mean(tf.reduce_sum(conf_loss, axis=[1, 2, 3, 4]))  # 每個(gè)樣本單獨(dú)計(jì)算自己的conf_loss,再求平均值    prob_loss = tf.reduce_mean(tf.reduce_sum(prob_loss, axis=[1, 2, 3, 4]))  # 每個(gè)樣本單獨(dú)計(jì)算自己的prob_loss,再求平均值

          至此,結(jié)合代碼,有關(guān)YOLO V4損失函數(shù)的實(shí)戰(zhàn)部分也就說(shuō)完了!


          4.小結(jié)


          本文結(jié)合了四個(gè)IOU損失理論定義,以及CIOU在YOLO V4中代碼定義,詳細(xì)地分析了DIOU損失CIOU損失。在當(dāng)前目標(biāo)檢測(cè)模型中,這樣的損失函數(shù)的確能夠提高模型的表現(xiàn),所以我認(rèn)為后面這種損失函數(shù)會(huì)大量替代MSE損失函數(shù)做bounding box regression,所以弄懂并理解它們是有必要的。


          下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程
          在「小白學(xué)視覺(jué)」公眾號(hào)后臺(tái)回復(fù):擴(kuò)展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺(jué)、目標(biāo)跟蹤、生物視覺(jué)、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目52講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):Python視覺(jué)實(shí)戰(zhàn)項(xiàng)目即可下載包括圖像分割、口罩檢測(cè)、車道線檢測(cè)、車輛計(jì)數(shù)、添加眼線、車牌識(shí)別、字符識(shí)別、情緒檢測(cè)、文本內(nèi)容提取、面部識(shí)別等31個(gè)視覺(jué)實(shí)戰(zhàn)項(xiàng)目,助力快速學(xué)校計(jì)算機(jī)視覺(jué)。

          下載3:OpenCV實(shí)戰(zhàn)項(xiàng)目20講
          小白學(xué)視覺(jué)公眾號(hào)后臺(tái)回復(fù):OpenCV實(shí)戰(zhàn)項(xiàng)目20講即可下載含有20個(gè)基于OpenCV實(shí)現(xiàn)20個(gè)實(shí)戰(zhàn)項(xiàng)目,實(shí)現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。

          交流群


          歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~


          瀏覽 43
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩欧美伊人 | 操逼逼逼视频 | 日韩经典一级片 | A黄色视频网站 | 最新中文字幕MV第三季歌词完整版 |