tensorflow_tutorials_libs.batch_norm

  • 批标准化(batch normalization,BN)一般用在激活函数之前,使结果x=Wx+bx各个维度均值为0,方差为1。通过规范化让激活函数分布在线性区间,让每一层的输入有一个稳定的分布会有利于网络的训练。

    优点:
    1.加大探索步长,加快收敛速度。
    2.更容易跳出局部极小。
    3.破坏原来的数据分布,一定程度上防止过拟合。
    4.解决收敛速度慢和梯度爆炸。
    在这里插入图片描述

  • affine:仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次,线性变换并接上一个平移,变换为另一个向量空间。

  • mean, variance = tf.nn.moments(x, axes, name=None, keep_dims=False)
    计算统计矩,输出两个张量,mean 是一阶矩即均值,variance 则是二阶中心矩即方差,axes表示在哪个维度上求解,是个list。
    在这里插入图片描述

  • 在采用随机梯度下降算法训练神经网络时,使用 tf.train.ExponentialMovingAverage 滑动平均操作的意义在于提高模型在测试数据上的健壮性(robustness)。
    参考:Tensorflow深度学习之九:滑动平均模型

  • tf.control_dependencies(control_inputs),此函数指定某些操作执行的依赖关系。返回一个控制依赖的上下文管理器,使用 with 关键字可以让在这个上下文环境中的操作都在 control_inputs 执行

    with tf.control_dependencies([a, b]):
        c = ....
        d = ...
    

    在执行完 a,b 操作之后,才能执行 c,d 操作。意思就是 c,d 操作依赖 a,b 操作

  • y = tf.identity(x)是一个op操作表示将x的值赋予y,

  • y = x只是一个内存拷贝,并不是一个op,而control_dependencies只有当里面是一个Op的时候才能起作用。

  • tf.cond,如果断言 pred 为 true 则返回 true_fn() ,否则返回 false_fn().(弃用参数)

    cond (pred , 
    	  true_fn = None , 
    	  false_fn = None , 
    	  strict = False , 
    	  name = None ,
    	  fn1 = None , 
    	  fn2 = None)
    
"""Batch Normalization for TensorFlow.
Parag K. Mital, Jan 2016.
"""

import tensorflow as tf

def batch_norm(x, phase_train, scope='bn', affine=True):
    """
    Batch normalization on convolutional maps.

    from: https://stackoverflow.com/questions/33949786/how-could-i-
    use-batch-normalization-in-tensorflow

    Only modified to infer shape from input tensor x.

    Parameters
    ----------
    x
        Tensor, 4D BHWD input maps
    phase_train
        boolean tf.Variable, true indicates training phase:is_training
    scope
        string, variable scope
    affine
        whether to affine-transform outputs

    Return
    ------
    normed
        batch-normalized maps
    """
    with tf.variable_scope(scope):
    
        shape = x.get_shape().as_list()

        beta = tf.Variable(tf.constant(0.0, shape=[shape[-1]]),
                           name='beta', trainable=True)
        gamma = tf.Variable(tf.constant(1.0, shape=[shape[-1]]),
                            name='gamma', trainable=affine)
		
		# 定义待更新变量列表
        batch_mean, batch_var = tf.nn.moments(x, [0, 1, 2], name='moments')
      	
      	# 定义滑动平均模型的类
        ema = tf.train.ExponentialMovingAverage(decay=0.9)

        def mean_var_with_update():
            """Summary

            Returns
            -------
            name : TYPE
                Description
            """
            # 使用滑动平均模型
            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(phase_train,
                            mean_var_with_update,
                            lambda: (ema.average(batch_mean), ema.average(batch_var))
                            )
        normed = tf.nn.batch_norm_with_global_normalization(
            x, mean, var, beta, gamma, 1e-3, affine)
            
    return normed

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章