最近在训练yolo模型一类检测模型,我在训练过程中发现precision会降低,思考之后对其做出一些分析.

起因

我在训练yolo的时候,首先是进行分类检测,即只训练class_loss,obj_loss,noobj_loss,这个时候训练precision会达到60%.

接下来进行第二次迭代,这次同时训练class_loss,obj_loss,noobj_loss,xy_loss,wh_loss,这个时候precision会降低到40%.

如下图所示:

原因分析

经过思考,我找到问题所在:

""" calc the noobj mask ~ """
if train_classifier == 'True':
noobj_mask = tf.logical_not(obj_mask)
else:
noobj_mask = calc_noobj_mask(true_xy, true_wh, pred_xy, pred_wh, obj_mask, iou_thresh=iou_thresh, helper=helper)

这段代码就是当我开始训练xy_loss,wh_loss时,那么noobj_mask就需要通过预测出来的boxground truth box计算iou来筛选.

当我可以拟合box之后,那么也就是说如果其他的cell预测出来的boxground truth boxiou大于iou_threshold之后,那么这个cell我就不会将他设置为noobj cell,同时也不会对这个cell进行惩罚措施.

再看precisionrecall的计算方式: \[ \begin{aligned} precision&=\frac{true\ positive}{true\ positive+false\ positive} \\ recall&=\frac{true\ positive}{true\ positive+false\ negative} \end{aligned} \]

因为我没有对预测boxtrue boxiou大于iou_threshold进行惩罚,所以我们的\(false\ positive\)会增加,\(false\ negative\)会减少.最终导致precision减少,recall增加.