提示:本文为半成品暂时禁止转载。
文章目录
前言
假设输入为640*640的图像,经过fpn-pan结构得到20 * 20, 40 * 40, 80 * 80三种尺度的特征图:
20 * 20的特征层对应的anchor是[116,90], [156,198], [373,326];
40 * 40的特征层对应的anchor是[30,61], [62,45], [59,119];
80 * 80的特征层对应的anchor是[10,13], [16,30], [33,23];
三个特征层上的缩放32、16、8。
提示:以下是本篇文章正文内容,下面案例可供参考
首先计算20*20特征层的操作
一、先求出anchor在不同特征层上的缩放
计算方式: [116,90],[156,198],[373,326] / 32
结果: scaled_anchors = [(3.625, 2.8125), (4.875, 6.1875), (11.65625, 10.1875)]
二、修改输入维度
原始维度为: batch_size, 3 * (4 + 1 + num_classes), 20, 20
修改后的output维度:batch_size, 3 * (4 + 1 + num_classes), 20, 20 => batch_size, 3, 20, 20, 4 + 1 + num_classes 即:[4, 3, 20, 20, 85]
需要注意的是:一般输入255那个维度是3*85得出来的,而不是85*3得出来的,因此在维度转换的时候需要现将255先resize为3*85,然后再做permute维度变换,这点在写板端代码的时候需要特别注意。
三、对输出x,y,w,h,conf,pred做sigmod
x = sigmod(output[...,0]) 维度为:[4, 3, 20, 20]
y = sigmod(output[...,1]) 维度为:[4, 3, 20, 20]
w = sigmod(output[...,2]) 维度为:[4, 3, 20, 20]
h = sigmod(output[...,3]) 维度为:[4, 3, 20, 20]
conf = sigmod(output[...,4]) 维度为:[4, 3, 20, 20]
pred = sigmod(output[...,5:]) 维度为:[4, 3, 20, 20, 80]
四、生成网格,先验框中心,网格左上角的坐标矩阵
grid_x = [[[[ 0., 1., 2., ..., 17., 18., 19.],
[ 0., 1., 2., ..., 17., 18., 19.],
[ 0., 1., 2., ..., 17., 18., 19.],
...,
[ 0., 1., 2., ..., 17., 18., 19.],
[ 0., 1., 2., ..., 17., 18., 19.],
[ 0., 1., 2., ..., 17., 18., 19.]]]
第三和第四个维度填充的是 [ 0., 1., 2., …, 17., 18., 19.] 重复20次的矩阵,后面batch和 3 都只是重复把这个矩阵增加维度而已
grid_y = [[[[ 0., 0., 0., ..., 0., 0., 0.],
[ 1., 1., 1., ..., 1., 1., 1.],
[ 2., 2., 2., ..., 2., 2., 2.],
...,
[17., 17., 17., ..., 17., 17., 17.],
[18., 18., 18., ..., 18., 18., 18.],
[19., 19., 19., ..., 19., 19., 19.]]]
注:grid_y类似grid_x的转置。
五、处理anchor
将步骤一中的scaled_anchors的w取出来形成二维矩阵 3*1
anchor_w = [[ 3.6250],
[ 4.8750],
[11.6562]]
将步骤一中的scaled_anchors的h取出来形成二维矩阵 3*1
anchor_h =[[ 2.8125],
[ 6.1875],
[10.1875]]
将anchor_w扩充维度为 [4, 3, 20, 20]
anchor_w = [[[[3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250],
[ 3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250],
[ 3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250],
...,
[ 3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250],
[ 3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250],
[ 3.6250, 3.6250, 3.6250, ..., 3.6250, 3.6250, 3.6250]],
[[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750],
[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750],
[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750],
...,
[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750],
[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750],
[ 4.8750, 4.8750, 4.8750, ..., 4.8750, 4.8750, 4.8750]],
[[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562],
[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562],
[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562],
...,
[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562],
[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562],
[11.6562, 11.6562, 11.6562, ..., 11.6562, 11.6562, 11.6562]]]
第三个和第四个维度填充的是 3.6250 形成形同元素的 20*20 矩阵。
第二个维度填充的是anchor_w 下一个元素形成相同元素的 20*20 矩阵。
anchor_h的操作也是一样的
anchor_h = [[[[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125],
[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125],
[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125],
...,
[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125],
[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125],
[ 2.8125, 2.8125, 2.8125, ..., 2.8125, 2.8125, 2.8125]],
[[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875],
[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875],
[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875],
...,
[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875],
[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875],
[ 6.1875, 6.1875, 6.1875, ..., 6.1875, 6.1875, 6.1875]],
[[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875],
[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875],
[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875],
...,
[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875],
[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875],
[10.1875, 10.1875, 10.1875, ..., 10.1875, 10.1875, 10.1875]]]]
六、解码步骤三中的输出,得到新的x,y,w,h
将输出的 x y w h 进一步按照下面公式进行解码
# x 0 ~ 1 => 0 ~ 2 => -0.5 ~ 1.5 + grid_x
# y 0 ~ 1 => 0 ~ 2 => -0.5 ~ 1.5 + grid_y
# w 0 ~ 1 => 0 ~ 2 => 0 ~ 4 * anchor_w
# h 0 ~ 1 => 0 ~ 2 => 0 ~ 4 * anchor_h
x, y, w, h, grid_x, grid_y, anc