0.无语
1.理论回头补充吧
2.流程:
a.将预测的box框的(x,y,h,w)与anchor(5个)去做对应,得到预测框box在特征图上的真正预测值(x0,y0,h0,w0)。yolo_to_bbox函数实现
b.计算真值的预测框与预测值的box框的iou值。bbox_np函数实现。是在像素坐标图上实现的
c.用阈值卡肯定无目标区域,准备这个区域的loss函数计算。无目标的置信度loss的组成部分
d.计算真值与anchor框的iou值。anchor_intersections函数实现。是在特征图上实现的。
e.根据d的计算,找出真值对应的最佳anchor,认为此区域包含目标了,然后计算有用目标的3个loss的组成部分,3个loss分别是 置信度loss, 分类loss, box框loss。
1. 最开始的处理
# tx, ty, tw, th, to -> sig(tx), sig(ty), exp(tw), exp(th), sig(to)
# xy_pred存储的是中心坐标相对于cell左上角的x坐标和y坐标的偏置,采用sigmod是为了将偏置控制在0和1之间。
xy_pred = F.sigmoid(global_average_pool_reshaped[:, :, :, 0:2])
# wh_pred存储的是预测的width和height,需要用指数函数解码
wh_pred = torch.exp(global_average_pool_reshaped[:, :, :, 2:4])
bbox_pred = torch.cat([xy_pred, wh_pred], 3) #bbox_pred [batchsize w * h num_anchors 4]
# iou_pred存储的是IOU存在置信度,采用sigmod控制在0和1之间 二分类 存在与否
iou_pred = F.sigmoid(global_average_pool_reshaped[:, :, :, 4:5])
# score_pred存储的是分类置信度,采用softmax控制在0和1之间 多分类 属于哪个类别
score_pred = global_average_pool_reshaped[:, :, :, 5:].contiguous()
prob_pred = F.softmax(score_pred.view(-1, score_pred.size()[-1])).view_as(score_pred) # noqa
2.anchor与预测值之间是怎么对应上的,下面这个代码里写的很清晰。此函数计算的是每个预测的box框在5个尺度(anchor)下在特征图上的预测框值(拗口哈,因为预测值bbox_pred_np是一个0~1之间的相对于网格左上角的偏移量,只有乘上anchor后才是目标在当前网格的当前anchor下的一个预测值框,这个值才能映射回原图,得到像素坐标)。换句话说,只有经过这个函数的处理,得到的才是在特征图上的预测边界。对应语句是bbox_np = bbox_np[0]
cimport cython
import numpy as np
cimport numpy as np
DTYPE = np.float
ctypedef np.float_t DTYPE_t
cdef extern from "math.h":
double abs(double m)
double log(double x)
def yolo_to_bbox(
np.ndarray[DTYPE_t, ndim=4] bbox_pred,
np.ndarray[DTYPE_t, ndim=2] anchors, int H, int W):
return yolo_to_bbox_c(bbox_pred, anchors, H, W)
cdef yolo_to_bbox_c(
np.ndarray[DTYPE_t, ndim=4] bbox_pred,
np.ndarray[DTYPE_t, ndim=2] anchors, int H, int W):
"""
Parameters
--