Batchnorm主要解决的问题:
covariate shift:
我们知道在做ml相关的项目时,由于训练数据和测试数据存在分布的差异性,需要对数据做归一化和白化,来提升模型的收敛速度和泛化性(训练时,数据归一化;测试时数据归一化)。Covariate ShiftShift 就是描述的训练预测输入数据分布不一致的现象,通过归一化,提升了模型的泛化能力,同时把数据缩放到一定的范围内可以提升模型的收敛速度。
Internal Covariate Shift:
Internal Covariate Shift 和Covariate Shift具有相似性,但并不是一个东西,前者发生在神经网络的内部,所以是Internal,后者发生在输入数据上。在深度神经网络中,数据经过一层层网络计算后,其数据分布也在发生着变化,此现象称为Internal Covariate Shift。那么怎么解决这个问题呢?如果单纯的每一层用归一化,神经网络又无法学习到数据的特征分布情况,于是这里加入了两个可以训练的参数gama缩放因子,beta偏置,这就是BatchNorm的实现了

之所以称之为batchnorm是因为所norm的数据是一个batch的,假设输入数据是β=x1…mβ=x1…m共m个数据,输出是yi=BN(x)yi=BN(x),batchnorm
batchnorm的步骤如下:
1.先求出此次批量数据x的均值
2.求出此次batch的方差
3.接下来就是对x做归一化
4.最重要的一步,引入缩放和平移变量(gama,beta) ,计算归一化后的值
(个人理解是将学习数据的分布转化为学习gama,beta两个变量,应该是这个样子吧)
这样就保证了每一次数据经过归一化后还保留的有学习来的特征,这样也就加速了模型的收敛速度,同时也能提升模型的泛化能力。
代码实现(转自知乎):
def batch_norm_layer(x, train_phase, scope_bn):
with tf.variable_scope(scope_bn):
# 新建两个变量,平移、缩放因子
beta = tf.Variable(tf.constant(0.0, shape=[x.shape[-1]]), name='beta', trainable=True)
gamma = tf.Variable(tf.constant(1.0, shape=[x.shape[-1]]), name='gamma', trainable=True)
# 计算此次批量的均值和方差
axises = np.arange(len(x.shape) - 1)
batch_mean, batch_var = tf.nn.moments(x, axises, name='moments')
# 滑动平均做衰减
ema = tf.train.ExponentialMovingAverage(decay=0.5)
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)
# train_phase 训练还是测试的flag
# 训练阶段计算runing_mean和runing_var,使用mean_var_with_update()函数
# 测试的时候直接把之前计算的拿去用 ema.average(batch_mean)
mean, var = tf.cond(train_phase, mean_var_with_update,
lambda: (ema.average(batch_mean), ema.average(batch_var)))
normed = tf.nn.batch_normalization(x, mean, var, beta, gamma, 1e-3)
return normed
至于此行代码tf.nn.batch_normalization()就是简单的计算batchnorm过程啦,代码如下:
这个函数所实现的功能就如此公式:gama(x-u)/theta + beta
def batch_normalization(x,
mean,
variance,
offset,
scale,
variance_epsilon,
name=None):
with ops.name_scope(name, "batchnorm", [x, mean, variance, scale, offset]):
inv = math_ops.rsqrt(variance + variance_epsilon)
if scale is not None:
inv *= scale
return x * inv + (offset - mean * inv
if offset is not None else -mean * inv)
参考:https://blog.youkuaiyun.com/qq_25737169/article/details/79048516
本文深入探讨BatchNorm解决的Covariate Shift与Internal Covariate Shift问题,解释BatchNorm如何通过引入可训练参数gama和beta加速模型收敛并提升泛化能力。文章详细介绍了BatchNorm的计算步骤,并提供了代码实现。
1094

被折叠的 条评论
为什么被折叠?



