美文网首页
深度学习_模型选择与拟合问题

深度学习_模型选择与拟合问题

作者: VictorHong | 来源:发表于2019-08-02 15:48 被阅读0次

模型选择

首先我们需要考虑误差!

首先在机器学习模型中误差有如下两种:

  1. 训练误差
  2. 泛化误差

训练误差指模型在训练数据集上表现出的误差

泛化误差指模型在任意一个测试数据样本上表现出的误差的期望

而在机器学习模型中应该关注降低泛化误差

在机器学习中,通常需要评估若干候选模型的表现并从中选择模型。这一过程称为模型选择(model selection)。可供选择的候选模型可以是有着不同超参数的同类模型。以多层感知机为例,我们可以选择隐藏层的个数,以及每个隐藏层中隐藏单元个数和激活函数。为了得到有效的模型,我们通常要在模型选择上下一番功夫。下面,我们来描述模型选择中经常使用的验证数据集(validation data set)。

在机器学习中,我们有两个数据集,一个是训练集,一个是测试集。严格意义讲,测试集只能使用一次。所以我们不能够根据测试集的数据选择模型,调参等。我们也无法从训练误差估计泛化误差,
因此我们也不能够更具训练集选择模型。那么既不能从测试集选择模型,又不能从训练集选择模型,那应该怎么办呢?

K折交叉验证

一种改善的方法是 K 折交叉验证( K -fold cross-validation ).
在 K 折交叉验证中,我们把原始训练数据集分割成 K 个不重合的子数据集,然后我们做 K 次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他 K−1 个子数据集来训练模型。在这 K 次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这 K 次训练误差和验证误差分别求平均。

欠拟合和过拟合

模型训练中经常出现的两类典型问题:

  1. 一类是模型无法得到较低的训练误差,我们将这一现象称作欠拟合(underfitting)
  2. 另一类是模型的训练误差远小于它在测试数据集上的误差,我们称该现象为过拟合(overfitting)

模型复杂度

以多项式函数拟合为例,目标是寻找一个K阶多项式函数

\hat{y} = b + \sum_{k=1}^K x^k w_k

来近似y。在上式中,wk是模型的权重参数,b是偏差参数。与线性回归相同,多项式函数拟合也使用平方损失函数。特别地,一阶多项式函数拟合又叫线性函数拟合。

因为高阶多项式函数模型参数更多,模型函数的选择空间更大,所以高阶多项式函数比低阶多项式函数的复杂度更高。因此,高阶多项式函数比低阶多项式函数更容易在相同的训练数据集上得到更低的训练误差。

给定训练数据集,模型复杂度和误差之间的关系通常如图3.4所示。给定训练数据集,如果模型的复杂度过低,很容易出现欠拟合;如果模型复杂度过高,很容易出现过拟合。应对欠拟合和过拟合的一个办法是针对数据集选择合适复杂度的模型。

图 3.4 模型复杂度对欠拟合和过拟合的影响

训练数据集大小

影响欠拟合和过拟合的另一个重要因素是训练数据集的大小。一般来说,如果训练数据集中样本数过少,特别是比模型参数数量(按元素计)更少时,过拟合更容易发生。此外,泛化误差不会随训练数据集里样本数量增加而增大。
因此,在计算资源允许的范围之内,我们通常希望训练数据集大一些,特别是在模型复杂度较高时,例如层数较多的深度学习模型。

多项式函数拟合实验

导入必要的包

import d2lzh as d2l
from mxnet import autograd,nd,gluon
from mxnet.gluon import data as gdata,loss as gloss,nn

生成数据集

我们将生成一个人工数据集。在训练数据集和测试数据集中,给定样本特征 x ,我们使用如下的三阶多项式函数来生成该样本的标签:

y = 1.2x - 3.4x^2 + 5.6x^3 + 5 + \epsilon,

其中噪声项 ϵ 服从均值为0、标准差为0.1的正态分布。训练数据集和测试数据集的样本数都设为100。

#设置训练集和测试集的样本数都为100,再设置w与b
train_n,test_n,true_w,true_b = 100,100,[1.8,-9.6,3.14],2.8
#随机生成特征值
features = nd.random.normal(shape=(train_n+test_n,1))
poly_features = nd.concat(features,nd.power(features,2),nd.power(features,3))

labels = poly_features[:,0]*true_w[0] + poly_features[:,1]*true_w[1] + poly_features[:,2]*true_w[2] + true_b
labels += nd.random.normal(scale=0.01,shape=labels.shape)

看一看生成的数据集的前两个样本。

features[:2],poly_features[:2],labels[:2]
(
 [[-1.680917 ]
  [-2.6438675]]
 <NDArray 2x1 @cpu(0)>, 
 [[ -1.680917    2.8254821  -4.749401 ]
  [ -2.6438675   6.9900355 -18.480726 ]]
 <NDArray 2x3 @cpu(0)>, 
 [ -42.26117 -127.08934]
 <NDArray 2 @cpu(0)>)

