TF-Batch Normalization的实际用法

Batch Normalization的好处我就不多说了,详细可看论文,其实老早之前就看过论文了,但无奈拖延症(加上使用Keras),所以对BN的代码具体实现(train和test阶段)不是很懂,所以在此记个笔记~~~~~~~~~~
简要说下:训练完成后的均值方差还只是最后一个batch的均值方差,所以测试的时候我们用训练时所有批次均值方差的滑动平均来作为测试的均值方差,区别就这些,实际操作还是看下面举例吧
参考代码:

https://github.com/soloice/mnist-bn(作者用的是TF-Slim)

optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.1)
train_step = slim.learning.create_train_op(cross_entropy, optimizer, global_step=step)

###########################################################
# The list of values in the collection with the given name, or an empty list if 
# no value has been added to that collection. The list contains the values in 
# the order under which they were collected.
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)

# 关键操作
# 我们要一次进行多个操作(训练节点和参数滑动平均更新),只不过滑动平均已经封
# 装好了,一次进行多个操作就会用到tf.control_dependencies和tf.group两种机制
# 来产生操作依赖关系(详情见我的另一篇笔记)
# 我试了以下三种形式,都可以使用
if update_ops:
    updates = tf.group(*update_ops)
    cross_entropy = control_flow_ops.with_dependencies([updates], cross_entropy)

if update_ops:
    updates = tf.group(*update_ops)
    cross_entropy = control_flow_ops.with_dependencies([updates], train_step)

with tf.control_dependencies([tf.group(*update_ops)]):
    train_step = slim.learning.create_train_op(cross_entropy, optimizer, global_step=step)

tf.nn.batch_normalization()的用法,这个api是封装级别比较低的一个

def bacthnorm(inputs, scope, epsilon=1e-05, momentum=0.99, is_training=True):
    inputs_shape = inputs.get_shape().as_list()
    params_shape = inputs_shape[-1:]
    axis = list(range(len(inputs_shape) - 1))

    with tf.variable_scope(scope):
        beta = create_bn_var("beta", params_shape,
                               initializer=tf.zeros_initializer())
        gamma = create_bn_var("gamma", params_shape,
                                initializer=tf.ones_initializer())
        # for inference
        moving_mean = create_bn_var("moving_mean", params_shape,
                            initializer=tf.zeros_initializer(), trainable=False)
        moving_variance = create_bn_var("moving_variance", params_shape,
                            initializer=tf.ones_initializer(), trainable=False)
    if is_training:
        mean, variance = tf.nn.moments(inputs, axes=axis)
        update_move_mean = moving_averages.assign_moving_average(moving_mean,
                                                mean, decay=momentum)
        update_move_variance = moving_averages.assign_moving_average(moving_variance,
                                                variance, decay=momentum)
        tf.add_to_collection("_update_ops_", update_move_mean)
        tf.add_to_collection("_update_ops_", update_move_variance)
    else:
        mean, variance = moving_mean, moving_variance
    return tf.nn.batch_normalization(inputs, mean, variance, beta, gamma, epsilon)

我已实验过,也是基于mnist的,传送门

tf.layers.batch_normalization()也是一个封装级别比较高的API

# 举例,来自官网
x_norm = tf.layers.batch_normalization(x, training=training)

# ...

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
    train_op = optimizer.minimize(loss)

一般来说,这三个就够用了~~~~~~~~~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值