triplet loss后面不收敛_【从零开始学习YOLOv3】8. YOLOv3中Loss部分计算

本文深入探讨YOLOv3的损失函数计算,包括 Anchor 的选择、偏移量的限制以及损失函数的三个组成部分:bbox loss、obj loss和class loss。详细解析了GIoU的运用以及正负样本的选取策略,揭示了模型训练中收敛的关键因素。
摘要由CSDN通过智能技术生成

YOLOv1是一个anchor-free的,从YOLOv2开始引入了Anchor,在VOC2007数据集上将mAP提升了10个百分点。YOLOv3也继续使用了Anchor,本文主要讲ultralytics版YOLOv3的Loss部分的计算, 实际上这部分loss和原版差距非常大,并且可以通过arc指定loss的构建方式, 如果想看原版的loss可以在下方release的v6中下载源码。

Github地址: https://github.com/ultralytics/yolov3

Github release: https://github.com/ultralytics/yolov3/releases

  • 1. Anchor

  • 2. 偏移公式

  • 3. Loss

  • 4. 代码

  • 5. 补充

1. Anchor

Faster R-CNN中Anchor的大小和比例是由人手工设计的,可能并不贴合数据集,有可能会给模型性能带来负面影响。YOLOv2和YOLOv3则是通过聚类算法得到最适合的k个框。聚类距离是通过IoU来定义,IoU越大,边框距离越近。

Anchor越多,平均IoU会越大,效果越好,但是会带来计算量上的负担,下图是YOLOv2论文中的聚类数量和平均IoU的关系图,在YOLOv2中选择了5个anchor作为精度和速度的平衡。

121aefdd801ce18efacc5a8a94d00c3f.png
YOLOv2中聚类Anchor数量和IoU的关系图

2. 偏移公式

在Faster RCNN中,中心坐标的偏移公式是:

其中、 代表中心坐标,和代表宽和高,和是模型预测的Anchor相对于Ground Truth的偏移量,通过计算得到的x,y就是最终预测框的中心坐标。

而在YOLOv2和YOLOv3中,对偏移量进行了限制,如果不限制偏移量,那么边框的中心可以在图像任何位置,可能导致训练的不稳定。

45560440aa5cbfa36ac3d879b40543e8.png
公式对应的意义

对照上图进行理解:

  • 和分别代表中心点所处区域的左上角坐标。

  • 和分别代表Anchor的宽和高。

  • 和分别代表预测框中心点和左上角的距离,代表sigmoid函数,将偏移量限制在当前grid中,有利于模型收敛。

  • 和代表预测的宽高偏移量,Anchor的宽和高乘上指数化后的宽高,对Anchor的长宽进行调整。

  • 是置信度预测值,是当前框有目标的概率乘以bounding box和ground truth的IoU的结果

3. Loss

YOLOv3中有一个参数是ignore_thresh,在ultralytics版版的YOLOv3中对应的是train.py文件中的iou_t参数(默认为0.225)。

正负样本是按照以下规则决定的

  • 如果一个预测框与所有的Ground Truth的最大IoU负样本。

  • 如果Ground Truth的中心点落在一个区域中,该区域就负责检测该物体。将与该物体有最大IoU的预测框作为正样本(注意这里没有用到ignore thresh,即使该最大IoU

在YOLOv3中,Loss分为三个部分:

  • 一个是xywh部分带来的误差,也就是bbox带来的loss
  • 一个是置信度带来的误差,也就是obj带来的loss
  • 最后一个是类别带来的误差,也就是class带来的loss

在代码中分别对应lbox, lobj, lcls,yolov3中使用的loss公式如下:

其中:

S: 代表grid size, 代表13x13,26x26, 52x52

B: box

: 如果在i,j处的box有目标,其值为1,否则为0

: 如果在i,j处的box没有目标,其值为1,否则为0

BCE(binary cross entropy)具体计算公式如下:

以上是论文中yolov3对应的darknet。而pytorch版本的yolov3改动比较大,有较大的改动空间,可以通过参数进行调整。

分成三个部分进行具体分析:

1. lbox部分

在ultralytics版版的YOLOv3中,使用的是GIOU,具体讲解见GIOU讲解链接。

简单来说是这样的公式,IoU公式如下:

而GIoU公式如下:

其中代表两个框最小闭包区域面积,也就是同时包含了预测框和真实框的最小框的面积。

yolov3中提供了IoU、GIoU、DIoU和CIoU等计算方式,以GIoU为例:

if GIoU:  # Generalized IoU https://arxiv.org/pdf/19
import pandas as pd import math as mt import numpy as np from sklearn.model_selection import train_test_split from Recommenders import SVDRecommender triplet_dataset_sub_song_merged = triplet_dataset_sub_song_mergedpd triplet_dataset_sub_song_merged_sum_df = triplet_dataset_sub_song_merged[['user','listen_count']].groupby('user').sum().reset_index() triplet_dataset_sub_song_merged_sum_df.rename(columns={'listen_count':'total_listen_count'},inplace=True) triplet_dataset_sub_song_merged = pd.merge(triplet_dataset_sub_song_merged,triplet_dataset_sub_song_merged_sum_df) triplet_dataset_sub_song_merged['fractional_play_count'] = triplet_dataset_sub_song_merged['listen_count']/triplet_dataset_sub_song_merged small_set = triplet_dataset_sub_song_merged user_codes = small_set.user.drop_duplicates().reset_index() song_codes = small_set.song.drop_duplicates().reset_index() user_codes.rename(columns={'index':'user_index'}, inplace=True) song_codes.rename(columns={'index':'song_index'}, inplace=True) song_codes['so_index_value'] = list(song_codes.index) user_codes['us_index_value'] = list(user_codes.index) small_set = pd.merge(small_set,song_codes,how='left') small_set = pd.merge(small_set,user_codes,how='left') mat_candidate = small_set[['us_index_value','so_index_value','fractional_play_count']] data_array = mat_candidate.fractional_play_count.values row_array = mat_candidate.us_index_value.values col_array = mat_candidate.so_index_value.values data_sparse = coo_matrix((data_array, (row_array, col_array)),dtype=float) K=50 urm = data_sparse MAX_PID = urm.shape[1] MAX_UID = urm.shape[0] recommender = SVDRecommender(K) U, S, Vt = recommender.fit(urm) Compute recommendations for test users uTest = [1,6,7,8,23] uTest_recommended_items = recommender.recommend(uTest, urm, 10) Output recommended songs in a dataframe recommendations = pd.DataFrame(columns=['user','song', 'score','rank']) for user in uTest: rank = 1 for song_index in uTest_recommended_items[user, 0:10]: song = small_set.loc[small_set['so_index_value'] == song_index].iloc[0] # Get song details recommendations = recommendations.append({'user': user, 'song': song['title'], 'score': song['fractional_play_count'], 'rank': rank}, ignore_index=True) rank += 1 display(recommendations)这段代码报错了,为什么?给出修改后的 代码
06-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值