定义 训练 测试 模型

#首先定义作图函数semilogy,y轴用了对数尺度
def semilogy(x_vals,y_vals,x_label,y_label,x2_vals=None,y2_vals=None,legend=None,figsize=(3.5,2.5)):
    d2l.set_figsize(figsize)
    d2l.plt.xlabel(x_label)
    d2l.plt.ylabel(y_label)
    d2l.plt.semilogy(x_vals,y_vals)
    if x2_vals and y2_vals:
        d2l.plt.semilogy(x2_vals,y2_vals)
        d2l.plt.legend(legend)
num_epochs, loss = 100, gloss.L2Loss()

def fit_and_plot(train_features, test_features, train_labels, test_labels):
    net = nn.Sequential()
    net.add(nn.Dense(1))
    net.initialize()
    batch_size = min(10, train_labels.shape[0])
    train_iter = gdata.DataLoader(gdata.ArrayDataset(
        train_features, train_labels), batch_size, shuffle=True)
    trainer = gluon.Trainer(net.collect_params(), 'sgd',
                            {'learning_rate': 0.01})
    train_ls, test_ls = [], []
    for _ in range(num_epochs):
        for X, y in train_iter:
            with autograd.record():
                l = loss(net(X), y)
            l.backward()
            trainer.step(batch_size)
        train_ls.append(loss(net(train_features),
                             train_labels).mean().asscalar())
        test_ls.append(loss(net(test_features),
                            test_labels).mean().asscalar())
    print('final epoch: train loss', train_ls[-1], 'test loss', test_ls[-1])
    semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',
             range(1, num_epochs + 1), test_ls, ['train', 'test'])
    print('weight:', net[0].weight.data().asnumpy(),
          '\nbias:', net[0].bias.data().asnumpy())

三阶多项式函数拟合(正常)

fit_and_plot(poly_features[:train_n, :], poly_features[train_n:, :],
             labels[:train_n], labels[train_n:])
final epoch: train loss 0.002419042 test loss 0.0032950742
weight: [[ 1.6981984 -9.568022   3.1638238]] 
bias: [2.7530537]

线性函数拟合(欠拟合)

fit_and_plot(features[:train_n, :], features[train_n:, :],
             labels[:train_n], labels[train_n:])
final epoch: train loss 219.35103 test loss 108.207634
weight: [[14.531894]] 
bias: [-9.7385435]

训练样本不足(过拟合)

fit_and_plot(poly_features[:2, :], poly_features[train_n:, :],
             labels[:2], labels[train_n:])
final epoch: train loss 1.0184645e+16 test loss 596942100000000.0
weight: [[-1407827.5  3514087.  -8941110. ]] 
bias: [579296.6]

相关文章

  • 深度学习_模型选择与拟合问题

    模型选择 首先我们需要考虑误差! 首先在机器学习模型中误差有如下两种: 训练误差 泛化误差 训练误差指模型在训练数...

  • 过拟合问题的理解(Explore overfitting and

    深度学习或者说神经网络中最让人头疼的问题也是最常见的问题,便是过拟合和欠拟合问题。过拟合体现在训练数据集中模型表现...

  • 2018-11-02 模型选择学习笔记

    占坑,完善中。。。。 模型的选择就是为了解决过拟合和欠拟合问题 过拟合: 解决简单问题用了过于复杂的模型, 机关枪...

  • 机器学习中的L0、L1、L2正则化

    过拟合 过拟合问题在机器学习中是一个经常遇到的问题,所谓过拟合,即模型过度地拟合了训练数据,从而导致模型在训练数据...

  • 如何处理欠拟合、过拟合?

    在我们机器学习和深度学习的训练过程中,经常会出现过拟合和欠拟合的现象。训练一开始,模型通常会欠拟合,所以会对模型进...

  • 机器学习的特征选择方法总结

    特征选择是机器学习非常重要的一环。之所以要考虑特征选择,是因为机器学习经常面临过拟合的问题。过拟合的表现是模型参数...

  • 进化模型的选择

    进化模型选择原理 *选择模型涉及的两个主要问题是:采用什么标准判断模型与数据拟合的好坏的问题,二是采用什么方法计算...

  • 机器学习应用建议(二)

    偏差和方差的判别 高偏差和高方差本质上为学习模型的欠拟合和过拟合问题。 对于高偏差和高方差问题,即学习模型的欠拟合...

  • [Deep-Learning-with-Python]机器学习基

    机器学习类型 机器学习模型评估步骤 深度学习数据准备 特征工程 过拟合 解决机器学习问题的一般性流程 机器学习四分...

  • 2018-11-24机器学习第三天

    模型选择 1 模型的错误类型 : 欠拟合(过度简化了要解决的问题 又称为高偏差模型) 和 过拟合(过度复杂化了要解...

网友评论

      本文标题:深度学习_模型选择与拟合问题

      本文链接:https://www.haomeiwen.com/subject/wdildctx.html