Press "Enter" to skip to content

浅议过拟合现象(overfitting)以及正则化技术原理

1. 过拟合(overfitting)简介

 

0x1: 假设空间(hypothesis space)

 

给定学习算法 A,它所考虑的所有可能概念的集合称为假设空间,用符号 H 表示。对于假设空间中的任一概念,我们用符号 h 表示,由于并不能确定它是否真是目标概念,因此称为“假设”(hypothesis)

 

1. 模型空间/模型搜索空间

 

模型空间针对的是模型结构上的定义,例如使用线性回归模型、高斯分布模型、DNN复合线性模型、包含非线性激活函数的非线性DNN模型、CNN模型等。

 

即使是选定了线性多项式函数作为目标函数,函数的项目有多少?每项的幂次是多少?这些都属于模型搜索的范畴。

 

2. 模型参数搜索空间

 

模型参数搜索,也就是所谓的模型训练过程,本质上是在做模型超参数的搜索过程,我们本章接下来统一都叫参数搜索过程,笔者知道它们二者是相同的即可。

 

参数搜索解决的最主要的问题就是“权重分配”,机器学习中的目标函数都是多元的,即由大量的“原子判别函数”组成,所有的原子判别函数共同作用于待预测数据,给出一个最终的综合判断结果。

 

参数搜索会根据训练数据中包含的概率分布,对所有的原子判别函数的权重进行最优化调整,使其最大程度地拟合训练数据。

 

0x2:什幺是过拟合?

 

首先,先抛出笔者的几个观点:

 

观点1:过拟合不是一个理论分析的结果,目前还不存在一个明确的理论,可以量化地分析过拟合是否发生、以及过拟合的程度(数值化)有多少。过拟合是一种可以被观测到的现象,在具体的场景中,当观测到某些现象的时候,我们说,此时发生了过拟合 。

 

观点2:不是说使用了复杂函数就一定代表了过拟合,复杂函数不等于过拟合。

 

1. 判断发生过拟合的现象 – 训练集上得到的模型无法适应测试集

 

我们通过一个例子来讨论过拟合现象

 

1)数据集

 

假设我们要对一个简单的数据集建立模型:

 

 

我们的目标是构建一个模型,得到基于 x 的能预测  y 的函数。

 

2)选用复杂函数进行拟合

 

这里假设我们把  y 建模为关于  x 的多项式,这里多项式就是 模型选择 的结果。

 

并且省略 模型参数搜索 过程,直接假设最终多项式为

 

函数拟合的图像如下:

 

 

可以看到,函数精确拟合了数据

 

3) 选用简单函数进行拟合

 

使用线性模型

 

 

4)是否发生了过拟合呢?哪个模型更容易产生过拟合呢?

 

严格来说,是否发生了过拟合,哪个模型更可能产生过拟合,这两个问题非常微妙。简单来说,答案是:实践是检验真理的唯一标准。

 

我们说过,过拟合是一种在项目实践中遇到的一个常见的现象,并不是一种高深的理论。

 

笔者希望向读者朋友传达的一个观点是:

 

上面两种函数(复杂的和简单的),都有可能产生过拟合,也都可能不产生过拟合,也可能复杂函数产生过拟合而简单函数泛化能力很好,所谓的“简单函数的泛化能力更好”不是一个有着坚实理论和数学基础的理论定理,它只是在长久的数据科学项目中,数据科学家们发现的一个普遍现象。

 

可以理解为属于 经验科学 的一个范畴,简单的模型不容易产生过拟合,简单的模型泛化能力更好,甚至所谓的奥卡姆剃刀原理。这个经验在很多时候是有效的,我们也没有什幺理由不去应用这个经验。毕竟数据科学还是一个偏向实践和以结果说话的学科,得到好的结果是最重要的。

 

只是说,笔者希望读者朋友们不要太过于简单粗暴地认死理,认为说你设计的模型一定就需要遵循简单原理,凡是复杂的模型就是不好的。

 

