Batch Normalization的解釋


輸入的標准化處理是對圖片等輸入信息進行標准化處理,使得所有輸入的均值為0,方差為1

normalize = T.Normalize([0.485, 0.456, 0.406],[0.229, 0.224, 0.225])

 

而Batch Normalization的目的是使各隱藏層輸入的均值和方差為任意值

Batch Norm經常使用在mini-batch上,這也是其名稱的由來

Batch Normalization是對下面隱藏層進行激活函數操作前的輸入Z[l]進行標准層處理

Z^{[l]}=W^{[l]}A^{[l-1]}+b^{[l]}

進行的操作有:

1)對輸入進行歸一化操作

  • m是單個mini-batch包含樣本個數
  • \varepsilon 是為了防止分母為零,可取值 10^{-8}

\mu=\frac1m\sum_iz^{(i)}

\sigma^2=\frac1m\sum_i(z_i-\mu)^2

z^{(i)}_{norm}=\frac{z^{(i)}-\mu}{\sqrt{\sigma^2+\varepsilon}}

 此時的輸入Z[i]變為了均值為0,方差為1的Znorm[i]

 

2)對歸一化的結果進行縮放和平移

但是大部分情況下我們其實並不希望輸入均值為0,方差為1,而是希望其根據訓練的需要而設置為任意值

這個時候就需要進一步處理:

\tilde z^{(i)}=\gamma\cdot z^{(i)}_{norm}+\beta

\gamma 和 \beta 是可以學習的參數,類似於W和b一樣,可以通過梯度下降等算法求得

當兩者的值為\gamma=\sqrt{\sigma^2+\varepsilon},\ \ \beta=u,那么\tilde z^{(i)}=z^{(i)},實現恆等映射

為什么需要進行這一步的處理:

從激活函數的角度來說,如果各隱藏層的輸入均值在靠近0的區域即處於激活函數的線性區域,這樣不利於訓練好的非線性神經網絡,得到的模型效果也不會太好

 

如resnet網絡中的使用:

#這個實現的是兩層的殘差塊,用於resnet18/34
class BasicBlock(nn.Module):
    expansion = 1

    def __init__(self, inplanes, planes, stride=1, downsample=None):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(inplanes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.relu = nn.ReLU(inplace=True)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.downsample = downsample
        self.stride = stride

    def forward(self, x):
        identity = x

        out = self.conv1(x)
        out = self.bn1(out)
        out = self.relu(out)

        out = self.conv2(out)
        out = self.bn2(out)

        if self.downsample is not None: #當連接的維度不同時,使用1*1的卷積核將低維轉成高維,然后才能進行相加
            identity = self.downsample(x)

        out += identity
        out = self.relu(out)

        return out

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM