dropout、Batch Normalaztion训练和预测时候是一样的吗

本文讨论了Dropout在神经网络中的作用,以及它与批量归一化(BN)的结合可能带来的问题。同时,解释了为何在某些场景下如RNN和Transformer中,会选择使用LayerNorm而非BN。
摘要由CSDN通过智能技术生成

1、Dropout

Dropout ,在训练时以一定的概率使神经元失活,实际上就是让对应神经元的输出为0

假设失活概率为 p ,就是这一层中的每个神经元都有p的概率失活,如下图的三层网络结构中,如果失活概率为0.5,则平均每一次训练有3个神经元失活,所以输出层每个神经元只有3个输入,而实际测试时是不会有dropout的,输出层每个神经元都有6个输入,这样在训练和测试时,

原因:输出层每个神经元的输入和的期望会有量级上的差异。

因此在训练时还要对第二层的输出数据除以(1-p)之后再传给输出层神经元,作为神经元失活的补偿,以使得在训练时和测试时每一层输入有大致相同的期望。

2、BN和Dropout共同使用时会出现的问题

BN和Dropout单独使用都能减少过拟合并加速训练速度,但如果一起使用的话并不会产生1+1>2的效果,相反可能会得到比单独使用更差的效果。

Dropout在训练时会随机丢弃一些神经元,这样会导致输出的结果变小。而预测时往往关闭dropout,保证预测结果的一致性(不关闭dropout可能同一个输入会得到不同的输出,不过输出会服从某一分布。

另外有些情况下可以不关闭dropout,比如文本生成下,不关闭会增大输出的多样性)

为了对齐Dropout训练和预测的结果,通常有两种做法,假设dropout rate = 0.2。一种是训练时不做处理,预测时输出乘以(1 - dropout rate)。另一种是训练时留下的神经元除以(1 - dropout rate)

3、BatchNorm是对一个batch-size样本内的每个特征做归一化,LayerNorm是对每个样本的所有特征做归一化。

def bn_layer(self, inputs, training, name='bn', moving_decay=0.9, eps=1e-5):
        # 获取输入维度并判断是否匹配卷积层(4)或者全连接层(2)
        shape = inputs.shape
        param_shape = shape[-1]
        with tf.variable_scope(name):
            # 声明BN中唯一需要学习的两个参数,y=gamma*x+beta
            gamma = tf.get_variable('gamma', param_shape, initializer=tf.constant_initializer(1))
            beta  = tf.get_variable('beat', param_shape, initializer=tf.constant_initializer(0))

            # 计算当前整个batch的均值与方差
            axes = list(range(len(shape)-1))
            batch_mean, batch_var = tf.nn.moments(inputs , axes, name='moments')

            # 采用滑动平均更新均值与方差
            ema = tf.train.ExponentialMovingAverage(moving_decay, name="ema")

            def mean_var_with_update():
                ema_apply_op = ema.apply([batch_mean, batch_var])
                with tf.control_dependencies([ema_apply_op]):           
                    return tf.identity(batch_mean), tf.identity(batch_var)

            # 训练时,更新均值与方差,测试时使用之前最后一次保存的均值与方差
            mean, var = tf.cond(tf.equal(training,True), mean_var_with_update,
                    lambda:(ema.average(batch_mean), ema.average(batch_var)))

            # 最后执行batch normalization
            return tf.nn.batch_normalization(inputs ,mean, var, beta, gamma, eps)

使用场景上

在BN和LN都能使用的场景中,BN的效果一般优于LN,原因是基于不同数据,同一特征得到的归一化特征更不容易损失信息。但是有些场景是不能使用BN的,例如batch size较小或者序列问题中可以使用LN。这也就解答了RNN 或Transformer为什么用Layer Normalization?

首先RNN或Transformer解决的是序列问题,一个存在的问题是不同样本的序列长度不一致,而Batch Normalization需要对不同样本的同一位置特征进行标准化处理,所以无法应用;当然,输入的序列都要做padding补齐操作,但是补齐的位置填充的都是0,这些位置都是无意义的,此时的标准化也就没有意义了。

其次上面说到,BN抹杀了不同特征之间的大小关系;LN是保留了一个样本内不同特征之间的大小关系,这对NLP任务是至关重要的。对于NLP或者序列任务来说,一条样本的不同特征,其实就是时序上的变化,这正是需要学习的东西自然不能做归一化抹杀,所以要用LN。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ai君臣

学会的就要教给人

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

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

打赏作者

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

抵扣说明:

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

余额充值