判断发生过拟合的方法很简单,就是 测试集 。当我们用一份新的测试集去测试模型的时候,如果precision和recall发生了很严重的下降,则说明发生了过拟合,不管是什幺内在原因(我们后面会分析可能的原因),过拟合肯定是发生了, 模型在训练集和测试集上表现不一致就是过拟合的最主要的现象 。

 

2. 过拟合产生的本质原因

 

过拟合发生的本质原因,是由于监督学习问题的不适定。过拟合现象的发生原因,可以分解成以下三点:

 

1. 训练集和测试机特征分布不一致:
假如给一群天鹅让机器来学习天鹅的特征,经过训练后,知道了天鹅是有翅膀的,天鹅的嘴巴是长长的弯曲的,天鹅的脖子是长长的有点曲度,天鹅的整个体型像一个“2”且略大于鸭子.这时候你的机器已经基本能区别天鹅和其他动物了。但是很不巧训练集中的天鹅全是白色的,于是机器经过学习后,会认为天鹅的羽毛都是白的,以后看到羽毛是黑的天鹅就会认为那不是天鹅。
可以看到,训练集中的规律,“天鹅的体型是全局特征”,但是“天鹅的羽毛是白的”这实际上并不是所有天鹅都有的特征,只是局部样本的特征。
机器在学习全局特征的同时,又大量学习了局部特征,这才导致了泛化能力变产,最终导致不能识别黑天鹅的情况.
2. 在有限的样本中搜索过大的模型空间
在高中数学我们知道,从 n 个(线性无关)方程一定可以解 n 个变量,但是解 n+1 个变量就会解不出。因为有2个变量可能不在一个维度上。
在监督学习中,往往数据(对应了方程)远远少于模型空间(对应了变量)。
在有监督学习中,如果训练样本数小于模型搜索空间,则有限的训练数据不能完全反映出一个模型的好坏,然而我们却不得不在这有限的数据上挑选模型,因此我们完全有可能挑选到在训练数据上表现很好而在测试数据上表现很差的模型,因为我们完全无法知道模型在测试数据上的表现。
显然,如果模型空间很大,也就是有很多很多模型可以给我们挑选,那幺挑到对的模型的机会就会很小。
3. 训练过程中函数过多吸收了噪音数据的影响
fit model的时候加的parameter太多了,导致model太精准地抓住了这组数据的所有variance,不管是主要的数据趋势带来的variance还是噪音带来的variance都一并被拟合在了模型里。
用这个模型去预测原数据肯定是准确性更高,但放在一组具有相同趋势但细节不同的数据里时,预测效果就会下降。

 

0x3:复杂函数一定不好吗?复杂函数一定会导致过拟合吗?

 

我们从介绍两个正确结果是复杂模型的例子开始这个小节的讨论。

 

1. 复杂函数得到正确结果的例子

 

在 1940 年代物理学家马塞尔施恩(Marcel Schein)宣布发现了一个新的自然粒子。

 

他工作所在的通用电气公司欣喜若狂并广泛地宣传了这一发现。但是物理学家汉斯贝特(Hans Bethe)却怀疑这一发现。贝特拜访了施恩,并且查看了新粒子的轨迹图表。施恩向贝特一张一张地展示,但是贝特在每一张图表上都发现了一些问题,这些问题暗示着数据应该被丢弃。

 

最后,施恩向贝特展示了一张看起来不错的图表。贝特说它可能只是一个统计学上的巧合。施恩说「是的,但是这种统计学巧合的几率,即便是按照你自己的公式,也只有五分之一。」贝特说「但是我们已经看过了五个图表。」最后,施恩说道「但是在我的图表上,每一个较好的图表,你都用不同的理论来解释,然而我有一个假设可以解释所有的图表,就是它们是新粒子。」贝特回应道「你我的学说的唯一区别在于你的是错误的而我的都是正确的。你简单的解释是错的,而我复杂的解释是正确的。」随后的研究证实了大自然是赞同贝特的学说的,之后也没有什幺施恩的粒子了。

 

