tf.layers.batch_normalization 中“可训练”和“训练”标志的意义
Posted
技术标签:
【中文标题】tf.layers.batch_normalization 中“可训练”和“训练”标志的意义【英文标题】:significance of "trainable" and "training" flag in tf.layers.batch_normalization 【发布时间】:2018-10-16 23:18:09 【问题描述】:tf.layers.batch_normalization 中“trainable”和“training”标志的意义是什么?这两者在训练和预测过程中有何不同?
【问题讨论】:
【参考方案1】:批量规范有两个阶段:
1. Training:
- Normalize layer activations using `moving_avg`, `moving_var`, `beta` and `gamma`
(`training`* should be `True`.)
- update the `moving_avg` and `moving_var` statistics.
(`trainable` should be `True`)
2. Inference:
- Normalize layer activations using `beta` and `gamma`.
(`training` should be `False`)
用于说明少数情况的示例代码:
#random image
img = np.random.randint(0,10,(2,2,4)).astype(np.float32)
# batch norm params initialized
beta = np.ones((4)).astype(np.float32)*1 # all ones
gamma = np.ones((4)).astype(np.float32)*2 # all twos
moving_mean = np.zeros((4)).astype(np.float32) # all zeros
moving_var = np.ones((4)).astype(np.float32) # all ones
#Placeholders for input image
_input = tf.placeholder(tf.float32, shape=(1,2,2,4), name='input')
#batch Norm
out = tf.layers.batch_normalization(
_input,
beta_initializer=tf.constant_initializer(beta),
gamma_initializer=tf.constant_initializer(gamma),
moving_mean_initializer=tf.constant_initializer(moving_mean),
moving_variance_initializer=tf.constant_initializer(moving_var),
training=False, trainable=False)
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
init_op = tf.global_variables_initializer()
## 2. Run the graph in a session
with tf.Session() as sess:
# init the variables
sess.run(init_op)
for i in range(2):
ops, o = sess.run([update_ops, out], feed_dict=_input: np.expand_dims(img, 0))
print('beta', sess.run('batch_normalization/beta:0'))
print('gamma', sess.run('batch_normalization/gamma:0'))
print('moving_avg',sess.run('batch_normalization/moving_mean:0'))
print('moving_variance',sess.run('batch_normalization/moving_variance:0'))
print('out', np.round(o))
print('')
当training=False
和trainable=False
:
img = [[[4., 5., 9., 0.]...
out = [[ 9. 11. 19. 1.]...
The activation is scaled/shifted using gamma and beta.
当training=True
和trainable=False
:
out = [[ 2. 2. 3. -1.] ...
The activation is normalized using `moving_avg`, `moving_var`, `gamma` and `beta`.
The averages are not updated.
当traning=True
和trainable=True
:
The out is same as above, but the `moving_avg` and `moving_var` gets updated to new values.
moving_avg [0.03249997 0.03499997 0.06499994 0.02749997]
moving_variance [1.0791667 1.1266665 1.0999999 1.0925]
【讨论】:
谢谢@vijay m 在推理过程中,不应该使用从训练中“学习”的移动平均值和方差对激活进行归一化吗?【参考方案2】:这很复杂。 而在 TF 2.0 中,行为发生了变化,请参见:
https://github.com/tensorflow/tensorflow/blob/095272a4dd259e8acd3bc18e9eb5225e7a4d7476/tensorflow/python/keras/layers/normalization_v2.py#L26
关于在
BatchNormalization
层上设置layer.trainable = False
:设置
layer.trainable = False
的意思是冻结 层,即其内部状态在训练期间不会改变: 在fit()
期间不会更新其可训练权重或train_on_batch()
,其状态更新将不会运行。通常, 这并不一定意味着该层在推理中运行 模式(通常由training
参数控制,该参数可以 调用层时传递)。 “冻结状态”和“推理模式” 是两个独立的概念。但是,对于
此行为仅从 TensorFlow 2.0 开始出现。在 1.* 中,设置BatchNormalization
图层,在图层上设置trainable = False
表示该图层将 随后以推理模式运行(这意味着它将使用 移动均值和移动方差以标准化当前批次, 而不是使用当前批次的均值和方差)。这 TensorFlow 2.0 中引入了行为,以启用layer.trainable = False
产生最普遍的预期 convnet 微调用例中的行为。请注意:layer.trainable = False
会冻结图层但不会 将其切换到推理模式。 在包含其他层的模型上设置trainable
将递归设置所有内层的trainable
值。 如果在模型上调用compile()
后更改了trainable
属性的值,则新的值不会对此生效 模型直到再次调用compile()
。
【讨论】:
【参考方案3】:training
控制是使用训练模式batchnorm(使用来自该小批量的统计数据)还是推理模式batchnorm(使用训练数据的平均统计数据)。 trainable
控制在 batchnorm 过程中创建的变量本身是否可训练。
【讨论】:
以上是关于tf.layers.batch_normalization 中“可训练”和“训练”标志的意义的主要内容,如果未能解决你的问题,请参考以下文章