一、读取cfg文件,根据cfg文件构建网络。
[convolutional]
batch_normalize=1
filters=64
size=3
stride=2
pad=1
activation=leaky
保存为如下格式:
[{"type":convolutional, "batch_normalize":1, "filters":64, "size":3,
"Stride":2, "pad":=1, "activation":leaky},...]
遍历所有模块,利用torch.nn.Sequential构建网络结构。block的保存顺序与网络顺序一致,所以可以用block重新构建网络。
model = torch.nn.Sequential()
conv = torch.nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias=bias)
model.add_model("conv_{0}".format(index), conv)
- yolov3中,若存在batch_normalization,则无bias,反之亦然。
- Conv1d:一维卷积层,输入的尺度是(N, C_in,L),输出尺度( N,C_out,L_out);Conv2d:二维卷积层, 输入的尺度是(N, C_in,H,W),输出尺度(N,C_out,H_out,W_out)。
- BatchNorm2d:对小批量(mini-batch)3d数据组成的4d输入进行批标准化(Batch Normalization)操作。
- Upsample:bilinear,双线性差值。
- route,shortcut layer,构建nn.Module类的空层,在后面对输出层进行操作。
- yolo层为detection layer,所用anchors不同,所以构建detection layer时,将anchors作为参数。
二.将预测结果,进行格式转换。
预测输出的shape为:
(batch_size, num_anchors*bbox_attracs, grid_size*grid_size)
转换为:
(batch_size, grid_size*grid_size*num_anchors, bbox_attracs)
x | y | w | h | objectness | confidence score |
根据以上处理prediction。
- 注意squeeze与unsqueeze的利用,对于Tensor进行操作,一定要注意维度。
三.NMS。
遍历batch中的图片,分别进行以下操作:
- 根据object_score进行判断,将小于阈值的置零。
- 统计图片所有类别,即每个Bbox的预测结果,将每类分别处理,按confidence进行排序,得到索引值。根据NMS原理,逐步消除无用的bbox。
- 统计类别,用到np.unique()函数,先将Tensor转为numpy操作,最后再转回Tensor。
- 消除bbox时,遍历排好序的bbox,先判断与confidence最大的bbox的IOU,等到下一次循环,会选择除上一个之外的confidence最大的bbox继续进行操作。
- 消除小于阈值的bbox的方法,即利用torch.nonzero()函数,得到非零值的索引。