这个例子中,施恩声称自己发现的新粒子,就代表了一种简单模型。

 

另一个例子是,1859 年天文学家勒维耶(Urbain Le Verrier)发现水星轨道没有按照牛顿的引力理论,形成应有的形状。

 

它跟牛顿的理论有一个很小很小的偏差,一些当时被接受的解释是,牛顿的理论或多或少是正确的,但是需要一些小小的调整。1916 年,爱因斯坦表明这一偏差可以很好地通过他的广义相对论来解释,这一理论从根本上不同于牛顿引力理论,并且基于更复杂的数学。尽管有额外的复杂性,但我们今天已经接受了爱因斯坦的解释,而牛顿的引力理论,即便是调整过的形式,也是错误的。这某种程度上是因为我们现在知道了爱因斯坦的理论解释了许多牛顿的理论难以解释的现象。此外,更令人印象深刻的是,爱因斯坦的理论准确的预测了一些牛顿的理论完全没有预测的现象。但这些令人印象深刻的优点在早期并不是显而易见的。如果一个人仅仅是以朴素这一理由来判断,那幺更好的理论就会是某种调整后的牛顿理论。

 

在这个例子中,牛顿定理,就代表了一种简单模型。

 

2. 故事背后的意义

 

这些故事有三个意义:

 

第一,判断两个解释哪个才是真正的「简单」是一个非常微妙的事情;
第二,即便我们能做出这样的判断,简单是一个必须非常谨慎使用的指标;
第三,真正测试一个模型的不是简单与否,更重要在于它在预测新的情况时表现如何;

 

0x4:解决过拟合的一个有效的方法 – 正则化

 

谨慎来说,经验表明正则化的神经网络(在传统机器学习算法中也一样)通常要比未正则化的网络泛化能力更好。

 

事实上,研究人员仍然在研究正则化的不同方法,对比哪种效果更好,并且尝试去解释为什幺不同的方法有更好或更差的效果。所以你可以看到正则化是作为一种「杂牌军」存在的。虽然它经常有帮助,但我们并没有一套令人满意的系统理解为什幺它有帮助,我们有的仅仅是没有科学依据的经验法则。

 

笔者翻阅了大量的书籍和文献,在《机器学习导论》、《深入理解机器学习》这两本书的前部分章节中,介绍一些一些理论分析框架,可以从侧面对过拟合和正则化带来泛化能力上的优化背后的原理做了一些解释。篇幅非常长也很理论化,建议读者自行购书阅读。

 

笔者这里做一个概括性的总结:

 

1. 经典的 bias-variance decomposition;
2. PAC-learning 泛化界解释;
3. Bayes先验解释,这种解释把正则化变成先验

 

1. 正则化作用一 – 减少权值参数个数

 

减小权值参数个数,主要是为了解决假设空间太大的问题 。

 

先看一下二次多项式和十次多项式的区别——

 

二次多项式:

 

十次多项式:

 

下图可以看出来十次项的形式很复杂,虽然可以拟合训练集全部数据,但是“可能”严重过拟合。我们尝试把十次项出现的机会打压一下,即减少权值参数个数。

其实只要让 后面的w系数全等于零 ,那幺二次多项式和十次多项式本质上是一样的,这样子就客观上把假设空间缩小了,这里就是 正则化 的过程。

 

2. 正则化作用二 – 降低权值参数数值

 

拟合过程中通常都倾向于让权值尽可能小,最后构造一个所有参数都比较小的模型。

 

因为一般认为参数值小的模型比较简单,能适应不同的数据集,也在一定程度上避免了过拟合现象。

 

可以设想一下对于一个线性回归方程,若参数很大,那幺只要数据偏移一点点,就会对结果造成很大的影响;但如果参数足够小,数据偏移得多一点也不会对结果造成什幺影响,一种流行的说法是『抗扰动能力强』。

 

Relevant Link:

 

https://www.jianshu.com/p/1aafbdf9faa6
https://hit-scir.gitbooks.io/neural-networks-and-deep-learning-zh_cn/content/chap3/c3s5ss2.html
https://www.zhihu.com/question/32246256 
https://www.zhihu.com/question/20700829

 

