一、正则化
正则化原理这里就不介绍了,网上资源有很多,详情可以点击这里(https://zhuanlan.zhihu.com/p/29297934)
但是网上大多数关于正则化的教程太乱,而且有很多代码 不能试用。这里说一个可以用的:
首先在权值初始话的时候,对权值进行正则化计算,利用函数:
tf.contrib.layers.l1_regularizer(lambda1)(w)
或 tf.contrib.layers.l2_regularizer(lambda1)(w)
分别是 l1 正则化和 l2 正则化,其实际效果如:
weights = tf.constant([[1., -2.], [-3., 4.]])
with tf.Session() as sess:
print(sess.run(tf.contrib.layers.l1_regularizer(.5)(weights)))
# (1+2+3+4)*.5 ⇒ 5
print(sess.run(tf.contrib.layers.l2_regularizer(.5)(weights)))
# (1+4+9+16)*.5*.5 ⇒ 7.5
对于正则化的权重,我们利用tf.add_to_collection()存到一个自定义的集合中,如:
w=tf.get_variable(name,shape,initializer=tf.truncated_normal_initializer(stddev=stddev))
tf.add_to_collection("regular_loss",tf.contrib.layers.l2_regularizer(lambda)(w))
其中lambda是惩罚程度,具体只可以自己设定,w的是被正则化的一组权重。regular_loss是正则化权值被存储的位置。当很多组权重被正则化存储到regular_loss中后,我们利用tf.get_collection()函数将这些值提取出来,根据正则化公式,利用tf.add_n()对其求和,即:
regular_loss = tf.add_n(tf.get_collection("regular_loss"))
最后将regular_loss与真正的loss想加,送进优化啊器即可。:
伪代码如下:
x = 1
w = tf.get_variable('w',[1],initializer=tf.truncated_normal_initializer(stddev=0.2))
tf.add_to_collection("regular_loss",tf.contrib.layers.l2_regularizer(0.001)(w))
y = w*x
rel_loss = 1/2*(y-label)^2
regular_loss = tf.add_n(tf.get_collection("regular_loss"))
loss = regular_loss + rel_loss
opt = tf.GradientDescentOptimizer(learning_rate).minimize(Loss)
1.1 其他几种正则化方式
- 第一种
在使用tf.get_variable()和tf.variable_scope()的时候,你会发现,它们俩中有regularizer形参.如果传入这个参数的话,那么variable_scope内的weights的正则化损失,会被添加到GraphKeys.REGULARIZATION_LOSSES中.如:
weight = tf.get_variable('weight', shape=[8], initializer=tf.ones_initializer(),regularizer=tf.contrib.layers.l2_regularizer(.5))
reg_ws = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
loss = rel_loss + tf.reduce_sum(reg_ws)
- 第二种
var_lists = tf.trainable_variables()
或者 var_lists = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'name')
reg_ws = tf.contrib.layers.apply_regularization(tf.contrib.layers.l2_regularizer(0.5), var_lists)
loss = rel_loss + reg_ws
个人认为第三种方式最简单,读者可以自行体会
二、Batch Normalization注意事项
tensorflow中使用Batch Normalization层教程很多,参考可见(http://www.jianshu.com/p/0312e04e4e83),
BN层的代码如下:
conv_bn = tf.contrib.layers.batch_norm(conv, momentum, scale=True, epsilon=1e-5,is_training = self.training, scope=names)
scale是指系数λ。
实际在搭建好包含BN层的网络之后,进行训练时需要注意使用如下模式代码:
rmsprop = tf.train.RMSPropOptimizer(learning_rate= self.lr)
with tf.control_dependencies(self.update_ops):
self.train_rmsprop = rmsprop.minimize(loss)
其中 with tf.control_dependencies(self.update_ops): 是保证在训练的时候,先将滑动计算的均值和方差更新之后,再进行梯度计算并优化,防止使用了初始化的权值和方差。