目标检测 SSD: Single Shot MultiBox Detector - L2Norm模块处理conv4_3的特征输出

目标检测 SSD: Single Shot MultiBox Detector - L2Norm模块处理conv4_3的特征输出

conv4_3特征输出之前需要经过L2Norm模块
conv4_3的特征和后面几层feature map的数值大小不匹配,归一化之后数值大小统计,取值范围相同,有利于模型收敛

方式1

import torch
import torch.nn as nn
from torch.autograd import Function
from torch.autograd import Variable
import torch.nn.init as init

class L2Norm(nn.Module):
    def __init__(self,n_channels, scale):
        super(L2Norm,self).__init__()
        self.n_channels = n_channels
        self.gamma = scale or None
        self.eps = 1e-10
        self.weight = nn.Parameter(torch.Tensor(self.n_channels))
        self.reset_parameters()

    def reset_parameters(self):
        init.constant_(self.weight,self.gamma)

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

方式2

import torch
import torch.nn.init as init
import torch.nn as nn
import torch.nn.functional as F

class L2NormScale(nn.Module):
    def __init__(self, n_channels, init_scale):
        super(L2NormScale, self).__init__()
        self.n_channels = n_channels
        self.init_scale = init_scale
        self.weight = nn.Parameter(torch.Tensor(self.n_channels))
        init.constant(self.weight, self.init_scale)

    def forward(self, x):
        x = F.normalize(x, dim=1)
        x = self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3).expand_as(x) * x
        return x

PyTorch封装好的函数

torch.nn.functional.normalize(input, p=2, dim=1, eps=1e-12, out=None)
对指定维度执行 规范化

对于默认参数, 它使用沿维度的Euclidean范数进行标准化.
v = v max ⁡ ( ∥ v ∥ p , ϵ ) v=\frac{v}{\max \left(\|v\|_{p}, \epsilon\right)} v=max(vp,ϵ)v
参数:
input – 任意形状的输入张量
p (float) – 范数公式中的指数值. 默认值: 等于2就是2范数
dim (int) – 进行规约的维度. 默认值: 1,一般是通道维度
eps (float) – 避免除以零的小值. 默认值: 1e-12
out (Tensor, 可选的) – 输出张量. 如果 out 被设置, 此操作不可微分.

不封装直接写的方式

norm = conv4_3_feats.pow(2).sum(dim=1, keepdim=True).sqrt()+1e-10  # (N, 1, 38, 38)
conv4_3_feats = conv4_3_feats / norm  # (N, 512, 38, 38)
conv4_3_feats = conv4_3_feats * self.rescale_factors  # (N, 512, 38, 38)

mmdetection 里的实现

 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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西笑生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值