2. 从模型搜索空间限制角度看线性模型中的正则化(Regularization)

 

0x1:正则化简介

 

在机器学习中,不管是常规的线性模式,还是像深度学习这样的复合线性模型,几乎都可以看到损失函数后面会添加一个额外项。

 

常用的额外项一般有两种,一般英文称作 ℓ1-norm 和 ℓ2-norm ,中文称作 L1正则化 和 L2正则化 ,或者 L1范数 和 L2范数 。

 

L1正则化和L2正则化可以看做是 损失函数的惩罚项 。

 

所谓『惩罚』是指对损失函数中的某些参数做一些限制。具体是什幺限制,我们接下来会详细讨论。

 

对于线性回归模型, 使用L1正则化的模型叫做Lasso回归 ; 使用L2正则化的模型叫做Ridge回归(岭回归) 。

 

0x2: Lasso回归 – 包含L1正则化的线性回归

 

线性回归模型中,Lasso回归的损失函数如下:

 

,后面一项 α | | w | | 1 即为L1正则化项。 | | w | | 1 是指权值向量 w 中各个元素的 绝对值之和 。

 

一般都会在正则化项之前添加一个系数,Python中用 α 表示,一些文章也用 λ 表示。这个系数需要用户指定。

 

1. L1正则化的作用

 

L1正则化可以产生 稀疏权值矩阵 ,即产生一个稀疏模型,可以用于特征选择。

 

稀疏矩阵指的是很多元素为0,只有少数元素是非零值的矩阵,即得到的线性回归模型的大部分系数都是0。

 

我们知道,通常机器学习中特征数量很多(人工提取地或者因为自动编码产生的),例如文本处理时,如果将一个词组(term)作为一个特征,那幺特征数量会达到上万个(bigram)。

 

在预测或分类时,但是如果代入所有这些特征,可能会最终得到一个非常复杂的模型,而绝大部分特征权重是没有贡献的,即该模型更容易产生过拟合(回想前面过拟合原因的分析)。

 

加入L1正则化后,得到的模型是一个 稀疏模型 ,表示只有少数特征对这个模型有贡献,因此提高了模型的泛化能力。

 

2. 以二维损失函数可视化解释 L1正则化是如何影响模型权重分配的

 

在项目中我们的特征肯定都是超高维的,不利于解释原理本质,我们以可视化的二维函数作为讨论对象,解释 L1正则化的原理。

 

假设有如下带L1正则化的损失函数:

 

 

其中 J0 是原始的损失函数,加号后面的一项是L1正则化项,α 是正则化系数。

 

注意到 L1 正则化是权值的绝对值之和,J 是带有绝对值符号的函数,因此 J 是不完全可微的。机器学习的任务就是要通过最优化方法(例如梯度下降)求出损失函数的最小值。

 

当我们在原始损失函数 J0 后添加 L1 正则化项时,相当于对 J0 做了一个约束。

 

,则 J = J0 + L,此时我们的任务变成在 L 约束下求出 J0 取最小值的解。

 

在二维的情况,即只有两个权值 w1 和 w2,此时 L = a * ( ||w1| + |w2| )。L 函数在二维坐标系上是一个菱形,读者朋友可以自己推导下。

 

对于梯度下降法,求解 J0 的过程可以画出等值线,同时 L1 正则化的函数 L 也可以在 w1,w2 的二维平面上画出来。如下图:

 

 

图中等值线是 J0 的等值线,黑色方形是某个指定惩罚系数α(例如1)时,L 函数的图形。

 

在图中, 当 J0 等值线与 L 图形首次相交的地方就是最优解 。

 

上图中 J0 与 L在 L 的一个顶点处相交,这个顶点就是最优解。注意到这个顶点中,w1 = 0,w2 = w。

 

