tensorflow 系列 batch normalization

一、tf.nn.moments函数

def moments(x, axes, name=None, keep_dims=False)

  • x 输出的数据,形如 [batchsize, height, width, kernels]
  • axes 表示在哪个维度上求解,是个list,例如 [0, 1, 2]
  • name 就是个名字,不多解释
  • keep_dims 是否保持维度

输出:Two Tensor objects: mean andvariance.

  • mean 就是均值
  • variance 就是方差

例如:计算2×3维向量的mean和variance

img = tf.Variable(tf.random_normal([2, 3]))
axis = list(range(len(img.get_shape()) - 1))
mean, variance = tf.nn.moments(img, axis)
可能对于2×3这么大的矩阵,理解起来比较容易,但是对于 [128, 32, 32, 64] 这样的4维矩阵,理解就有点困难了

根据图示可能好理解些:




二、tf.nn.batch_normalization函数

def batch_normalization(x, mean, variance, offset, scale, variance_epsilon, name=None):

其中Xi对应x,μ即为mean,δ对应variance。第3个公式做初步的Norm,第4个公式中,γ即为scale,β对应offset。offset一般初始化为0,scale初始化为1,另外offset、scale的shape与mean相同,variance_epsilon这个参数设为一个很小的数就行,比如0.001。

BN在实际中,由于mean和variance是和batch内的数据有关的,因此需要注意训练过程和预测过程中,mean和variance无法使用相同的数据。需要一个trick,即moving_average,代码如下:

update_moving_mean = moving_averages.assign_moving_average(moving_mean, mean, BN_DECAY)
update_moving_variance = moving_averages.assign_moving_average(moving_variance, variance, BN_DECAY)
tf.add_to_collection(UPDATE_OPS_COLLECTION, update_moving_mean)
tf.add_to_collection(UPDATE_OPS_COLLECTION, update_moving_variance)
mean, variance = control_flow_ops.cond(['is_training'], lambda: (mean, variance), lambda: (moving_mean, moving_variance))
在训练的过程中,通过每个step得到的mean和variance,叠加计算对应的moving_average(滑动平均),并最终保存下来以便在inference的过程中使用。
对于assign_moving_average方法如下:
def assign_moving_average(variable, value, decay, zero_debias=True, name=None)
其实内部计算比较简单,公式表达如下:
variable = variable * decay + value * (1 - decay)
变换一下:
variable = variable - (1 - decay) * (variable - value)
减号后面的项就是moving_average的更新delta了。
关于BN的完整实现,在Ryan Dahl的repository里有,名字叫做 tensorflow-resnet ,可以自行查看



参考博文:http://blog.csdn.net/hjimce/article/details/50866313

                     https://www.jianshu.com/p/0312e04e4e83

猜你喜欢

转载自blog.csdn.net/m0_37598149/article/details/80982420
今日推荐