Batch Normalization 简单理解

1:背景

由于在训练神经网络的过程中,每一层的 params是不断更新的,由于params的更新会导致下一层输入的分布情况发生改变,所以这就要求我们进行权重初始化,减小学习率。这个现象就叫做internal covariate shift。

2:idea思想

虽然可以通过whitening来加速收敛,但是需要的计算资源会很大。

而Batch Normalizationn的思想则是对于每一组batch,在网络的每一层中,分feature对输入进行normalization,对各个feature分别normalization,即对网络中每一层的单个神经元输入,计算均值和方差后,再进行normalization。

对于CNN来说normalize “Wx+b”而非 “x”,也可以忽略掉b,即normalize “Wx”,而计算均值和方差的时候,是在feature map的基础上(原来是每一个feature)

3:算法流程(对network进行normalize)

算法一

这里写图片描述

算法二

这里写图片描述

4:代码(keras):

class BatchNormalization(Layer):
    '''
        Reference:
            Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
                http://arxiv.org/pdf/1502.03167v3.pdf
            mode: 0 -> featurewise normalization
                  1 -> samplewise normalization (may sometimes outperform featurewise mode)
            momentum: momentum term in the computation of a running estimate of the mean and std of the data
    '''
    def __init__(self, input_shape, epsilon=1e-6, mode=0, momentum=0.9, weights=None):
        super(BatchNormalization, self).__init__()
        self.init = initializations.get("uniform")
        self.input_shape = input_shape
        self.epsilon = epsilon
        self.mode = mode
        self.momentum = momentum
        self.input = ndim_tensor(len(self.input_shape) + 1)

        self.gamma = self.init((self.input_shape))
        self.beta = shared_zeros(self.input_shape)

        self.params = [self.gamma, self.beta]
        self.running_mean = shared_zeros(self.input_shape)
        self.running_std = shared_ones((self.input_shape))
        if weights is not None:
            self.set_weights(weights)

    def get_weights(self):
        return super(BatchNormalization, self).get_weights() + [self.running_mean.get_value(), self.running_std.get_value()]

    def set_weights(self, weights):
        self.running_mean.set_value(floatX(weights[-2]))
        self.running_std.set_value(floatX(weights[-1]))
        super(BatchNormalization, self).set_weights(weights[:-2])

    def init_updates(self):
        X = self.get_input(train=True)
        m = X.mean(axis=0)
        std = T.mean((X - m) ** 2 + self.epsilon, axis=0) ** 0.5
        mean_update = self.momentum * self.running_mean + (1-self.momentum) * m
        std_update = self.momentum * self.running_std + (1-self.momentum) * std
        self.updates = [(self.running_mean, mean_update), (self.running_std, std_update)]

    def get_output(self, train):
        X = self.get_input(train)

        if self.mode == 0:
            X_normed = (X - self.running_mean) / (self.running_std + self.epsilon)

        elif self.mode == 1:
            m = X.mean(axis=-1, keepdims=True)
            std = X.std(axis=-1, keepdims=True)
            X_normed = (X - m) / (std + self.epsilon)

        out = self.gamma * X_normed + self.beta
        return out

    def get_config(self):
        return {"name": self.__class__.__name__,
                "input_shape": self.input_shape,
                "epsilon": self.epsilon,
                "mode": self.mode}
  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Batch normalization是一种常用的神经网络正则化技术,它的主要思想是对每一层的输入进行归一化,使得网络中每一层的输入分布都具有相似的统计特性。Batch normalization可以在训练过程中减少内部协变量偏移(Internal Covariate Shift)现象的发生,有助于加速网络的训练,并提高网络的泛化能力。 内部协变量偏移是指在训练过程中,每一层的输入分布会发生改变,导致网络中每一层的参数都需要重新适应新的输入分布,从而影响了网络的收敛速度和泛化能力。Batch normalization通过对每一层的输入进行归一化,使得每一层的输入分布都具有相似的统计特性,从而减少了内部协变量偏移现象的发生。 具体来说,Batch normalization计算公式如下: $$ \hat{x}=\frac{x-\mu}{\sqrt{\sigma^2+\epsilon}} \\ y=\gamma\hat{x}+\beta $$ 其中,$x$是输入,$\mu$和$\sigma^2$是在batch计算得到的均值和方差,$\epsilon$是一个很小的常数,用于避免分母为0的情况,$\hat{x}$是将输入$x$进行归一化后的结果,$\gamma$和$\beta$是可学习的缩放和偏移参数。 Batch normalization的作用是将每一层的输入归一化到均值为0,方差为1的分布上,从而使得每一层的输入分布具有相似的统计特性,加速了网络的训练,并提高了网络的泛化能力。 总之,Batch normalization通过对每一层的输入进行归一化,减少了内部协变量偏移现象的发生,提高了网络的训练速度和泛化能力,是一种非常实用的神经网络正则化技术。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值