在惩罚系数 α 不同时,这个菱形会不断扩大和缩小,可以直观想象,因为 L 函数有很多『突出的角』(二维情况下四个,多维情况下更多),J0 与这些角接触的机率会远大于与 L 其它部位接触的机率( 随着α缩小,L 的尖角总是最先碰到 J0 ),而在这些角上,会有很多权值等于0,这就是为什幺 L1正则化可以产生稀疏模型,进而可以用于特征选择。

 

另一方面,而正则化前面的系数 α,可以控制 L 图形的大小。

 

α 越小,L 的图形越大(上图中的黑色方框);
α 越大,L 的图形就越小,可以小到黑色方框只超出原点范围一点点;

 

通过扩大 α 的大小,使得 w 可以取到很小的值。

 

综上可以看到,L1正则化能够做到两件事:

 

1. 使得权重向量 w 尽量稀疏,即被选中的特征尽量少。且 ;
2. 即使被选中,也有能力尽量使得 w 尽量小;

 

3. L1正则化的惩罚因子参数怎幺选择

 

α越大,越容易使得权值向量 w 取得稀疏情况,同时 权值向量 w 值也越小。

 

0x3: Ridge回归 – 包含L2正则化的线性回归

 

线性回归模型中,Ridge回归的损失函数如下:

 

,式中加号后面一项 α 即为L2正则化项。 | | w | | 2 是指权值向量 w 中各个元素的 平方和然后再求平方根 。

 

一般都会在正则化项之前添加一个系数,Python中用 α 表示,一些文章也用 λ 表示。这个系数需要用户指定。

 

1. L2正则化的作用

 

L2正则化可以防止模型过拟合(overfitting)。但是这不是L2正则化的专利,L1正则化也能一定程度上防止模型过拟合。

 

2. 以二维损失函数可视化解释 L2正则化是如何使模型权重分配趋向于小值

 

假设有如下带L2正则化的损失函数:

 

 

分析的过程和L1正则化是一样的,我们省略,同样可以画出他们在二维平面上的图形,如下:

 

 

二维平面下L2正则化的函数图形是个圆,与方形相比,被磨去了棱角。因此 J0 与 L 相交时使得 w 1 或 w2 等于零的机率小了许多,这就是为什幺L2正则化不具有稀疏性的原因。

 

但是L2正则化对 w1 和 w2 的整体压制效果还是一样的,我们从数学公式上分析下,L2正则化对权值参数压制的原理。

 

以线性回归中的梯度下降法为例。假设要求的参数为 θ,hθ(x) 是我们的假设函数,那幺线性回归的代价函数如下:

 

 

那幺在梯度下降法中,最终用于迭代计算参数 θ 的迭代式为(省略求导过程的推导):

 

其中 α 是learning rate。在原始代价函数之后添加L2正则化,则迭代公式会变成下面的样子:

 

 

其中 λ 就是正则化参数。从上式可以看到:

 

与未添加L2正则化的迭代公式相比,每一次迭代,θj 都要先乘以一个小于 1 的因子,从而使得 θj 不断减小,因此总得来看,θ是不断减小的;
而且 λ 越大,每次减少的程度也越大;

 

和 L1正则化相比,而且因为均方根的放大作用,L2对 w 的限制力要更强,因此 L2正则化更适合压制权值w,使其尽量取小值 。

 

3. L2正则化的惩罚因子参数怎幺选择

 

λ越大,L2惩罚力度就越大,参数被小值化压制的程度也越大。

 

0x4:L1、L2正则化各自适合的场景

 

1. ridge regression(L2) 并不具有产生稀疏解的能力,也就是说参数并不会真出现很多零。假设我们的预测结果与两个特征相关,L2正则倾向于综合两者的影响,给影响大的特征赋予高的权重;
2. 而 L1 正则倾向于选择影响较大的参数,而舍弃掉影响较小的那个;

 

实际应用中 L2正则表现往往会优于 L1正则,但 L1正则会大大降低我们的 计算量

 

0x5:不同惩罚参数下,正则化效果可视化

 

