PS:学习内容来自李宏毅机器学习2019版
误差
误差的来源
平均误差(Average Error)会随着模型复杂增加呈指数上升趋势。更复杂的模型并不能给测试集带来更好的效果,而这些Error的主要来源是偏差(bias)和方差(variance)。
关于bias和variance,可以查看链接里的解答。机器学习中Bias(偏差)、Error(误差)Variance(方差)的区区别与联系。下面简单介绍自己对问题答复中的理解,不一定正确,因为有些回答有一些出入,如有错误,恳请指出改正。
在《机器学习》(周志华)一书中:泛化误差(Error) = 偏差(Bias) + 方差(Variance) + 噪声(Noise),其中:
- 偏差度量了学习算法的期望预测与真实结果的偏离程度,即刻画了算法本身的拟合能力;
- 方差度量了同样大小的训练集的变动所导致的学习性能的变化,即刻画了数据扰动所造成的影响即模型的稳定性;
- 噪声则表达了在当前任务上任何学习算法所能达到的期望繁花误差的下界,即刻画了学习问题本身的难度。
偏差-方差分解说明,泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度共同决定的。给定学习任务,为了取得好的泛化新能,则需使偏差较小,既能够充分拟合数据,并且使方差较小,即使得数据扰动产生的影响小。
通俗理解就是,对于我们能获得的数据,在这个数据集上存在某个模型能使得损失最小,我们假设称之为“真实模型”,但是这样一个真实模型,由于我们不可能获得所有可能的数据,因而训练出来的模型与“真实模型”存在差距,虽无法获得,但是“真实模型”确是客观存在的。为此,我们的最终目标就是去学习一个模型使其更接近这个真实模型。而bias和variance分别从两个方面描述我们学习到的模型与真实模型之间的差距: - bias:训练出来的模型在训练数据集上所有输出与真实值之间的差距的平均值即期望,也就是模型拟合贴合真实模型的程度。
- variance:不同的训练数据集训练出的模型的输出值之间差异的方差,而方差刻画的是模型的稳定性,即数据扰动对模型的影响。
上述两个参数的要对模型优化又有哪些指导意义呢?下图以打靶,命中靶心为目标为例,其中bias可以是做瞄准是否准,variance则表示风呀,手呀等因素影响的打的是否准。 - 准:bias含义上面已有解释,简单讲就是在样本上拟合的好不好。要想在bias上表现好,low bias,就得复杂化模型,增加模型的参数,但是这样旧容易过拟合(overfitting)。对应上图的low bias high variance的打靶图,点很分散。low bias对应的点都打在了靶心附近,所以瞄的是准的,但是手不一定稳。
- 确:variance描述的是样本上训练出来的模型在测试集上的表现,要想在variance上表现好,low varience,就得简化模型,减少模型参数,但这样容易欠拟合(underfitting),欠拟合对应上图high bias low variance,点偏离中心。low variance对应的点都打的很集中,但不一定是靶心附近,手很稳,但是瞄的不准。
从图以及上述解释可以看出,两个指标对同一模型优化指导上相互矛盾,如low bias要求模型复杂,而low variance却要求模型简单。因此bias和variance之间的tradeoff(折中)是机器学习的永恒主题之一。
估测变量x的偏差和方差
偏差和方差计算公式,以及用于机器学习中模型的选择也可以通过链接进行更详细的学习,同时里面含有偏差与方差对机器学习模型选择相关内容。偏差(Bias)和方差(Variance)–机器学习中的模型选择。
评估x的偏差
- 假设x的平均值为
μ
\mu
μ,方差为
σ
2
\sigma^2
σ2
样本的平均估值如何处理呢? - 首先拿到N个样本点: { x 1 , x 2 , x 3 , . . . , x n } \{ x_1,x_2,x_3,...,x_n \} {x1,x2,x3,...,xn}
- 计算平均值m,得到 m = 1 N ∑ n x n ≠ μ m = \frac 1 N \sum_n{x^n} \neq \mu m=N1∑nxn=μ
然后对m求期望:
E
[
m
]
=
E
[
1
N
∑
x
n
]
=
μ
E[m] = E[\frac 1 N \sum{x^n}] = \mu
E[m]=E[N1∑xn]=μ
这个估计是
μ
\mu
μ的无偏估计。m对于
μ
\mu
μ的离散程度(方差):
V
a
r
[
m
]
=
σ
2
N
Var[m] = \frac {\sigma^2} N
Var[m]=Nσ2
估测x的方差
估测样本x的方差,则是用样本值与样本平均值只差的平均即:
s
2
=
1
N
∑
n
(
x
n
−
m
)
2
s^2 = \frac 1 N\sum_n{(x^n - m)^2}
s2=N1n∑(xn−m)2
对其求期望得到样本方差:
E
[
s
2
]
=
N
−
1
N
σ
2
≠
σ
2
E[s^2]=\frac {N-1} N \sigma^2\neq \sigma^2
E[s2]=NN−1σ2=σ2
为什么会有很多的模型
用同意model,在不同的训练集中找到function就是不一样的。就像在靶心上射击,进行了横夺组(一组多次)。现在需要知道它的散布是怎样的,讲100个宇宙中的model画出来不同的数据集之前什么都有可能发生。
考虑不同模型的方差
一次模型的方差比较小,也就是比较集中,离散程度较小。而五次模型的方差就比较大,同理散布比较广,离散程度较大。所以用比较简单的模型,方差是比较小的(就像射击的时候,每次射击的设置都集中在一个比较小的区域中)。如果用到了复杂的模型,方差就很大,散布比较开。这也是因为简单的模型收到不同训练集的影响是较小的。
偏差VS方差
将误差才分为偏差和方差。简单模型(左边)是偏差比较大造成的误差,这种情况叫做欠拟合,而复杂模型(右边)是方差过大造成的误差,这种情况叫做过拟合。
如何判断过拟合与欠拟合及一些解决方式
如果模型没有哼好的训练训练集,就是偏差过大,也就是欠拟合;如果模型很好的训练训练集,即再训练集上得到很小的错误,但在测试集上得到大的错误,这意味着模型可能方差比较大,就是过拟合。对于欠拟合和过拟合,使用不同的方式来处理的
偏差大-欠拟合
此时应该重新设计模型。因为之前的函数集里面可能跟本没有包含f*。可以:
- 将更多特征加入进去
- 考虑更多次幂、更复杂的模型
如果此时强行再收集更多的data去训练,这也是没有什么帮助的,因为设计的函数本身就不好,再找更多的训练集也不会更好。
方差大-过拟合
简单粗暴的方法:更多的数据。但是很多时候不一定能做到收集更多的data。可以针对问题的理解对数据集做调整。比如识别手写数字的时候,偏转角度的数据集不够,那就将正常的数据集左转15度,右转15度,类似这样处理。还有时,应当注意各类数据之间的比列。
模型选择
现在在偏差和方差之间就需要一个权衡想选择的模型,可以平衡偏差和方差产生的错误,使得总错误最小,但是下面这件事最好不要做:
用训练集训练不同的模型,然后再测试集上比较误差,模型3的错误较小,就认为模型3好。但实际上这只是我们手上的测试集,真正完整的测试集并没有。比如再已有的测试集上错误是0.5,但又条件收集到更多的测试集后错误通常大于0.5。
交叉验证
图中public的测试集是已有的,private是没有的,不知道的。交叉验证就是将训练集再分为两部分,一部分作为训练集,一部分作为验证集。用训练集训练模型,然后再验证集上比较,确定出最好的模型之后(比如模型3),再用全部的训练集训练模型3,然后再用public的测试集进行测试,此时一般得到的错误都是大一些的。不过此时会比较想再回去调一下参数,调整模型,让在public的测试集上更好,但不太推荐这样。上述方法可能会出现训练集拆分的时候因为数据拆分情况,而使得模型效果较差,为此可以使用K折验证的方法。
K-折交叉验证
将训练集分成K份,比如3份。每次将其中一份作为验证集,其他的作为训练集,分别得到同一模型的误差最后取平均得到平均误差,最后选择平均误差最小的模型,使用全部测试集数据进行训练模型。比如在下图中三份训练结果平均错误模型1最后,再用全部训练集训练模型1。
梯度下降法
梯度下降的做法在回归模型中已经介绍了。
回顾梯度下降法
在回归问题的第三步中,需要解决下面的最优化问题:
θ
∗
=
arg min
θ
L
(
θ
)
\theta^*=\argmin_\theta L(\theta)
θ∗=θargminL(θ)
- L L L:lossfunction(损失函数)
-
θ
\theta
θ:parameters(参数)
这里的parameters是复数,即 θ \theta θ指代一堆参数,比如线性回归中的 w w w和 b b b。我们要找一组参数 θ \theta θ,让损失函数越小越好,这个问题可以使用梯度下降法解决。
假设 θ \theta θ里有两个参数 θ 1 \theta_1 θ1, θ 2 \theta_2 θ2随机选取促使值: θ 0 = [ θ 1 0 θ 2 0 ] \theta^0=\left[\begin{matrix}\theta_1^0 \\ \theta_2^0\end{matrix}\right] θ0=[θ10θ20]
然后分别计算初始点处两个参数对 L L L的偏微分,然后 θ 0 \theta^0 θ0剪掉 η \eta η(学习率)乘上偏微分的值,得到一组新的参数,同理这样反复计算。黄色部分为简洁写法, ∇ L ( θ ) \nabla L(\theta) ∇L(θ)即为梯度。由于梯度方向是函数增加最快的反向,我们要求最小值,应该沿梯度的反方向运动,可视化如下图所示。
Tip:调整学习率
学习率的调整需要谨慎![在这里插入图片描述](https://img-blog.csdnimg.cn/ade9853f704f4d199a46ac829c1e1f5d.png#pic_center)
上图中左边黑色为损失函数的曲线,假设从左边最高点开始,如果学习率调整的的刚刚好,比如红色的线,就能顺利而且较快的找到最低点。如果学习率调整的太小了,比如蓝色的线,就会走的太慢,训练时间会较长,同时在局部最优时,可能难以离开局部最优形成的山谷去寻找全局最优。如果学习率调整的太大,如绿色的线,就会在上面震荡,走不下去,无法达到最低点。还有一种可能,学习率非常大,直接飞出去了,更新参数的时候只会发现损失函数越更新越大。
虽然这样可以可视化,但可视化尽可在参数是一维或者二维的时候进行,更高维则无法进行可视化了。解决方案是上图右边的方案,将参数改变对损失函数的影响进行可视化。比如学习率太小(蓝色的线),损失函数下降的非常慢;学习率太大(绿色的线),损失函数下降恒快,但是马上卡住不下降了;学习率特别大(黄色的线),损失函数就飞出去了;红色的差不多刚好,可以得到一个好的结果。
自适应学习率
通常刚开始,初始点会距离最低点比较远,所以使用大一点的学习率。更新几次参数后,比较靠近最低点了,此时需要减少学习率。一个想法就是需要动态的调整学习率,其中对上述过程思考一种简单想法:随着次数增加,通过一些因子来减少学习率如: η t = η t t + 1 \eta^t = \frac {\eta^t} {\sqrt{t+1}} ηt=t+1ηt。学习率不能是一个值通用所有特征,因而不同的参数需要不同的学习率。
Adagrad算法
每个参数的学习率都除以之前微分的均方根。
普通的梯度下降为:
w
t
+
1
←
w
t
−
η
t
g
t
η
t
=
η
t
t
+
1
w^{t+1}\leftarrow w^t-\eta^tg^t \\ \eta^t = \frac {\eta^t} {\sqrt{t+1}}
wt+1←wt−ηtgtηt=t+1ηt
其中
w
w
w是一个参数。Adagrad可以做的更好:
w
t
+
1
←
w
t
−
η
t
σ
t
g
t
g
t
=
∂
L
(
θ
t
)
∂
w
w^{t+1}\leftarrow w^t-\frac {\eta^t} {\sigma^t} g^t \\ g^t = \frac {\partial L(\theta^t)} {\partial w}
wt+1←wt−σtηtgtgt=∂w∂L(θt)
其中
σ
t
\sigma^t
σt:之前参数的所有微方的均方根,对于每个参数都是不一样的。下图是一个参数更新过程,可以直观理解
σ
t
\sigma^t
σt的含义。
将Adagrad的式子进行化简:
Adagrad存在的矛盾?
在Adagrad中,当梯度越大的时候,步伐应该越大,但是梯度越大的时候,下面的分母也会越大,从而导致步伐会越小。因此分母会会造成反差。下面对梯度越大应该步伐进行解释:
比如初始点在
x
0
x_0
x0,最低点为
−
b
2
a
-\frac b {2a}
−2ab,最佳步伐应该是
x
0
x_0
x0到最低点
−
b
2
a
-\frac b {2a}
−2ab之间的距离
∣
x
0
+
b
2
a
∣
|x_0+\frac b {2a}|
∣x0+2ab∣,也可以写成
∣
2
a
x
0
+
b
2
a
∣
|\frac {2ax_0+b} {2a}|
∣2a2ax0+b∣。而2a刚好是
∣
2
a
x
0
+
b
∣
|2ax_0+b|
∣2ax0+b∣在
x
0
x_0
x0这一点的微分。
这样可以认为如果算出来的微分越大,则是距离最低点越远。而且最好的步伐和微分的大小成正比。所以如果使用的步长如果与微分成正比,它可能是比较好的。
结论1-1:梯度越大,就跟最低点的距离越远。这个结论在多个参数的时候不一定成立了。
多参数下结论不一定成立
上图左边是两个参数的损失函数,颜色代表损失函数的值。如果只考虑参数
w
1
w_1
w1,就像图中蓝色的线,得到右边上图结果;如果只考虑参数
w
2
w_2
w2,就像图中绿色的线,得到右边下图结果。确实对于a和b,结论1-1成立,同理c和b也成立。但是如果对比a和c,就不成立了,c比a大,但c距离最低点是比较远的。所以结论1-1是在没有考虑参数对比的情况下,才能成立的。所以还不完善。
之前说到的最佳距离
∣
2
a
x
0
+
b
2
a
∣
|\frac {2ax_0+b} {2a}|
∣2a2ax0+b∣,还有个分母2a。对function进行二次微分刚好可以得到:
∂
2
y
∂
x
2
=
2
a
\frac {\partial^2y} {\partial x^2} = 2a
∂x2∂2y=2a
所以最好的步伐应该是:
一次微分
二次微风
\frac {一次微分} {二次微风}
二次微风一次微分
即不仅和一次微分成正比,还和二次微分成反比。最好的步长应该考虑到二次微分。
Adagrad进一步的解释
再回到之前的Adagrad,对于
g
t
g^t
gt是一次微分,显然
σ
t
\sigma^t
σt不是二次微分,是否
σ
t
\sigma^t
σt与二次微分有关呢?对于
σ
t
\sigma^t
σt就是希望再尽可能不增加过多运算的情况下模拟二次微分。弱国计算二次微分,在实际情况中可能会增加很多的时间。
Tip2:随机梯度下降法
之前的梯度下降,需要考虑每一个样本点的损失:
L
=
∑
n
(
y
^
n
−
(
b
+
∑
w
i
x
i
n
)
)
2
θ
i
=
θ
i
−
1
−
η
∇
L
(
θ
i
−
1
)
L = \sum_n{(\hat{y}^n-(b+\sum{w_ix_i^n}))^2} \\ \theta^i = \theta^{i-1} - \eta \nabla L(\theta^{i-1})
L=n∑(y^n−(b+∑wixin))2θi=θi−1−η∇L(θi−1)
相脚之下随机梯度下降法更快,其损失函数不需要处理训练集所有的数据,选取一个例子
x
n
x^n
xn
L
=
∑
n
(
y
^
n
−
(
b
+
∑
w
i
x
i
n
)
)
2
θ
i
=
θ
i
−
1
−
η
∇
L
n
(
θ
i
−
1
)
L = \sum_n{(\hat{y}^n-(b+\sum{w_ix_i^n}))^2} \\ \theta^i = \theta^{i-1} - \eta \nabla L^n(\theta^{i-1})
L=n∑(y^n−(b+∑wixin))2θi=θi−1−η∇Ln(θi−1)
此时不需要像之前那样对所有的数据进行处理,只需要计算某一个例子的损失函数
L
n
L_n
Ln就可以赶紧更新梯度了。假设有20个数据样例,常规梯度下降法要处理到所有二十个例子,但随机梯度下降只需要处理一个例子就更新,因而同样的时间下,随机梯度更新已经走了二十步了。
Tip3:特征缩放
比如有个函数:
y
=
w
1
x
1
+
w
2
x
2
+
b
y = w_1x_1+w_2x_2+b
y=w1x1+w2x2+b
两个输入的分布的范围很不一样,数量级相差较大,建议把他们的范围缩放,使得不同输入的范围一样的或者数量级相差不是很大。
为什么要这样处理?
上图左边是
x
1
x_1
x1的范围比
x
2
x_2
x2要小很多,所以当
w
1
w_1
w1和
w
2
w_2
w2做同样变化时,
x
1
x_1
x1对y的变化影响是较小的,
x
2
x_2
x2对y的变化影响是比较大的。
坐标系中是两个参数的损失等高线,因为
w
1
w_1
w1对y的变化影响较小,所以
w
1
w_1
w1对损失函数的影响比较小,因而
w
1
w_1
w1对损失函数有比较小的微分,所以
w
1
w_1
w1方向上是比较平滑的。同理
w
2
w_2
w2对损失函数的影响比较大,因而
w
1
w_1
w1对损失函数有比较大的微分,所以
w
2
w_2
w2方向上是比较尖的峡谷。
上图右边是两个参数的范围比较接近,右边的绿色图就比较接近圆形。对于左边的情况,上面讲过这种狭长的情形如果不用Adagrad比较难处理,两个方向上需要不同的学习率,同一组学习率会搞不定它。而右边情形更新参数就会变得比较容易。左边的梯度下降并不是向着最低方向走的,而是顺着等高线切线的法向走的。但右边就可以向着原心(最低点)走,这样做参数更新也是比较有效率。
怎么做缩放
方法非常多,这里举例一种常见的作法,线性归一化的方式:
上图每一列都是一个样本数据,里面都有一组特征。对每一个二维度i(绿色框)求和计算平均数,记作
m
i
m_i
mi,同时计算标准差,记作
σ
i
\sigma_i
σi。然后每一个例子的第i个输入,减去平均数
m
i
m_i
mi,然后除以标准差
σ
i
\sigma_i
σi,得到的结果是所有的维数都是平均值为0,方差为1。
梯度下降的数学理论
对于损失函数寻找最小值,比如再在 θ 0 \theta^0 θ0处,可以找到一个小范围圆圈内找到损失函数细小的 θ 1 \theta^1 θ1,不断的这样去寻找。接下来就是如何在小圆圈内快速找到最小值?
泰勒展开式
定义
若
h
(
x
)
h(x)
h(x)在
x
=
x
0
x = x_0
x=x0点的某个邻域内有无限阶倒数(即可无线微分,infinitely differentiable),那么在此邻域内有:
h
(
x
)
=
∑
k
=
0
∞
h
k
(
x
0
)
k
!
(
x
−
x
0
)
k
=
h
(
x
0
)
+
h
′
(
x
0
)
(
x
−
x
0
)
+
h
′
′
(
x
0
)
2
!
(
x
−
x
0
)
2
+
.
.
.
\begin{aligned}h(x) &= \sum^\infty_{k=0}\frac {h^k(x_0)} {k!}(x-x_0)^k \\ &= h(x_0)+h^{'}(x_0)(x-x_0)+\frac {h^{''}(x_0)} {2!}(x-x_0)^2+...\end{aligned}
h(x)=k=0∑∞k!hk(x0)(x−x0)k=h(x0)+h′(x0)(x−x0)+2!h′′(x0)(x−x0)2+...
当
x
x
x很接近
x
0
x_0
x0时,有
h
(
x
)
=
h
(
x
0
)
+
h
′
(
x
0
)
(
x
−
x
0
)
h(x) = h(x_0)+h^{'}(x_0)(x-x_0)
h(x)=h(x0)+h′(x0)(x−x0),该式就是函数
h
(
x
)
h(x)
h(x)在
x
=
x
0
x=x_0
x=x0点附近关于
x
x
x的幂函数展开式,也叫泰勒展开式。
多变量泰勒展开式
下面是两个变量的泰勒展开式
回到之前寻找圆圈内最小值部分。基于泰勒展开式,在(a,b)点的红色圆圈范围内,可以将损失函数用泰勒展开式进行简化:
将问题进而简化为下图:
不考虑s,可以看出身下的部分是两个向量
(
Δ
θ
1
,
Δ
θ
2
)
(\Delta\theta_1,\Delta\theta_2)
(Δθ1,Δθ2)和
(
u
,
v
)
(u,v)
(u,v)的内积,那么让它最小,就是和向量
(
u
,
v
)
(u,v)
(u,v)方向相反。
然后将
u
u
u和
v
v
v带入。
发现最后的式子就是梯度下降的式子。但这里用这种方法找到这个式子有个前提,泰勒展开式给的损失函数的估算值是要足够精确的,而这需要红色的圆圈足够小即学习率足够小来保证。所以理论上每次更新参数都想要损失函数减小的话即保证
d
d
d足够小,就需要保证学习率足够小。
所以在实际中,当更新参数的时候,如果学习率没有设好,那么无法保证
d
d
d足够小成立,所以导致做梯度下降的时候,损失函数没有越来越小。上述泰勒展开式是一次项的,如果考虑到二次项(如牛顿法),在实际应用中不是特别好,会涉及到二次微分等,多很多的运算,性价比不好。
梯度下降限制
容易陷入局部极值,还有可能卡在不是极值的驻点,还有可能实际中只是当微分值小于某一数值就停下来了,但这里只是比较平缓的,并不是极值点。