人工智能|YOLOX笔记

目录
1. 样本匹配 正负样本划分过程
2. yoloxwarmcos 学习率
3. 无法开启多gpu训练, 或者多gpu训练卡住?


1. 样本匹配 正负样本划分过程 ==

说明: gt_centerbbox是在gt_bbox中心点向四周发散的bbox, 中心点到该bbox四边的距离是 center_radius * expanded_strides_per_image1. is_in_boxes:[n_gt, n_anchor], 样本中心点是否落在各个gt_bbox里面 2. is_in_boxes_all:[n_anchor],样本中心点是否至少落在1个gt_bbox里面 3. is_in_centers:[n_gt, n_anchor],样本中心点是否落在各个gt_centerbbox里面 4. is_in_centers_all: [n_anchor],样本中心点是否至少落在1个gt_centerbbox里面 5. is_in_boxes_anchor = is_in_boxes_all | is_in_centers_all, [n_anchor], 满足至少落在1个gt_bboxes里面或者1个gt_centerbbox里面 6. is_in_boxes_and_center = ( is_in_boxes[:, is_in_boxes_anchor] & is_in_centers[:, is_in_boxes_anchor] ), [n_gt, n_anchor] True表示同时落在gt_bboxes和gt_centerbbox里面 (落在gt_centerbbox不是已经表示落在gt_bboxes里面吗?难道是gt_centerbbox可能超出gt_bboxes?)n_pos = sum(is_in_boxes_anchor) 选出is_in_boxes_anchor==True的那些输出样本 ===========以上是先根据feature map上每个像素点的坐标, 选出落在gt_bbox里面的像素点, 数量为n_pos, 再拿到 网络在这些像素点上的预测样本 ===========下面进一步在这些预测样本(n_pos个)和gt_bboxes之间, 确定匹配关系, 找出哪些是正样本 哪些是负样本7. pair_wise_cls_loss: [n_gt, n_pos], 预测样本和gt_bboxes的两两cls loss, 用sqrt(cls_pred*obj_pred)作为预测得分, 得分越高该loss越小 8. pair_wise_ious_loss: [n_gt, n_pos], 预测样本和gt_bboxes的两两iou loss, iou越大该loss越小 9. cost = ( pair_wise_cls_loss + 3.0 * pair_wise_ious_loss + 100000.0 * (~is_in_boxes_and_center) ), 第三个表示如果anchor同时不落在gt_bboxes和gt_centerbbox里面则cost为100000 毕竟如果不落在gt_bboxes和gt_centerbbox里就不可能分配为正样本的 10. Dynamic K();



Dynamic K()算法过程:
==
Dynamic K(): 1. matching_matrix:[n_gt, n_pos], 标记gt与样本的匹配关系, 初始化为全0矩阵 n_candidate_k = 10 2. topk_ious:[n_gt, n_candidate_k], 选出与gt的iou在topk【大】的样本(根据pair_wise_ious不是pair_wise_ious_loss) 3. dynamic_ks:[n_gt], =max(topk_ious.sum(1), 1), 最小为1, 表示每个gt要选几个正样本 (参考如何评价旷视开源的YOLOX,效果超过YOLOv5? - 旷视科技的回答 - 知乎 https://www.zhihu.com/question/473350307/answer/2021031747, 这里说了“然后把这个 10 个预测与 gt 的 iou 加起来求得最终的k”) 4. for idx in range(num_gt): 对每个gt, 从cost[idx]选出cost值是top dynamic_ks[idx]【小】的样本, 这些样本被分配给该gt 5. 如果1个样本被分配给1个以上的gt, 则找出与该样本有最小cost的gt, 把该样本分配给这个gt 到这里已经是每个gt有1个样本, 每个样本最多被分配给1个gt或者没分配 分配到gt的样本就是正样本 6. 返回每个正样本的gt索引, gt类别, 以及样本与gt的iou

【人工智能|YOLOX笔记】参考代码: https://github.com/Megvii-BaseDetection/YOLOX/blob/main/yolox/models/yolo_head.py

2. yoloxwarmcos 学习率 ==
# 假设10个epoch,每个epoch有10个iters, # warmup_epochs=2, no_aug_epochs=3, # warmup_lr_start=0, min_lr_ratio=0.05ys = [] for i in range(10*10): v = yolox_warm_cos_lr( lr=0.01, min_lr_ratio=0.05, total_iters=10*10, warmup_total_iters=10*2, warmup_lr_start=0, no_aug_iter=10*3, iters=i, ) ys.append(v)

学习率曲线:
人工智能|YOLOX笔记
文章图片

结论是:
前2个epochs, 学习率从0->0.01
第3个epochs->第7个epochs, 学习率从0.01->0.01*0.05
最后3个epochs, 学习率保持0.01*0.05=0.0005

另外,
Exp里面,
self.basic_lr_per_img = 0.01 / 64.0,
trainer.py里面:
self.lr_scheduler = self.exp.get_lr_scheduler(
self.exp.basic_lr_per_img * self.args.batch_size, self.max_iter
)
所以训练时的最大学习率是:
lr = self.exp.basic_lr_per_img * self.args.batch_size = 0.01*batch_size / 64.0
3. 无法开启多gpu训练, 或者多gpu训练卡住? 去trainer.py, 检查是不是额外添加了什么代码, 导致各gpu之间不同步 如果是tensorboard logger这种记录变量, 就要确保只在其中一个gpu中执行, 比如在前面加上 if self.rank == 0:..., 完了之后最好再加上 synchronize() 同步一下.



    推荐阅读