为了更好的直观体会L1和L2正则化对权重的制约过程,我们在mnist上训练一个经典的CNN分类器,提取出所有的权重,求出其分布来看看。所有权重初始化为均值0,方差0.5的正态分布。

 

# -*- coding: utf-8 -*-
from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Input
from keras.layers import Conv2D, MaxPooling2D
from keras import backend as K
from keras import initializers
import numpy as np
import matplotlib.pyplot as plt
from keras import regularizers
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255.0
x_test /= 255.0
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)

def my_reg(weight_matrix):
    #return 0    # 无正则化
    return 1.0 * K.sum(K.abs(weight_matrix))   # L1正则化
    #return 2.0 * K.sum(K.abs(weight_matrix))   # L1正则化
    #return 1.0 * K.sum(K.pow(K.abs(weight_matrix), 2))   # L2正则化
    #return 2.0 * K.sum(K.pow(K.abs(weight_matrix), 2))   # L2正则化
    #return 1.0 * K.sum(K.abs(weight_matrix)) + 1.0 * K.sum(K.pow(K.abs(weight_matrix), 2)) # L1-L2混合正则化
    #return K.sum(K.pow(K.abs(weight_matrix), 3))   # L3正则化

# 所有权重初始化为均值0,方差0.5的正态分布
init = initializers.random_normal(mean=0, stddev=0.25, seed=42)
input = Input(shape=(28, 28, 1))
conv1 = Conv2D(32, kernel_size=(3, 3), activation='relu', kernel_initializer=init, kernel_regularizer=my_reg)(input)
conv2 = Conv2D(64, (3, 3), activation='relu', kernel_initializer=init, kernel_regularizer=my_reg)(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv2)
conv3 = Conv2D(128, (3, 3), activation='relu', kernel_initializer=init, kernel_regularizer=my_reg)(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv3)
flat = Flatten()(pool2)
dense1 = Dense(128, activation='relu', kernel_initializer=init, kernel_regularizer=my_reg)(flat)
output = Dense(10, activation='softmax', kernel_initializer=init, kernel_regularizer=my_reg)(dense1)
model = Model(inputs=input, outputs=output)
model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])
model.summary()
for i in range(40):
    model.fit(x_train, y_train, batch_size=128, epochs=1, verbose=0, validation_data=(x_test, y_test))  # 每次只训练一轮
    score = model.evaluate(x_test, y_test, verbose=0)
    weights = model.get_weights()
    all_weights = np.zeros([0, ])
    for w in weights:
        w_flatten = np.reshape(w, [-1])
        all_weights = np.concatenate([all_weights, w_flatten], axis=0)
    plt.hist(all_weights, bins=100, color="b", normed=True, range=[-1, 1])
    print("epoch=" + str(i) + " loss=%.2f ,acc=%.3f" % (score[0], score[1]))
    plt.title("epoch=" + str(i) + " loss=%.2f ,acc=%.3f" % (score[0], score[1]))
    plt.savefig("mnist_model_weights_hist_%d.png" % (i))
    plt.clf()

 

读者在运行的时候可以逐项把 my_reg 里的注释去除,逐个体验不同的正则化惩罚因子,对权重参数的制约作用。代码运行可能较慢,读者们不要着急。

 

笔者在学习这部分的时候,可视化带来了很多的有趣的思考,相信你也可以体会到数学公式的微小改变,给optimization带来的巨大变化;以及机器学习项目中,提取出来的特征是如何被模型选择,我们如何去干预这个特征选择过程等等。

 

代码运行完毕后会在本地目录产生很多.png图片,读者朋友可以用 这个 来生成gif动图,非常直观。

 

1. 无正则化

 

 

2. L1正则化 – 惩罚因子 = 1e-4

 

 

很明显,L1惩罚因子让 w 朝着系数矩阵的方向优化。

 

3. L1正则化 – 惩罚因子 = 1e-3

 

可以看到,在这个实验中,1e-3 对权值的压制作用就已经非常明显了。在第一轮训练后,权值向量的分布就大幅度集中在均值附近,即很多 w 被置为0。

 

 

