深度学习之正则化系列(1):深入理解参数范数惩罚(L1正则化、L2正则化)原理及tensorflow实现

1、背景简介

说起正则化,那为什么我们训练的模型或者是神经网络需要正则化呢?

它的主要作用在于: 提高泛化能力,防止过拟合


举个例子:上学期间广义分为三种人(仅仅说学习成绩):
学渣:根本就没学懂,书中的题目不会,考试卷也不会(欠拟合)
书呆子:就会课本上的,所有题目都会做,但是考试就是成绩低(过拟合)
学霸: 书中的会,考试照样考100,是不是可怕?


懂了吧,机器学习和人一样,目标就是向第三种一样,就是说我不仅要在训练集上表现的优异,最重要的是在测试集上表现好(平时差点也行,考试100也是不错的)。但是前两种,就是要不没有从数据中学到内容,要不就是测试集上表现的太差!那常用的正则化方法有哪些呢?

2、常见正则化方法

  • 参数范数惩罚
  • 作为约束的范数惩罚
  • 数据集增强
  • 提前终止
  • Dropout

先从参数范数惩罚开始,回想一下,在线性回归等问题中,我们定义了损失函数

J ( θ X y ) = 1 2 i = 1 n ( y y ) 2

注:这里的 θ 是指所有的参数,包括权重 w
我们发现,这样学习的模型虽然在测试集上比较好,但是泛化能力一般,于是就有了参数惩罚的思路,直接给 J ( ) 后面加个惩罚项(拖住学习的节奏),也就是正则化项,损失函数变成了:
J ( θ X y ) = 1 2 i = 1 n ( y y ) 2 + α Ω ( θ )

其中 α [ 0 , ) 是惩罚系数,那么这个惩罚项 Ω ( θ ) 是什么呢?在神经网络中又是怎样使用呢?


在神经网络中,参数包括每一层仿射变换的权重和偏置,我们通常只对权重做惩罚而不对偏置做正则惩罚。精确拟合偏置所需的数据通常比拟合权重少得多,且每个权重会指定两个变量如何相互作用。我们需要在各种条件下观察这两个变量才能良好地拟合权重。而每个偏置仅控制一个单变量。这意味着,我们不对其进行正则化也不会导致太大的方差。另外,正则化偏置参数可能会导致明显的欠拟合。因此,我们使用向量 w 表示所有应受范数惩罚影响的权重,而向量 θ 表示所有参数 (包括 w 和无需正则化的参数)。

在神经网络的情况下,有时希望对网络的每一层使用单独的惩罚,并分配不同 的 α 系数。寻找合适的多个超参数的代价很大,因此为了减少搜索空间,我们会在所有层使用相同的权重衰减(L2正则化)。

3、L2正则化

说起L2正则化,它指权值向量w中各个元素的平方和然后再求平方根(可以看到Ridge回归的L2正则化项有平方符号),通常表示为 w 2 , 数学表示为:

Ω ( θ ) = 1 2 w 2 2 = 1 2 i = 1 n w i 2

其目的是使权重更加接近原点1。在其他学术圈, L2 也被称为岭回归或 Tikhonov 正则。那它是怎么实现权重衰减的呢?我们用线性代数表示一下损失函数:

J ^ ( w ; X , y ) = α w T w + J ( w ; X , y )

我们对权重求取梯度得到
w J ^ ( w ; X , y ) = α w + w J ( w ; X , y )

因此在梯度下降过程中权重的更新为:

w w β ( α w + w J ( w ; X , y ) )

β 为梯度下降的步长,最终我们得到了:

w ( 1 β α ) w w J ( w ; X , y )

我们可以看到,加入权重衰减后会引起学习规则的修改,即在每步执行通常的梯度更 新之前先收缩权重向量(将权重向量乘以一个常数因子)。其实L2的本质是:

L2正则化能让学习算法 ‘‘感知’’ 到具有较高方差的输入 x,因此与输出目标的协方差较小(相对增加方差)的特征的权重将会收缩。
详细的图解见博客:https://blog.csdn.net/jinping_shi/article/details/52433975
下面解释一下Tensoflow的实现方式

import tensorlfow as tf
tf.contrib.layers.l2_regularizer(
    scale,
    scope=None
)
"""
Returns a function that can be used to apply L2 regularization to weights.
Small values of L2 can help prevent overfitting the training data.
Args:
scale: A scalar multiplier Tensor. 0.0 disables the regularizer.
scope: An optional scope name.
"""
# 具体的实现方式
def get_weight(shape):
    return tf.Variable(tf.random_normal(shape),dtype=tf.float32)
def get_loss(shape,lambda):
    var = get_weight(shape)
    loss = tf.reduce_mean(tf.square(y_ - cur_layer))+tf.contrib.layers.l2_regularizer(lambda)(var))
    return loss

4、L1正则化

说起L1正则化,它和L2之间区别很小,是指权值向量w中各个元素的绝对值之和,通常表示为 w 1 ,表示为:

Ω ( θ ) = 1 2 w 1 = 1 2 i = 1 n | w i |

那么损失函数就变成了:
J ^ ( w ; X , y ) = α w 1 + J ( w ; X , y )

求解梯度后就和L2之间有点区别了,它的梯度为:
w J ^ ( w ; X , y ) = α s i g n ( w ) + w J ( w ; X , y )

其中 sign(w) 只是简单地取 w 各个元素的正负号,我们立刻发现 L1 的正则化效果与 L2 大不一样。具体来说,我们可以看到正则化对梯度的影响不再是线性地缩放每个 wi;而是添加了一项与 w i 同号的常数。使用这种形式的梯度之后,我们不一定能得到 J ( X ; y ; w ) 二次近似的直接算术解(L2正则化时可以)。另外一个比较特征就是 L2正则化不会使参数变得稀疏,而L1正则化有可能通过足够大的 α 实现稀疏。由 L1正则化导出的稀疏性质已经被广泛地用于特征选择(feature selection)机制。 特征选择从可用的特征子集选择出有意义的特征,化简机器学习问题

同样的道理,L1正则化的tensorlfow代码只是使用了不同的接口而已,L2换成L1即可

tf.contrib.layers.l1_regularizer(
    scale,
    scope=None
)
#后面的就不详写了,和上文代码一样。

关于正则化的解释:
https://hit-scir.gitbooks.io/neural-networks-and-deep-learning-zh_cn/content/chap3/c3s5ss1.html

猜你喜欢

转载自blog.csdn.net/gsww404/article/details/80414675
今日推荐