TensorFlow_4正则化

TensorFlow学习系列:

TensorFlow_1参数初始化方法

TensorFlow_2学习率

TensorFlow_3激活函数

TensorFlow_4正则化

TensorFlow_5dropout

TensorFlow_6断点续训与Tensorboard可视化

TensorFlow_7优化器

TensorFlow_8损失函数

 

       避免过拟合的方法之一是增加训练数据数量。那么,还有没有别的方法能让我们避免过拟合呢?一种可能的方法是减小网络的规模。然而,我们并不情愿减小规模,因为大型网络比小型网络有更大的潜力。幸好,哪怕使用固定的网络和固定的训练数据,我们还有别的方法来避免过拟合。这就是所谓的正则化(regularization)技术。

一 、正则化的目的:解决过拟合

1.1 过拟合现象

    如图,在线性回归中:

  • 最左边的图:使用一条直线进行数据的拟合,但是这个模型并没有很好的拟合数据,产生很大的偏差。这种现象称为欠拟合
  • 中间的图:使用一个二次函数进行拟合,得到很好的拟合结果。
  • 右边的图:使用更高阶的多项式进行拟合,这个模型通过了所有的训练数据,使代价函数  约等于0甚至等于0。但是这是一条极度不规律扭曲的曲线,它并不是一个好的模型。这种现象称为过拟合

       过拟合现象:如果我们使用高阶多项式,变量(特征)过多,那么这个函数能够很好的拟合训练集,但是却会无法泛化到新的数据样本中(泛化:一个假设模型能够应用到新样本的能力)。当存在较多的变量较少的训练数据,使得没有足够的训练集来约束这个变量过多的模型,就会导致过拟合的现象

1.2 解决过拟合问题思路

  • 1)减少变量的个数:舍弃一些变量,保留更为重要的变量。但是,如果每个特征变量都对预测产生影响。当舍弃一部分变量时,也就舍弃了一些信息。所以,希望尽量保留所有的变量。
  • 2)增加样本数量
  • 3)Droput:会单独写一篇。
  • 4)正则化:保留所有的变量,将一些不重要的特征的权值置为0或权值变小使得特征的参数矩阵变得稀疏,使每一个变量都对预测产生一点影响。

二、 正则化

2.1 常见正则化方法

      回想一下,在线性回归等问题中,我们定义了损失函数:

                                                                       J(\theta;X,y )=1/2* \sum_{i=1}^{n}(y-y^{'})^{2}

       注:这里的θ是指所有的参数,包括权重w等

       我们发现,这样学习的模型虽然在测试集上比较好,但是泛化能力一般,于是就有了参数惩罚的思路,直接给J()后面加个惩罚项拖住学习的节奏),也就是正则化项,损失函数变成了:

                                                              J(\theta;X,y)= 1/2*\sum_{i=1}^{n}}(y-y^{'})^{2}+\alpha\Omega(\theta)

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

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

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

2.2 L2正则化

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

                                                                  \Omega (\theta )=\frac{1}{2}||w||_{2}^{2}=\frac{1}{2}\sum_{i=1}^{n}||w_{i}||^{2}

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

                                                               \hat{J}(w;X,y)=\alpha w^{T}w+J(w;X,y)
我们对权重求取梯度得到:

                                                              w\leftarrow w-\beta (\alpha w+\bigtriangledown _{w}J(w;X,y))

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

                                                              w\leftarrow (1-\beta \alpha )w-\bigtriangledown _{w}J(w;X,y)

我们可以看到,加入权重衰减后会引起学习规则的修改,即在每步执行通常的梯度更 新之前先收缩权重向量(将权重向量乘以一个常数因子)。其实L2的本质是:L2正则化能让学习算法 ‘‘感知’’ 到具有较高方差的输入 x,因此与输出目标的协方差较小(相对增加方差)的特征的权重将会收缩。 

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

2.3 L1正则化

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

                                                               \Omega (\theta )=\frac{1}{2}||w||_{1}=\frac{1}{2}\sum_{i=1}^{n}||w_{i}|| 

       那么损失函数就变成了: 

                                                          \hat{J}(w;X,y)=\alpha||w||_{1}+J(w;X,y)

       求解梯度后就和L2之间有点区别了,它的梯度为: 

                                                 \bigtriangledown _{w}\hat{J}(w;X,y)=\alpha sign(w)-\bigtriangledown _{w}J(w;X,y)

       其中 sign(w) 只是简单地取 w 各个元素的正负号,我们立刻发现 L1 的正则化效果与 L2 大不一样

       具体来说,我们可以看到正则化对梯度的影响不再是线性地缩放每个 wi;而是添加了一项与 wi 同号的常数。使用这种形式的梯度之后,我们不一定能得到 J(X;y;w)二次近似的直接算术解(L2正则化时可以)。

       另外一个比较特征就是 L2正则化不会使参数变得稀疏,而L1正则化有可能通过足够大的α实现稀疏。由 L1正则化导出的稀疏性质已经被广泛地用于特征选择(feature selection)机制。 特征选择从可用的特征子集选择出有意义的特征,化简机器学习问题。

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

import tensorlfow as tf
tf.contrib.layers.l1_regularizer(
    scale,
    scope=None
)

# 具体的实现方式
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.l1_regularizer(lambda)(var))
    return loss

 

欢迎扫码关注我的微信公众号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值