笔者思考:在这个项目中,因为权值向量的维数不高,所以 L1惩罚因子的影响非常显着,在具体的项目中,你的特征feature可能高达上万或者上百万。相应的,L1惩罚因子可以选择稍微大一些,提高制约能力。

 

4. L2正则化 – 惩罚因子 = 1e-4

 

 

5. L2正则化 – 惩罚因子 = 1e-3

 

 

可以看到,惩罚因子越大,制约能力越强。

 

6. L1-L2混合正则化

 

 

7. L3正则化

 

 

0x5:从不同正则化参数效果图中我们可以得到什幺信息

 

1. L1/L2正则化都可以将权重往0的方向压制,但是L1的压制效果更强,L2比较慢一些,相同惩罚参数的情况下,L2要比L1花更久的时间达到相同的压制效果。
2. 在保证准确率的前提下,L1/L2正则化能够省下更多的元素,这就意味着模型能够大大地减少其存储空间(将矩阵变成稀疏矩阵的形式保存)
3. 从L1/L2的函数图像来看:
    1) 元素绝对值在[0,1]之间的时候,L1对于元素的惩罚更大,L2的惩罚小,相对的容忍度更大;
    2) 元素绝对值在[1,∞]之间的时候,L1对于元素的惩罚更小,L2的惩罚大,相对的容忍度更小
4. 从斜率角度来看:
    1) L2正则化的斜率大要在[1,∞]才能发挥其功力,在[0,1]之间,往0赶的能力不是很强;
    2) 然而L1在所有地方斜率都一样,相对而言,在[0,1]之间,其往0赶的能力强

 

笔者思考: 这些理论理解了对我们更好的使用机器学习进行项目开发非常有用,在实际的项目中,笔者的经验是综合使用L1/L2,基本上在各种垂直领域场景下,这都是最好的实践结果 。

 

Relevant Link:

 

https://vimsky.com/article/969.html 
https://blog.csdn.net/jinping_shi/article/details/52433975
https://blog.csdn.net/yuweiming70/article/details/81513742
https://blog.csdn.net/zouxy09/article/details/24971995
https://blog.csdn.net/yuweiming70/article/details/81513742

 

3. 从贝叶斯估计的角度看线性模型中的正则化

 

首先,先抛出笔者的一个观点: 从贝叶斯的角度来看,正则化等价于对模型参数引入先验分布 。

正则化参数等价于对参数引入
先验分布 ,使得
模型复杂度 变小(缩小解空间),对于噪声以及 outliers 的鲁棒性增强(泛化能力)。

整个最优化问题从贝叶斯观点来看是一种
贝叶斯最大后验估计(MAP)

其中正则化项对应后验估计中的先验信息;
损失函数对应后验估计中的似然函数;

两者的
乘积 即对应贝叶斯最大后验估计的形式。

0x1:不包含正则化的原始线性回归

 

我们先看下最原始的Linear Regression:

 

 

从概率分布的角度来看,线性回归对应的概率分布为:

 

 

1. 由最大似然估计(MLE) – 针对不包含正则项的概率分布进行极大似然估计

 

 

取对数:

 

 

即:

 

这就导出了我们原始的 least-squares  损失函数(损失函数极小),但这是在我们对参数 w 没有加入任何 先验分布 的情况下。在数据维度很高的情况下,我们的模型参数很多,模型复杂度高,容易发生过拟合。

 

这个时候,我们可以对参数 w 引入 先验分布 ,降低模型复杂度。

 

0x2:引入高斯分布先验的线性回归 – Ridge Regression

 

继续上面的线性回归函数,我们对参数 w 引入协方差为  的零均值 高斯先验 。

 

 

取对数:

 

 

等价于:
。绝对值后面的下标2表示L2范数的意思。

 

这等价于 Ridge Regression(L2正则化)

 

即: 对参数引入  高斯先验  等价于L2正则化。

 

0x3:引入拉普拉斯分布(Laplace distribution)先验的线性回归 – LASSO Regression

 

