参考: http://blog.csdn.net/u012162613/article/details/44261657
https://blog.csdn.net/chaowang1994/article/details/80388990
目录:
(2) L1, L2在TensorFlow中是如何体现的呢?
1. 过拟合
在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。随着训练过程,网络在training data上的error渐渐减小,但是在验证集上的error却反而渐渐增大——因为训练出来的网络过拟合了训练集,对训练集外的数据却不work。
在机器学习算法中,我们常常将原始数据集分为三部分:training data、validation data,testing data。
这个validation data是什么?它其实就是用 来避免过拟合的,在训练过程中,我们通常用它来确定一些超参数(比如根据validation data上的accuracy来确定early stopping的epoch大小、根据 validation data确定learning rate等等)。那为啥不直接在testing data上做这些呢?因为如果在testing data做这些,那么随着训练的进行,我们的网络实际上就是在一点一点地overfitting我们的testing data,导致最后得到的testing accuracy没有任何参考意义。因此,training data的作用是计算梯度更新权重,validation data如上所述,testing data则给出一个accuracy以判断网络的好坏。
避免过拟合的方法有很多:early stopping、数据集扩增(Data augmentation)、正则化(Regularization)包括L1、L2(L2 regularization也叫weight decay),dropout。
2. 正则化
(1)L1和L2是什么
L1 和 L2 的区别在于: L2 是 weights平方和, 而 L1 仅仅是weights绝对值的和.(注意是针对weights, 不包含bias)
(2) L1, L2在TensorFlow中是如何体现的呢?
下面的代码把所有可以训练的参数都进行“惩罚”:
vars = tf.trainable_variables()
lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in vars ]) * 0.001
但一般来说,我们都是对权重进行惩罚,(Stack Overflow上对于L2惩罚项的讨论:TensorFlow - regularization with L2 loss, how to apply to all weights, not just last one?)因此改为:
lossL2 = tf.add_n([ tf.nn.l2_loss(v) for v in vars
if 'bias' not in v.name ]) * 0.001
最后再加到loss项里:
方法一:
loss = (tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(
logits=out_layer, labels=tf_train_labels)) +
0.001*lossL2)
L1 loss 同理,只要把tf.nn.l2_loss() 改为 tf.nn.l1_loss(v) 即可。
方法二:
S = tf.get_variable(name='S',regularizer=tf.contrib.layers.l2_regularizer )
reg_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES)
reg_constant = 0.01 # Choose an appropriate one.
loss = my_normal_loss + reg_constant * sum(reg_losses)
参考链接:https://greydanus.github.io/2016/09/05/regularization/
https://stackoverflow.com/questions/37107223/how-to-add-regularizations-in-tensorflow#