任务目录:
- 理解偏差和方差
- 学习误差为什么是偏差和方差而产生的,并且推导数学公式
- 过拟合,欠拟合,分别对应bias和variance什么情况
- 学习鞍点,复习上次任务学习的全局最优和局部最优
- 解决办法有哪些
- 梯度下降
- 学习Mini-Batch与SGD
- 学习Batch与Mini-Batch,SGD梯度下降的区别
- 如何根据样本大小选择哪个梯度下降(批量梯度下降,Mini-Batch)
- 写出SGD和Mini-Batch的代码
- 学习交叉验证
- 学习归一化
- 学习回归模型评价指标
更多的对梯度下降优化将在《李宏毅深度学习》中会有学习任务介绍(指数加权平均,动量梯度下降等)
1 偏差与方差
偏差(Bias)就是样例实际值与预测值的差值
方差(variance)就是样例之间的差别程度
如图所示,bias是样例与靶心的差值,variance是个样例与样例均值的差异
1.1 学习误差为什么是偏差和方差而产生的,并且推导数学公式
符号表示:
蓝色部分是对上面对应的等价替换, 然后对其展开后, 红色部分刚好为 0.
由此可得:
1.2 过拟合,欠拟合,分别对应bias和variance什么情况
过拟合是对应bias较小,variance偏大,模型过于拟合数据,反而对于测试集的错误率较高
欠拟合是指bias较大,variance较小,模型没有很好的拟合数据
1.3 鞍点,复习全局最优和局部最优
在鞍点附近,基于梯度的优化算法(几乎目前所有的实际使用的优化算法都是基于梯度的)会遇到较为严重的问题:
鞍点处的梯度为零,鞍点通常被相同误差值的平面所包围(这个平面又叫Plateaus,Plateaus是梯度接近于零的平缓区域,会降低神经网络学习速度),在高维的情形,这个鞍点附近的平坦区域范围可能非常大,这使得SGD算法很难脱离区域,即可能会长时间卡在该点附近(因为梯度在所有维度上接近于零)。
我对鞍点的理解就是在一个方向上是极大值,另一方向是极小值的点,就是马鞍的中间那个点。
1.4 解决办法有哪些
对于偏差:
添加特征、试着复杂模型
对于方差:
试着增加数据、正则化
2 梯度下降
2.1 Mini-Batch与SGD
2.1.1 Stochastic Gradient Descent (SGD)
随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况,那么可能只用其中部分的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。缺点是SGD的噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。所以虽然训练速度快,但是准确度下降,并不是全局最优。虽然包含一定的随机性,但是从期望上来看,它是等于正确的导数的。
梯度更新规则:
和 BGD 的一次用所有数据计算梯度相比,SGD 每次更新时对每个样本进行梯度更新,对于很大的数据集来说,可能会有相似的样本,这样 BGD 在计算梯度时会出现冗余,而 SGD 一次只进行一次更新,就没有冗余,而且比较快,并且可以新增样本。
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
2.1.2 Mini-Batch Gradient Descent (MBGD)
梯度更新规则:
MBGD 每一次利用一小批样本,即 n 个样本进行计算,这样它可以降低参数更新时的方差,收敛更稳定,另一方面可以充分地利用深度学习库中高度优化的矩阵操作来进行更有效的梯度计算。
和 SGD 的区别是每一次循环不是作用于每个样本,而是具有 n 个样本的批次。
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
超参数设定值: n 一般取值在 50~256
缺点:(两大缺点)
- 不过 Mini-batch gradient descent 不能保证很好的收敛性,learning rate 如果选择的太小,收敛速度会很慢,如果太大,loss function 就会在极小值处不停地震荡甚至偏离。(有一种措施是先设定大一点的学习率,当两次迭代之间的变化低于某个阈值后,就减小 learning rate,不过这个阈值的设定需要提前写好,这样的话就不能够适应数据集的特点。)对于非凸函数,还要避免陷于局部极小值处,或者鞍点处,因为鞍点周围的error是一样的,所有维度的梯度都接近于0,SGD 很容易被困在这里。(会在鞍点或者局部最小点震荡跳动,因为在此点处,如果是训练集全集带入即BGD,则优化会停止不动,如果是mini-batch或者SGD,每次找到的梯度都是不同的,就会发生震荡,来回跳动。)
- SGD对所有参数更新时应用同样的 learning rate,如果我们的数据是稀疏的,我们更希望对出现频率低的特征进行大一点的更新。LR会随着更新的次数逐渐变小。
2.2 如何根据样本大小选择哪个梯度下降(批量梯度下降,Mini-Batch)
如果训练集较小,一般小于2000的,就直接使用Batch gradient descent
当样本非常大或数据源源不断到来时,建议使用mini-Batch.一般Mini Batch gradient descent的m取2的幂次时能够充分利用矩阵运算操作,所以可以在2的幂次中挑选最优的取值,例如32、64、128、256等。
如果样本量比较小,采用批量梯度下降算法。如果样本太大,或者在线算法,使用随机梯度下降算法。在实际的一般情况下,采用小批量梯度下降算法。
补充:
如果数据是稀疏的,就用自适用方法,即 Adagrad, Adadelta, RMSprop, Adam。
RMSprop, Adadelta, Adam 在很多情况下的效果是相似的。
Adam 就是在 RMSprop 的基础上加了 bias-correction 和 momentum,
随着梯度变的稀疏,Adam 比 RMSprop 效果会好。
整体来讲,Adam 是最好的选择。
很多论文里都会用 SGD,没有 momentum 等。SGD 虽然能达到极小值,但是比其它算法用的时间长,而且可能会被困在鞍点。
如果需要更快的收敛,或者是训练更深更复杂的神经网络,需要用一种自适应的算法。
2.3 交叉验证
交叉验证是在机器学习建立模型和验证模型参数时常用的办法。交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏。在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓“交叉”。
交叉验证分为下面三种:
第一种是简单交叉验证,所谓的简单,是和其他交叉验证方法相对而言的。首先,我们随机的将样本数据分为两部分(比如: 70%的训练集,30%的测试集),然后用训练集来训练模型,在测试集上验证模型及参数。接着,我们再把样本打乱,重新选择训练集和测试集,继续训练数据和检验模型。最后我们选择损失函数评估最优的模型和参数。
第二种是S折交叉验证(S-Folder Cross Validation)。和第一种方法不同,S折交叉验证会把样本数据随机的分成S份,每次随机的选择S-1份作为训练集,剩下的1份做测试集。当这一轮完成后,重新随机选择S-1份来训练数据。若干轮(小于S)之后,选择损失函数评估最优的模型和参数。
第三种是留一交叉验证(Leave-one-out Cross Validation),它是第二种情况的特例,此时S等于样本数N,这样对于N个样本,每次选择N-1个样本来训练数据,留一个样本来验证模型预测的好坏。此方法主要用于样本量非常少的情况,比如对于普通适中问题,N小于50时,我一般采用留一交叉验证。
2.4 归一化
一、定义
数据标准化(Normalization),也称为归一化,归一化就是将你需要处理的数据在通过某种算法经过处理后,限制将其限定在你需要的一定的范围内。
数据标准化处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要对数据进行归一化处理,解决数据指标之间的可比性问题。
二、优点
如上面所说,数据归一化的目的就是为了把不同来源的数据统一到同一数量级(一个参考坐标系)下,这样使得比较起来有意义。归一化使得后面数据的处理更为方便,它有两大优点:(1)归一化可以加快梯度下降求最优解的速度,(2)归一化有可能提高精度。
2.5 回归模型评价指标
用真实值-预测值 然后平方之后求和平均。
参考资料:
百度百科
https://blog.csdn.net/baidu_27643275/article/details/79250537
https://blog.csdn.net/winds_lyh/article/details/90243291
https://www.cnblogs.com/pinard/p/5992719.