SSD目标检测:conv4_3特征的L2Norm处理

 

正则化方式的选择:

       原生态SSD中,特征金字塔不同特征层上的特征值,有不同的尺度范围(different ranges of value),SSD采取的做法为:使用L2-Normal正则化conv4_3;FSSD使用方案更简单有效:将concate后的特征,后接一个BN层,从row2、6对比可知,新增BN层可以带来0.5%的性能提升。

(1)L2 Normalization公式及作用:

对于一行向量,其L2归一化公式入下所示,其中D为向量长度:

在深度神经网络中,偶尔会出现多个量纲不同的向量拼接在一起的情况,此时就可以使用L2归一化统一拼接后的向量的量纲,使得网络能够快速收敛。

(2)mmdetection中的vgg-ssd.py中处理方式:

class L2Norm(nn.Module):

    def __init__(self, n_dims, scale=20., eps=1e-10):
        super(L2Norm, self).__init__()
        self.n_dims = n_dims
        self.weight = nn.Parameter(torch.Tensor(self.n_dims))
        self.eps = eps
        self.scale = scale

    def forward(self, x):
        # normalization layer convert to FP32 in FP16 training
        x_float = x.float()
        norm = x_float.pow(2).sum(1, keepdim=True).sqrt() + self.eps
        return (self.weight[None, :, None, None].float().expand_as(x_float) *
                x_float / norm).type_as(x)

       转换为onnx->ncnn时,ncnn执行这一层的处理会出错,因为在ncnn中虽然支持Operation_POW处理,但是在此处保存的blobs数据只有一个,Operation_POW输入需要传入两个blobs。

若要满足ncnn的处理,需要将自定义的norm处理改为pytorch的算子,这样转换成ncnn就不会报错了:

class L2Norm(nn.Module):

    def __init__(self, n_dims, scale=20., eps=1e-10):
        super(L2Norm, self).__init__()
        self.n_dims = n_dims
        self.weight = nn.Parameter(torch.Tensor(self.n_dims))
        self.eps = eps
        self.scale = scale
        init.constant(self.weight, self.scale)

    def forward(self, x):
        norm = x.norm(p=2, dim=1, keepdim=True) + self.eps
        x = torch.div(x,norm)
        out = self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3).expand_as(x) * x
        return out

延伸阅读参考:https://blog.csdn.net/flyfish1986/article/details/105586716

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值