SSD網絡中的L2標準化

  • L1標準化:每個元素/L1範數
  • L2標準化:每個元素/L2範數

SSD網絡中的L2標準化

VGG16的conv4_3特徵圖的大小爲38*38,網絡層靠前,方差比較大,需要加一個L2標準化,以保證和後面的檢測層差異不是很大。L2標準化的公式如下:

                                                                                                    \hat{x}=\frac{x}{\left \| x \right \|^{2}}

其中xconv4_3特徵圖數據,x=\left ( x_{1} ...x_{d}\right )。   \left \| x \right \|^{2}爲x的L2範數,\left \| x \right \|^{2}=\left ( \sum_{i=1}^{d}\left | x_{i} \right |^{2} \right )^{\frac{1}{2}}

同時,這裏還要注意的是如果簡單的對一個層的輸入進行L2標準化就會改變該層的規模,並且會減慢學習速度,因此這裏引入了一個縮放係數\gamma _{i} ,對於每一個通道l2標準化後的結果爲: y_{i}=\gamma _{i}\hat{x_{i}},通常\gamma _{i}的值設10或者20,效果比較好。

代碼如下所示:(代碼摘自https://github.com/amdegroot/ssd.pytorch/

import torch
import torch.nn as nn
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
        #將一個不可訓練的類型Tensor轉換成可以訓練的類型parameter
        self.weight = nn.Parameter(torch.Tensor(self.n_channels))
        self.reset_parameters()

    def reset_parameters(self):
        init.constant_(self.weight,self.gamma) #用值填充向量,即給weight賦值

    def forward(self, x):
        #計算x的L2範數,暫時不知道self.eps參數的意義
        norm = x.pow(2).sum(dim=1, keepdim=True).sqrt()+self.eps
        #x /= norm
        x = torch.div(x,norm)
        #乘以縮放係數
        out = self.weight.unsqueeze(0).unsqueeze(2).unsqueeze(3).expand_as(x) * x
        return out

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章