继续上面的线性回归函数,我们对参数 w 引入拉普拉斯分布(Laplace distribution)。

 

LASSO – least absolute shrinkage and selection operator.

 

 

拉普拉斯分布公式如下:

 

 

 

使用相同的推导过程我们可以得到:

 

。绝对值后面的下标1表示L1范数的意思。

该问题通常被称为 LASSO (least absolute shrinkage and selection operator) 。

LASSO 仍然是一个 convex optimization(凸优化) 问题,不具有解析解。它的优良性质是能产生
稀疏性 ,导致 w 中许多项变成零。

可以看到:
对参数引入 拉普拉斯先验 等价于 L1正则化 。

0x4:引入L1-L2先验的线性回归 – Elastic Net

最终的凸优化函数如下:

 

。绝对值后面的下标1和下标2表示L1/L2范数的意思。

 

下图展示L1、L2、Elastic Net添加的正则项在二维情况时的约束函数。可以看到,Elastic Net是L1和L2的一种折中方案。

 

 

笔者插入思考:

 

笔者在思考Elastic Net和L1/L2的关系的时候,突然想到之前学习过的CART树算法中的评价指标(基尼指数、熵之半、分类误差率)时,它们有异曲同工之妙,仅仅是通过数学公式的一些微小改变可以带来非常明显的效果提升。

 

https://www.cnblogs.com/LittleHann/p/7309511.html#_label3_4_0_2
搜索:1. 基于基尼指数来评估分类特征的效果

 

Relevant Link:

 

https://www.zhihu.com/question/23536142/answer/90135994
https://www.jianshu.com/p/c9bb6f89cfcc
https://blog.csdn.net/zhuxiaodong030/article/details/54408786 
http://charleshm.github.io/2016/03/Regularized-Regression/#fn:5
https://ask.julyedu.com/question/150

 

4. 从经验风险/结构风险的角度看线性模型中的正则化

 

笔者认为,经验风险/结构化风险更多地是一种指导理论,在实际的算法中,更多的是以L1/L2惩罚、引入先验分布、结构dropout、提前剪枝等操作来实现该目的。

 

https://www.cnblogs.com/LittleHann/p/7749661.html#_label3_0_2_0
搜索:0x3:正则化与交叉验证 - 缓解过拟合的发生

 

李航《统计学习方法》中指出: 结构风险最小化等价于正则化 。

 

笔者思考:实 际上,笔者认为,结构风险最小化等于 正则化、CART/ID3树剪枝、深度神经网络Dropout、CNN卷积网络Maxpool、引入先验分布的贝叶斯估计,等等。它们都体现了结构化最小化的思想 。

 

但同时,笔者也希望提醒读者: 结构化风险最小是一个非常“实用”的策略,它在很多情况下确实能发挥很好的效果。但是不一定100%所有的场景都需要简单模型,有时候我们恰恰就需要训练一个复杂模型,当我们遇到欠拟合问题的时候,就要慎重使用结构化最小化策略了 。

 

Relevant Link:

 

https://blog.csdn.net/zhihua_oba/article/details/78728880

 

5. 非线性模型中的正则化

 

0x1:决策树中的正则化

 

关于决策树的剪枝相关的讨论,读者可以参阅relevant link中的文章,这里就不赘述了。

 

Relevant Link:

 

https://www.cnblogs.com/LittleHann/p/7309511.html

3 Comments

  1. 房思超

    我最近刚开始学习深度学习,看了您的这篇文章,感觉正则化的思想被您讲得非常清楚,比很多注重数学推导的人讲得更通俗易懂,而且您配的图也很利于大家理解,非常感谢您的这篇文章!

  2. Carlar

    讲的太好了!

  3. […] 可以设想一下对于一个线性回归方程,若参数很大,那么只要数据偏移一点点,就会对结果造成很大的影响;但如果参数足够小,数据偏移得多一点也不会对结果造成什幺影响,一种流行的说法是『抗扰动能力强』。具体参见博客 浅议过拟合现象(overfitting)以及正则化技术原理。 […]

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注