精华内容
下载资源
问答
  • 批标准化(Batch Noemalization)防止过拟合1. 正则化2. Dropout 梯度下降的变化 1. SGD随机梯度下降 每次使用一批(batch)数据进行梯度的计算,而不是计算全部的梯度 2. Momentum SGD的同时,增加动量(momentum...
  • 一些从理论研究和实践经验中总结的防止过拟合的思路,这里以XGBoost为例,其他模型也可以用类似的思路。

    1 概述

    以下是一些从理论研究和实践经验中总结的防止过拟合的思路:
    思路一:控制模型的复杂度
    主要方法:

    限制树的最大深度
    调节正则项系数
    限制叶子节点样本数量

    思路二:增加随机性使得模型对噪声鲁棒
    主要方法:

    控制随机采样比例
    调节学习率

    思路三:通过监控loss防止过拟合发生
    主要方法:

    EarlyStopping

    思路四:缓解样本不均衡问题
    主要方法:

    SMOTE上采样(适用于分类问题)

    以下是这些方法的详细介绍。

    2 具体方法

    2.1 控制模型的复杂度

    2.1.1 限制树的最大深度

    参数名称:max_depth
    我们常用3-10之间的数字。这个值为树的最大深度。这个值是用来控制过拟合的。max_depth越大,模型学习的更加具体。设置为0代表没有限制,范围: [0,∞]

    2.1.2 调节正则项系数

    参数名称:gamma
    gamma()就是正则化项控制叶子节点数量复杂度()的系数
    在节点分裂时,只有分裂后损失函数的值下降了,才会分裂这个节点。gamma指定了节点分裂所需的最小损失函数下降值。 这个参数的值越大,算法越保守。因为gamma值越大的时候,损失函数下降更多才可以分裂节点。所以树生成的时候更不容易分裂节点。范围: [0,∞]
    参数名称:alpha
    权重的L1正则化项。(和Lasso regression类似)。 可以应用在很高维度的情况下,使得算法的速度更快。
    参数名称:lambda
    权重的L2正则化项。(和Ridge regression类似)。这个参数是用来控制XGBoost的正则化部分的。这个参数在减少过拟合上很有帮助。

    2.1.3 限制叶子节点样本数量

    参数名称:min_child_weight
    决定最小叶子节点样本权重和,和GBM的 min_child_leaf 参数类似,但不完全一样。XGBoost的这个参数是最小样本权重的和,而GBM参数是最小样本总数。
    这个参数用于避免过拟合。当它的值较大时,可以避免模型学习到局部的特殊样本。
    但是如果这个值过高,会导致欠拟合。
    这个参数需要使用CV来调整。

    2.2 增加随机性使得模型对噪声鲁棒

    2.2.1 控制随机采样比例

    参数名称:subsample
    和GBM中的subsample参数一模一样。这个参数控制对于每棵树,随机采样的比例。
    减小这个参数的值,算法会更加保守,避免过拟合。但是,如果这个值设置得过小,它可能会导致欠拟合。
    典型值:0.5-1.0。

    2.2.2 调节学习率

    参数名称:eta
    和GBM中的 learning rate 参数类似。
    通过减少每一步的权重,可以提高模型的鲁棒性。
    典型值为0.01-0.2。

    2.3 通过监控loss防止过拟合发生

    2.3.1 EarlyStopping

    XGBoost提供了在指定轮数完成后提前停止训练的功能。
    除了提供用于评估每轮迭代中的评价指标和数据集之外,还需要指定一个阈值,如果连续多轮迭代中模型的效果没有提升,就停止训练。这是通过early_stopping_rounds参数来设置的。

    2.4 缓解样本不均衡问题

    2.4.1 SMOTE上采样(适用于分类问题)

    SMOTE算法的思想是合成新的少数类样本,合成的策略是对每个少数类样本a,从它的最近邻中随机选一个样本b,然后在a、b之间的连线上随机选一点作为新合成的少数类样本。
    分类问题中,当样本不均衡问题出现时,模型对于数据量较少的类会存在过拟合,通过上采样提升占比较小的样本类的比例,可以在一定程度上降低模型的过拟合风险。

    参考链接
    XGBoost中如何防止过拟合
    XGBoost 重要参数(调参使用)
    机器学习系列(12)_XGBoost参数调优完全指南(附Python代码)
    过采样中用到的SMOTE算法

    展开全文
  • 1.什么是过拟合? 参考和引用: https://www.jianshu.com/p/97aafe479fa1 https://blog.csdn.net/heyongluoyao8/article/details/49429629

    1.什么是过拟合?

    对于数据挖掘或者机器学习建立的模型model来说,该模型在训练集上的表现性能较好,而在测试集上效果很差,也就是说该模型的泛化能力差,我们就称之为过拟合(overfitting)。

    2.问题延伸

    2.1 什么是欠拟合(underfitting)?什么是合适拟合
    我们建立的模型实质上就是复杂函数f(x)
    x ----输入----> f(x) ----输出----> y_
    拟合的函数和训练集误差较大,我们称这种情况为欠拟合
    拟合的函数和训练集误差较小,我们称这种情况为合适拟合
    同理,拟合的函数和训练集完美的匹配(训练集误差非常非常的小),我们称之为过拟合。

    欠拟合
    在这里插入图片描述
    合适拟合
    在这里插入图片描述
    过拟合
    在这里插入图片描述
    2.2 如何解决欠拟合?
    欠拟合问题,根本原因是特征维度过少,导致拟合的函数无法满足训练集,误差较大。
    我们可以通过增加特征维度来解决

    3.为什么要解决过拟合问题

    因为我们训练出来的模型一般是用来测试独立的数据集(不在训练集内的),预测未知的结果,过拟合虽然在训练集上效果好,但是在测试集上(实际应用上)效果差,这是我们不想遇到的。同时,在很多问题上,我们无法穷尽所有的状态,不可能将所有情况都包含在训练集上,所以我们要解决过拟合问题。

    为什么机器学习中比较常见过拟合问题?
    因为机器学习算法是为了满足尽可能复杂的任务,其模型的拟合能力一般远远高于问题的复杂度,也就是说,机器学习算法有拟合出正确规则前提下,进一步拟合噪声的能力
    而传统的函数拟合问题(例如机器人系统辨识),一般是经过经验,物理和数学等推导出一个含参模型,模型的复杂度确定了,只需要调整个别参数就可以,这样的模型没有多余的能力拟合噪声。

    4.过拟合产生的原因:

    (1)训练数据量不足
    (2)训练参数的增多
    (3)模型学习能力过于强大(由学习算法和数据内涵共同决定)
    (4)其他…

    5.防止过拟合的方法

    (1)数据扩增,这是解决过拟合最有效的方法,但是对于算法工程师来说,目前的数据是固定不变的,不应该从这里下手收集更多数据,而是找其他方法。

    为什么说数据扩增越多越好?
    因为有这样一个假设,训练的数据和将来测试的数据是独立同分布的(或者近似),因此当前训练的数据越多,模型对未来数据预测越准确。

    数据扩增方法:

    • 从数据源头采集更多数据
    • 复制原有数据+随机噪声
    • 重采样
    • 根据当前数据集估计分布参数,使用该分布产生更多数据等
    • 数据增强
      数据增强,例如,在图像处理中:
      图像平移:学习平以不变的特征
      图像旋转:学习旋转不变的特征,图片目标中的姿态
      图像亮度变化、裁剪、缩放、图像模糊等
      还有mixup(https://www.jianshu.com/p/97aafe479fa1)
      还不是很了解,有待进一步学习。

    (2)选择合适的模型其实过拟合最主要的2个原因是:数据太少+模型太复杂,前面提到数据很难再去收集了,但是我们可以选择合适复杂度的模型来防止过拟合问题。
    对于神经网络来说,我们可以从以下几个方面来限制网络的拟合能力,从而防止过拟合:

    • 网络结构 Architecture(减少网络层、神经元个数):减少网络的层数、神经元数等可以限制网络的拟合能力,优化模型,从而防止过拟合
    • 训练时间 Early stopping(提前终止):对模型进行训练的过程即是对模型的参数进行学习更新的过程,这个参数学习的过程往往会用到一些迭代方法,如梯度下降(Gradient Descent)学习算法。Early stopping便是一种迭代次数截断的方法来防止过拟合的方法,即在模型对训练数据集迭代收敛之前停止迭代来防止过拟合。Early stopping方法的具体做法是,在每一个Epoch结束时(一个Epoch集为对所有的训练数据的一轮遍历)计算validation data的accuracy,当accuracy不再提高时,就停止训练。这种做法很符合直观感受,因为accurary都不再提高了,在继续训练也是无益的,只会提高训练的时间。那么该做法的一个重点便是怎样才认为validation accurary不再提高了呢?并不是说validation accuracy一降下来便认为不再提高了,因为可能经过这个Epoch后,accuracy降低了,但是随后的Epoch又让accuracy又上去了,所以不能根据一两次的连续降低就判断不再提高。一般的做法是,在训练的过程中,记录到目前为止最好的validation accuracy,当连续10次Epoch(或者更多次)没达到最佳accuracy时,则可以认为accuracy不再提高了。此时便可以停止迭代了(Early Stopping)。这种策略也称为“No-improvement-in-n”,n即Epoch的次数,可以根据实际情况取,如10、20、30……
    • 限制权值/权重衰减 weight-decay,也叫**正则化(regularization)**【我们放在后面的大类中讲述】
    • 增加噪声 Noise:
      例如,
      在输入中增加噪声,噪声会随着网络传播,按照权值的平方放大,并传播到输出层,对误差 Cost 产生影响
      (参考:https://www.cnblogs.com/anitinaj/p/10025034.html)
      在权值上增加噪声,在初始化网络的时候,用 0 均值的高斯分布作为初始化。
      对网络的响应加噪声,如在前向传播过程中,让默写神经元的输出变为 binary 或 random。显然,这种有点乱来的做法会打乱网络的训练过程,让训练更慢,但据 Hinton 说,在测试集上效果会有显著提升 (But it does significantly better on the test set!)。

    (3)正则化方法(regularization)
    正则化方法是指在进行目标函数或代价函数优化时,在目标函数或代价函数后面加上一个正则项,一般有L1正则与L2正则等。

    • L1正则
      在这里插入图片描述

    • L2正则
      在这里插入图片描述

    • 总结
      正则项是为了降低模型的复杂度,从而避免模型区过分拟合训练数据,包括噪声与异常点(outliers)。从另一个角度上来讲,正则化即是假设模型参数服从先验概率,即为模型参数添加先验,只是不同的正则化方式的先验分布是不一样的。这样就规定了参数的分布,使得模型的复杂度降低(试想一下,限定条件多了,是不是模型的复杂度降低了呢),这样模型对于噪声与异常点的抗干扰性的能力增强,从而提高模型的泛化能力。还有个解释便是,从贝叶斯学派来看:加了先验,在数据少的时候,先验知识可以防止过拟合;从频率学派来看:正则项限定了参数的取值,从而提高了模型的稳定性,而稳定性强的模型不会过拟合,即控制模型空间。
        另外一个角度,过拟合从直观上理解便是,在对训练数据进行拟合时,需要照顾到每个点,从而使得拟合函数波动性非常大,即方差大。在某些小区间里,函数值的变化性很剧烈,意味着函数在某些小区间里的导数值的绝对值非常大,由于自变量的值在给定的训练数据集中的一定的,因此只有系数足够大,才能保证导数的绝对值足够大。如下图(引用知乎):
      在这里插入图片描述
      另外一个解释,规则化项的引入,在训练(最小化cost)的过程中,当某一维的特征所对应的权重过大时,而此时模型的预测和真实数据之间距离很小,通过规则化项就可以使整体的cost取较大的值,从而,在训练的过程中避免了去选择那些某一维(或几维)特征的权重过大的情况,即过分依赖某一维(或几维)的特征(引用知乎)。
      (以上来自 :https://blog.csdn.net/heyongluoyao8/article/details/49429629

    延伸:L1正则和L2正则的区别?(后面博文讲述)
    L0范数?
    svm中引进松弛变量?

    3)Dropout
    L1、L2正则是通过在代价函数后面加上正则项来防止模型过拟合的。而在神经网络中,有一种方法是通过修改神经网络本身结构来实现的,其名为Dropout。该方法是在对网络进行训练时用一种技巧(trick),对于如下所示的三层人工神经网络:
    在这里插入图片描述
    假设我们要训练上图这个网络,在训练开始时,我们随机地“删除”一些(1/2、1/3等)的隐层单元,视它们为不存在,同时保持输入层与输出层神经元的个数不变,得到如下的网络:

    在这里插入图片描述
    按照BP算法更新上图神经网络中的权值(虚线连接的单元不更新,因为它们被“临时删除”了)。
    以上就是一次迭代的过程,在第二次迭代中,也用同样的方法,只不过这次删除的那一些隐层单元,跟上一次删除掉的肯定是不一样的,因为我们每一次迭代都是“随机”地去删掉一些。第三次、第四次……都是这样,直至训练结束。
    以上就是Dropout。
    它为什么有助于防止过拟合呢
    可以简单地这样解释,运用了dropout的训练过程,相当于训练了很多个只有半数(删除一半,1/2情况)隐层单元的神经网络(后面简称为“半数网络”),每一个这样的半数网络,都可以给出一个分类结果,这些结果有的是正确的,有的是错误的。随着训练的进行,大部分半数网络都可以给出正确的分类结果,那么少数的错误分类结果就不会对最终结果造成大的影响。

    注:还有其他的一些方法,例如,贝叶斯方法,我还在学习中,努力吧。

    参考和引用:

    吴恩达机器学习教学视频,以及一些优质的博文

    https://www.jianshu.com/p/090dc626d00f

    http://blog.sina.com.cn/s/blog_13eacc8800102yk05.html

    https://www.jianshu.com/p/97aafe479fa1

    https://blog.csdn.net/heyongluoyao8/article/details/49429629

    https://www.jianshu.com/p/0a6ac483b950

    https://www.cnblogs.com/anitinaj/p/10025034.html

    https://www.zhihu.com/question/59201590/answer/167392763

    仅用来个人学习和分享,如若侵权,留言立删。

    尊重他人知识产权,不做拿来主义者!

    喜欢的可以关注我哦QAQ,

    你的关注就是我write博文的动力。

    展开全文
  • 文章目录使用最小二乘法做多项式拟合 使用最小二乘法做多项式拟合 # -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt class PolynomialModel(object): def __init__(self, degree): ...

    本文档暂未完成

    多项式+最小二乘法做曲线拟合的数学基础

    记n次多项式的表达式为:
    y = a 0 + a 1 x 1 + a 2 x 2 + . . . + a n x n y = a_0 + a_1x^1 + a_2x^2 + ... + a_nx^n y=a0+a1x1+a2x2+...+anxn
    拟合的目的就是利用已知点求取所有的系数 a i a_i ai

    假设我们有m个点用来做拟合,m个点的坐标为: ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) (x_1, y_1), (x_2, y_2), ... , (x_m, y_m) (x1,y1),(x2,y2),...,(xm,ym)

    上述点的坐标均为已知内容,将其代入多项式可得:
    a 0 + a 1 x 1 + a 2 x 1 2 + . . . + a n x 1 n = y 1 a 0 + a 1 x 2 + a 2 x 2 2 + . . . + a n x 2 n = y 2 . . . a 0 + a 1 x m + a 2 x m 2 + . . . + a n x m n = y m a_0 + a_1{x_1} + a_2{x_1}^2 + ... + a_n{x_1}^n = y_1 \\[2ex] a_0 + a_1{x_2} + a_2{x_2}^2 + ... + a_n{x_2}^n = y_2 \\[2ex] ... \\[2ex] a_0 + a_1{x_m} + a_2{x_m}^2 + ... + a_n{x_m}^n = y_m a0+a1x1+a2x12+...+anx1n=y1a0+a1x2+a2x22+...+anx2n=y2...a0+a1xm+a2xm2+...+anxmn=ym
    将上述方程组写为线性方程形式:
    [ 1 x 1 1 x 1 2 . . . x 1 n 1 x 2 1 x 2 2 . . . x 2 n . . . 1 x m 1 x m 2 . . . x m n ] [ a 0 a 1 . . . a n ] = [ y 1 y 2 . . . y m ] \begin{bmatrix} 1 & {x_1}^1 & {x_1}^2 & ... & {x_1}^n \\ 1 & {x_2}^1 & {x_2}^2 & ... & {x_2}^n \\ && ... \\ 1 & {x_m}^1 & {x_m}^2 & ... & {x_m}^n \end{bmatrix} \begin{bmatrix} a_0 \\ a_1 \\ ... \\ a_n \end{bmatrix} = \begin{bmatrix} y_1 \\ y_2 \\ ... \\ y_m \end{bmatrix} 111x11x21xm1x12x22...xm2.........x1nx2nxmna0a1...an=y1y2...ym
    记:
    X = [ 1 x 1 1 x 1 2 . . . x 1 n 1 x 2 1 x 2 2 . . . x 2 n . . . 1 x m 1 x m 2 . . . x m n ] X = \begin{bmatrix} 1 & {x_1}^1 & {x_1}^2 & ... & {x_1}^n \\ 1 & {x_2}^1 & {x_2}^2 & ... & {x_2}^n \\ && ... \\ 1 & {x_m}^1 & {x_m}^2 & ... & {x_m}^n \end{bmatrix} X=111x11x21xm1x12x22...xm2.........x1nx2nxmn
    A = [ a 0 a 1 . . . a n ] A = \begin{bmatrix} a_0 \\ a_1 \\ ... \\ a_n \end{bmatrix} A=a0a1...an
    Y = [ y 1 y 2 . . . y m ] Y = \begin{bmatrix} y_1 \\ y_2 \\ ... \\ y_m \end{bmatrix} Y=y1y2...ym
    那么有如下推导:
    X A = Y X T X A = X T Y ( X T X ) − 1 X T X A = ( X T X ) − 1 X T Y A = ( X T X ) − 1 X T Y XA=Y \\[2ex] X^TXA=X^TY \\[2ex] (X^TX)^{-1}X^TXA=(X^TX)^{-1}X^TY \\[2ex] A=(X^TX)^{-1}X^TY XA=YXTXA=XTY(XTX)1XTXA=(XTX)1XTYA=(XTX)1XTY
    最后的表达式就是A的最小二乘解,将求解出的A代入到多项式中,就可以得到多项式关于已知点的最小二乘拟合曲线。
    注意,只有当 m > n m>n m>n 时,得到的是最小二乘意义下的解;当 m = n m=n m=n 时得到的是精确解,此时拟合曲线可以精准穿过所有的已知点;当 m < n m<n m<n 时,就不能称之为最小二乘解了(该叫什么我也忘了,好像是最小方差解?),此时尽管多项式本身有更加富足的能力穿过所有的已知点,但是通过上述线性代数求解方法则得不到这样的解。

    程序

    在代码中,将系数 a i a_i ai 称为模型 model,将待拟合的已知点称为训练集train data,将用来测试的点称为测试集test data

    代码中拟合是fit,fit的目的就是通过训练集求出模型(我们这里只是借用了训练的说法,实际上也没啥可训的,求解过程是一步到位。。。)。做预测是predict,predict的目的是针对任意输入,使用训练得到的模型求得输出。

    代码构造了x_train, y_train, x_test, y_test用于测试,并根据这些数据画了一些图片以帮助理解。

    # -*- coding: utf-8 -*-
    import numpy as np
    import matplotlib.pyplot as plt
    
    DEGREE = [2, 4, 6, 8]
    DEGREE_AUG = [2, 4, 6, 8, 10, 12]
    
    
    class PolynomialModel(object):
        def __init__(self, degree):
            self.model = None
            self.degree = degree
    
        def _generate_x_matrix(self, X):
            """
            generate X matrix
    
            Parameters:
            -----------
            X: list or 1-dim numpy array
                x coordinates of points
    
            Returns:
            --------
            x_matrix: 2-dim numpy array
                X matrix
            """
            x_matrix = np.ones([len(X), self.degree + 1])
            for i in range(1, self.degree + 1):
                x_matrix[:, i] = np.power(X, i)
            return x_matrix
    
        def fit(self, X, Y):
            """
            compute model by least square fitting
    
            Parameters:
            -----------
            X, Y: list or 1-dim numpy array
                coordinates of points (x, y)
            """
            Y = np.array(Y)
            x_mat = self._generate_x_matrix(X)
            Y = np.reshape(Y, [Y.shape[0], 1])
            self.model = np.linalg.inv(x_mat.T @ x_mat) @ x_mat.T @ Y
    
        def predict(self, X):
            """
            predict output of input X, using the computed model
    
            Parameters:
            -----------
            X: list or 1-dim numpy array
                x coordinates of points
            """
            x_mat = self._generate_x_matrix(X)
            Y = x_mat @ self.model
            return Y
    
    
    def compute_mse(y1, y2):
        """
        compute mean square error
    
        Parameters:
        -----------
        y1, y2: list or numpy array, with same shape
    
        Returns:
        --------
        mse: mean square error
        """
        y1 = np.array(y1)
        y2 = np.array(y2)
        assert np.product(y1.shape) == np.product(y2.shape)
        y2 = np.reshape(y2, y1.shape)
        mse = np.mean(np.power(y1 - y2, 2))
        return mse
    
    
    def gauss_augmentation(X, Y, aug_num, std):
        """
        augment data using gauss distributed random number
    
        Parameters:
        -----------
        X, Y: list or 1-dim numpy array
            coordinates of points (x, y)
        aug_num: augmentation number for each point
        std: std of random number
    
        Returns:
        --------
        x_aug, y_aug: augmented points
        """
        assert len(X) == len(Y)
        length = len(X)
    
        x_aug = []
        y_aug = []
        for i in range(length):
            x = X[i] + np.random.randn(aug_num) * std
            y = Y[i] + np.random.randn(aug_num) * std
            x_aug.append(x)
            y_aug.append(y)
        x_aug = np.array(x_aug).reshape([-1])
        y_aug = np.array(y_aug).reshape([-1])
        return x_aug, y_aug
    
    
    def get_x_range(x, increment):
        """
        get evenly distributed coordinates by input x, the low limit and high
        limit of coordinates are min(x) and max(x), separately.
    
        Parameters:
        -----------
        x: list or 1-dim numpy array
            x coordinates of points
        increment: float number
            interval of adjacent coordinates
    
        Returns:
        --------
        range: evenly distributed coordinates
        """
        x = np.array(x)
        xmin = np.min(x)
        xmax = np.max(x) + increment
        range = np.arange(xmin, xmax, increment)
        return range
    
    
    def plot_original_dataset(x_train, y_train, x_test, y_test):
        plt.figure(1, figsize=(9, 6))
        plt.plot(x_train, y_train,
                 color='red', marker='o', markersize=6,
                 linewidth=0, label='train_data')
        plt.plot(x_test, y_test,
                 color='green', marker='o', markersize=6,
                 linewidth=0, label='test_data')
        plt.legend()
        plt.savefig('original_dataset.png')
    
    
    def plot_augmented_dataset(x_train, y_train, x_test, y_test, x_aug, y_aug):
        plt.figure(2, figsize=(9, 6))
        plt.plot(x_train, y_train,
                 color='red', marker='o', markersize=6,
                 linewidth=0, label='train_data')
        plt.plot(x_test, y_test,
                 color='green', marker='o', markersize=6,
                 linewidth=0, label='test_data')
        plt.plot(x_aug, y_aug,
                 color='blue', marker='o', markersize=3,
                 linewidth=0, label='augmented_data')
        plt.legend()
        plt.savefig('augmented_dataset.png')
    
    
    def plot_no_augmentation_model(x_train, y_train, x_test, y_test):
        x_range = get_x_range(x_train, 0.1)
        plt.figure(3, figsize=(15, 9))
        for i, degree in enumerate(DEGREE):
            plt.subplot(2, 2, i + 1)
            poly_model = PolynomialModel(degree)
            poly_model.fit(x_train, y_train)
            y_predict = poly_model.predict(x_range)
            plt.plot(x_train, y_train,
                     color='red', marker='o', markersize=6,
                     linewidth=0, label='train_data')
            plt.plot(x_test, y_test,
                     color='green', marker='o', markersize=6,
                     linewidth=0, label='test_data')
            plt.plot(x_range, y_predict, color='black', label='fitted curve')
            plt.title('degree = %d' % degree)
            plt.legend()
        plt.savefig('no_augmentation_model.png')
    
    
    def plot_loss_for_overfitting(x_train, y_train, x_test, y_test):
        plt.figure(4, figsize=(9, 6))
        degrees = get_x_range(DEGREE, 1)
        train_loss = []
        test_loss = []
        for _, degree in enumerate(degrees):
            poly_model = PolynomialModel(degree)
            poly_model.fit(x_train, y_train)
            train_predict = poly_model.predict(x_train)
            test_predict = poly_model.predict(x_test)
            train_mse = compute_mse(y_train, train_predict)
            test_mse = compute_mse(y_test, test_predict)
            train_loss.append(train_mse)
            test_loss.append(test_mse)
        plt.plot(degrees, train_loss, color='red', label='train_loss')
        plt.plot(degrees, test_loss, color='green', label='test_loss')
        plt.xlabel('degree')
        plt.ylabel('mean square error')
        plt.legend()
        plt.savefig('loss_for_overfitting.png')
    
    
    def plot_augmentation_model(x_train, y_train, x_aug, y_aug):
        x_range = get_x_range(x_train, 0.1)
        plt.figure(5, figsize=(15, 15))
        for i, degree in enumerate(DEGREE_AUG):
            plt.subplot(3, 2, i + 1)
            poly_model = PolynomialModel(degree)
            poly_model.fit(x_aug, y_aug)
            y_predict = poly_model.predict(x_range)
            plt.plot(x_train, y_train,
                     color='red', marker='o', markersize=6,
                     linewidth=0, label='train_data')
            plt.plot(x_test, y_test,
                     color='green', marker='o', markersize=6,
                     linewidth=0, label='test_data')
            plt.plot(x_range, y_predict, color='black', label='fitted curve')
            plt.title('degree = %d' % degree)
            plt.legend()
        plt.savefig('augmentation_model.png')
    
    
    def plot_loss_for_augmentation(x_train, y_train, x_test, y_test, x_aug, y_aug):
        plt.figure(6, figsize=(9, 6))
        degrees = get_x_range(DEGREE_AUG, 1)
        train_loss = []
        test_loss = []
        for _, degree in enumerate(degrees):
            poly_model = PolynomialModel(degree)
            poly_model.fit(x_aug, y_aug)
            train_predict = poly_model.predict(x_train)
            test_predict = poly_model.predict(x_test)
            train_mse = compute_mse(y_train, train_predict)
            test_mse = compute_mse(y_test, test_predict)
            train_loss.append(train_mse)
            test_loss.append(test_mse)
        plt.plot(degrees, train_loss, color='red', label='train_loss')
        plt.plot(degrees, test_loss, color='green', label='test_loss')
        plt.xlabel('degree')
        plt.ylabel('mean square error')
        plt.legend()
        plt.savefig('loss_for_augmentation.png')
    
    
    if __name__ == '__main__':
        np.random.seed(1337)
        x_train = [-3.0, -2.1, -0.9, 0.1, 1.2, 2.0, 3]
        y_train = [2.5, 1.2, 1.1, -2.9, -0.7, -3.2, 1.3]
    
        x_test = [-3.0, -2.7, -2.3, -2.0, -1.8, -1.6, -1.3, -1.0, -0.9, -0.6, -0.2,
                  0.1, 0.4, 0.7, 1.0, 1.2, 1.5, 1.8, 2.0, 2.3, 2.5, 2.7, 3.0]
        y_test = [2.4, 2.1, 1.6, 1.1, 1.3, 1.0, 1.2, 1.0, 0.8, -0.2, -1.3, -2.3,
                  -2.7, -2.3, -1.5, -1.2, -1.5, -2.9, -2.5, -1.3, -1.1, -0.4, 1.1]
    
        x_aug, y_aug = gauss_augmentation(x_train, y_train, 20, 0.4)
    
        plot_original_dataset(x_train, y_train, x_test, y_test)
        plot_augmented_dataset(x_train, y_train, x_test, y_test, x_aug, y_aug)
        plot_no_augmentation_model(x_train, y_train, x_test, y_test)
        plot_loss_for_overfitting(x_train, y_train, x_test, y_test)
        plot_augmentation_model(x_train, y_train, x_aug, y_aug)
        plot_loss_for_augmentation(x_train, y_train, x_test, y_test, x_aug, y_aug)
    
    

    解释

    训练和测试数据

    如图
    在这里插入图片描述

    使用原始训练数据做曲线拟合

    如图,随着多项式的次数(degree)从2变到6,拟合曲线对训练数据(红色点)的逼近程度越来越高,但是对测试数据的逼近程度却不是如此,特别是degree从4变到6以后,拟合曲线与测试数据的逼近程度反而增大,这就是过拟合现象。

    当degree等于8时曲线反而不能完全穿过训练数据,关于此我们前面已有解释。
    在这里插入图片描述

    过拟合现象的loss表现

    随着模型变大,测试集loss反而开始升高,这就是典型的过拟合现象在loss上的表现。
    在这里插入图片描述

    数据增强

    数据增强方式是以训练集中的各个点为基准加上高斯分布的随机数,在其周围构造出一些随机点,这些随机点就是增强后的数据。此例中针对每个训练集中的点构造了20个增强的数据点。
    在这里插入图片描述

    使用增强后的数据做曲线拟合

    从图中可以看到,随着模型增大,拟合曲线不仅对训练集的逼近程度越来越高,对测试集的逼近程度也越来越高。这就是数据增强的威力:防止过拟合,提升在测试集上的效果;另外关键是,我们并没有额外地付出数据采集成本。
    在这里插入图片描述

    数据增强后的loss表现

    从loss上也能看出数据增强带来明显的效果改善,随着模型增大,不仅训练集loss在降低,测试集loss也在不断降低。
    在这里插入图片描述

    展开全文
  • 过拟合以及如何防止过拟合

    千次阅读 2019-02-22 21:20:43
    什么是过拟合 过拟合即模型在训练过程中对模型参数进行拟合的过程中,由于训练数据集存在抽样误差(噪声),复杂的模型在训练的过程中会将抽样误差也一同进行拟合。这就导致训练好的模型在训练集上的表现很好,在...

    什么是过拟合

    过拟合即模型在训练过程中对模型参数进行拟合的过程中,由于训练数据集存在抽样误差(噪声),复杂的模型在训练的过程中会将抽样误差也一同进行拟合。这就导致训练好的模型在训练集上的表现很好,在测试集上的表现很差的原因。
    导致过拟合的主要原因有两个:数据量太少和模型过于复杂
    因为机器学习算法在拟合出正确的规则后,具有进一步拟合噪声的能力,因此,模型在训练的过程中极有可能会发生过拟合。过拟合会大大降低模型的鲁棒性,因此在实际应用的过程中我们要尽可能的防止模型发生过拟合现象。

    如何防止过拟合

    关于如何防止过拟合先放一张图
    防止过拟合的方法
    防止过拟合可以从数据和模型这两个角度进行琢磨。

    增加数据量

    马云曾经说过(被说过):数据是二十一世纪的石油。不管这个命题是否为真,我们都能意识到数据对当今社会的重要性。的确,增加数据也是解决过拟合问题最为有效的手段。数据量越大,抽样误差就越小,模型拟合的误差就越小,模型的泛化性能就越好。

    简化模型

    如果我们已经有了足够多的训练数据,但是我们训练的模型还是会发生过拟合的话,那就有可能是我们的模型过于复杂了,导致模型对一些数据中的一些噪声都进行了和好的拟合。模型只是对部分数据产生过拟合,我们可以在保证模型能够正确的拟合出数据中的规则的同时,又能适当的降低模型的复杂度,减少模型对抽样误差的拟合程度。适当的降低模型的复杂度,不仅能很好降低模型的过拟合程度,同时也能提高模型的训练速度以及运行速度。
    降低模型的复杂度可以提前结束模型的训练过程(early stopping)。通常情况下,模型在训练的过程中会优先拟合数据的正确的规则,拟合出正确的规则之后,才会拟合数据中的误差。所以在训练的过程中就存在一个转折点,在这个转折点之前,模型一致都处于欠拟合状态,在这个转折点之后,模型就开始过拟合。所以在训练的过程中我们可以通过迭代不同的训练周期,从而观察这个转折点的位置,然后在这个转折点结束训练,这样也可以很好的防止模型发生过拟合。
    对于线性模型如LR而言,可以在损失函数中引入正则化项来降低模型的复杂度,从而有效的防止模型发生过拟合现象。正则化项分为L1正则(L1范数)和L2正则(L2范数)。
    优化目标:
    在这里插入图片描述
    引入L1正则项:
    在这里插入图片描述
    引入L2正则项
    在这里插入图片描述
    加入正则化的目的就是为了使得模型在训练的时候,既要降低模型的训练误差,又要使得参数的范数尽可能的小,也就是降低模型的复杂度。关于引入L1正则化项和L2正则化项为什么能够防止模型发生过拟合可以参照这两篇知乎回答:
    https://zhuanlan.zhihu.com/p/35356992
    https://www.zhihu.com/question/20924039/answer/131421690
    对于深度学习模型而言,可以在模型中引入dropout层防止模型发生过拟合,提高模型的泛化性能。
    所谓dropout, 就是在模型的训练过程中,在模型的前向传输过程中,当传输至dropout层时,会随机的删除一定比例(dropout中的参数)的隐藏神经元,输入和输出神经元保持不变,如下图所示:
    在这里插入图片描述
    然后再根据训练误差利用反向传播算法更新网格中未隐藏的神经元参数的大小。更新完为隐藏的参数后,再恢复之前被隐藏的神经元。这就导致训练一次后,只更新未被隐藏神经元参数,被隐藏的神经元的参数则保持不变。
    继续重复上述套路,随机更新模型中的参数。
    至于dropout为什么能有效的防止模型发生过拟合,其一是是因为引入dropout层进行训练后,相当于训练了了多个模型,最后训练的结果也就相当于取多个模型的平均值,类似于bagging;其二是dropoout通过随机更新参数,减少了不同特征之间的宫适应性,从而能有效提高模型的泛化性能。
    这是对近期复习过拟合以及如何防止过拟合做的一个简单的学习总结。其中难免会有一些错误,希望各位大佬批评指正。

    展开全文
  • 什么是过拟合 过拟合这个意思其实就是提高泛化能力,我们在...看了很多关于L1和L2的文章,上来就是各种数学推导,还有不明所以的图片,L1让参数变为0,L2让参数趋向于0,这怎么就可以提高泛化能力,防止过拟合呢?推...
  • 一、出现过拟合的原因 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在training data上的error渐渐减小,但是在验证...
  • 防止过拟合的方法

    2021-06-12 15:40:11
    深度学习网络中需要训练的参数较多,需要更多的数据量才能获得稳定的训练结果,增加训练样本可以有效防止过拟合,数据不足的时候可以使用数据增强技术,例如在图像方面使用数据增强平移图像的位置、姿态、尺度、明暗...
  • 1.2 如何防止过拟合 防止过拟合的方法有4种: 1)增加训练集数据; 该方式是从数据入手,将更多的数据参与到模型的训练中,这是最有效的方法,这样可以让模型学习到更多更有效的特征,降低噪声对模型的影响。 但是...
  • 防止过拟合(一):正则化

    千次阅读 多人点赞 2020-03-14 01:04:04
    深度学习笔记:欠拟合过拟合 防止过拟合(二):Dropout 防止过拟合(三):数据增强 前言 通过设计不同层数、大小的网络模型,可以为优化算法提供初始的函数假设空间(或者所示网络容量)。但是随着网络参数的...
  • 度量泛化能力的好坏,最直观的表现就是模型的过拟合(overfitting)和欠拟合(underfitting)。过拟合和欠拟合是用于描述模型在训练过程中的两种状态。一般来说,训练过程会是如下所示的一个曲线图。训练刚开...
  • 正则化防止过拟合

    2020-10-03 08:37:11
    正则化主要作用就是通过减小模型的复杂度来防止过拟合,提高泛化能力。 为了更好的了解过拟合以及为后面做铺垫,还是先看一个吴恩达机器学习系列课程中一个线性回归来预测房价的例子吧 Size表示房子的大小,Price...
  • 度量泛化能力的好坏,最直观的表现就是模型的过拟合(overfitting)和欠拟合(underfitting)。过拟合和欠拟合是用于描述模型在训练过程中的两种状态。一般来说,训练过程会是如下所示的一个曲线图 一、什么是欠拟合...
  • 正则化方法:防止过拟合,提高泛化能力 转载文章:https://www.cnblogs.com/alexanderkun/p/6922428.html 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。其直观的表现如下图所示,...
  • 为什么L2范数能防止过拟合

    千次阅读 2020-08-30 20:40:23
    都在说加正则化项能防止过拟合,可是为什么它可以防止过拟合呢呢         说这个东西之前我们先讲一下什么是 L2 范数,以及什么是过拟合 L2范数     &...
  • 1、过拟合       过拟合有回归过拟合和分类过拟合。 回归过拟合: 分类过拟合: ...过拟合虽然会提高训练集的准确率,但是会...2、防止过拟合的方式 2.1 增大数据集       ...
  • xgboost中用来防止过拟合的措施

    千次阅读 2020-03-17 23:00:56
    1、损失函数中加入了正则化项,相当于预剪枝 2、shrinkage 即在迭代中为树的叶子结点乘以一个权重衰减稀疏,以削弱每棵树的影响力,为后面的树留下提升空间3 3、列采样,即特征采样。 有按层采样和建树之前随机采样...
  • 防止过拟合

    2015-09-13 17:34:40
    在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。 为了防止overfitting,可以用的方法有很多,下文就将以此展开。有一个概念需要先说明,在机器学习算法中,我们常常将原始数据集...
  • 神经网络,常见防止模型过拟合的几种方式: 1、数据增强,合适的数据增强方式可以很大程度提高模型鲁棒性 2、使用正则化项 可以参考: https://segmentfault.com/a/1190000018378231 keras正则化 3、使用dropout 4、...
  • 本文将主要来谈谈神经网络中的过拟合问题以及如何避免过拟合。 什么是过拟合 任何机器学习模型,包括神经网络都可能存在过拟合(Overfit)问题。下面用一张图来说明: 上图中,分别用三个模型来拟合实际...
  • 本文转载自: 一只鸟的天空,http://blog.csdn.net/heyongluoyao8/article/details/49429629 ...———————————————————————————————————————————— 过拟合 我们...
  • DropOut是神经网络中一种防止过拟合的手段,其主要的原理是在每一次的训练过程中 放置几个神经元,不对进行训练,他的参数不会进行更新,但是在实际测试训练集的时候.所有的神经元都会被用到, 正则化 正则化同样是一种...
  • 点击 机器学习算法与Python学习 ,选择加星标精彩内容不迷路选自Medium,作者:Mahitha Singirikonda机器之心编译在机器学习中,过拟合(overfitting)...
  • 防止过拟合、dropout理解

    千次阅读 2018-10-18 10:21:58
    获得了类似多个模型ensemble的效果,避免过拟合 2)dropout其实也是一个data augmentation的过程,它导致了稀疏性,使得局部数据簇差异性更加明显,这也是其能够防止过拟合的原因。 dropout率的选择: 经过交叉...
  • 防止过拟合方法

    千次阅读 2018-06-21 18:59:13
    正则化及Dropout都能很好的防止过拟合。 正则化   P-范数公式 ∥ x ∥ p = ( ∑ i = 0 ∞ | x p i | ) 1 p ‖x‖p=(∑i=0∞|xip|)1p L1范数: λ ∥ x ∥ 1 λ‖x‖1 L2范数: λ 2 ∥ x ∥ 2 λ2‖x‖2 参考:...
  • 文章目录/欠拟合定义防止过拟合的措施防止拟合的措施参考文献 /欠拟合定义 过拟合是指模型对于训练数据拟合当的情况,反映到评估指标上,就是模型在训练集上的表现很好,但在测试集和新数据上的表现较差。...
  • pytorch使用dropout防止过拟合

    千次阅读 2020-04-07 10:33:16
    但是,神经网络倾向于在训练数据上表现得太好,并且无法将其推广到以前从未见的数据,这称为过拟合,它会削弱推理性能。 为了在训练过程中发现过拟合,我们不在训练集中测试,而在验证集测试性能。 我们在训练...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 43,094
精华内容 17,237
关键字:

防止过拟合