论文
https://arxiv.org/pdf/2301.06719
https://github.com/yh-pengtu/FemtoDet
超轻量级检测模型,非常适合cpu推理
IBE
主干使用一种IBE模块堆叠,提升模糊物体边界导致的错误检测问题,是对深度可分离卷积的一种改进,下面的图像中最右边图像是有IBE的效果
IBE(ncnn格式)结构:
其中右分支的1×1卷积是将w、h做层融合达到稀疏化,
# 两次sum代表对两个kernel_size求和
# 变成[C_out, C_in, kernel_size, kernel_size]-》[C_out, C_in, kernel_size]-》[C_out, C_in]
# 混合通道可以评估重要性,并且
kernel_diff = self.conv.weight.sum(2).sum(2)
# 手工构建1x1卷积
kernel_diff = kernel_diff[:, :, None, None]
memorydata是一个theta调节系数,作用于这个1×1卷积上;parameter保证训练时该参数会被不断更新
self.theta = Parameter(torch.zeros([1]))
将融合层1×1卷积的输出与原始卷积融合,并通过两个batchnorm再次融合:
out_diff = F.conv2d(input=x, weight=kernel_diff, stride=self.conv.stride, padding=0, groups=self.conv.groups)
theta = F.sigmoid(self.theta)#[None, :, None, None]
# outs = self.att(out_normal, out_normal - theta * out_diff)
# 将普通卷积和1x1稀疏卷积融合,1x1
outs = self.bn(out_normal) + self.bn2(out_normal - theta * out_diff)
以上代码出自femtodet的ibeconv.py
这里我的模型为了提升性能使用的是SILU,原本是ReLU
检测头
如下图所示检测头叫sharedneck,顾名思义相较于其他金字塔结构对三个层级通道直接fusion输出,三个通道共享一个头,以此达到性能与能耗的平衡
能量损耗
文章很少见的讨论了工程领域模块功耗的实验,对于边缘设备续航与发热控制很有参考价值
最终在上述所有模块选择最低能耗设计,得到了显著优于其他同尺寸模型的femtodet
使用总结
因为模型尺寸很小(默认的widen_factor=0.25不到70k)相对yolo对数据的尺寸适应是比较差的,但是比MobileNet要好一点,建议按照一定范围内resize,并且如果对精度有要求适当的减少一些数据增强预处理更好;非常推荐在有续航要求的设备上尝试下