前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >动手学深度学习(二)——欠拟合和过拟合

动手学深度学习(二)——欠拟合和过拟合

作者头像
Tyan
发布2019-05-25 23:35:40
5290
发布2019-05-25 23:35:40
举报
文章被收录于专栏:SnailTyanSnailTyan

版权声明:博客文章都是作者辛苦整理的,转载请注明出处,谢谢! https://cloud.tencent.com/developer/article/1434125

文章作者:Tyan

博客:noahsnail.com | CSDN | 简书

注:本文为李沐大神的《动手学深度学习》的课程笔记!

欠拟合和过拟合

训练误差和泛化误差

机器学习模型在训练数据集上表现出的误差叫做训练误差,在任意一个测试数据样本上表现出的误差的期望值叫做泛化误差。

统计学习理论的一个假设是:训练数据集和测试数据集里的每一个数据样本都是从同一个概率分布中相互独立地生成出的(独立同分布假设)。

一个重要结论是:训练误差的降低不一定意味着泛化误差的降低。机器学习既需要降低训练误差,又需要降低泛化误差。

欠拟合和过拟合

  • 欠拟合:机器学习模型无法得到较低训练误差。
  • 过拟合:机器学习模型的训练误差远小于其在测试数据集上的误差。

模型的选择

模型拟合能力和误差之间的关系如下图:

训练数据集的大小

一般来说,如果训练数据集过小,特别是比模型参数数量更小时,过拟合更容易发生。除此之外,泛化误差不会随训练数据集里样本数量增加而增大。

多项式拟合

给定一个标量数据点集合x和对应的标量目标值y,多项式拟合的目标是找一个K阶多项式,其由向量w和位移b组成,来最好地近似每个样本xy。用数学符号来表示就是我们将学wb来预测

ŷ =b+∑k=1Kxkwky^=b+∑k=1Kxkwk

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

并以平方误差为损失函数,一阶多项式拟合又叫线性拟合。

创建数据集

使用二阶多项式来生成每一个数据样本,y=1.2x−3.4x2+5.6x3+5.0+noisey=1.2x−3.4x2+5.6x3+5.0+noisey=1.2x−3.4x^2+5.6x^3+5.0+noise,噪音服从均值0和标准差为0.1的正态分布。

代码语言:javascript
复制
# 导入mxnet
import mxnet as mx

# 设置随机种子
mx.random.seed(2)

from mxnet import gluon
from mxnet import ndarray as nd
from mxnet import autograd
代码语言:javascript
复制
# 训练数据数量
num_train = 100
# 测试数据数量
num_test = 100
# 多项式权重
true_w = [1.2, -3.4, 5.6]
# 多项式偏置
true_b = 5.0
代码语言:javascript
复制
# 生成随机数据x
x = nd.random.normal(shape=(num_train + num_test, 1))
# 计算x的多项式值
X = nd.concat(x, nd.power(x, 2), nd.power(x, 3))
# 计算y
y = true_w[0] * X[:, 0] + true_w[1] * X[:, 1] + true_w[2] * X[:, 2] + true_b
# 查看数据
('x:', x[:5], 'X:', X[:5], 'y:', y[:5])
代码语言:javascript
复制
(200L,)

定义训练和测试步骤

代码语言:javascript
复制
%matplotlib inline
import matplotlib as mpl
mpl.rcParams['figure.dpi']= 120
import matplotlib.pyplot as plt

# 定义训练过程
def train(X_train, X_test, y_train, y_test):
    # 定义线性回归模型
    net = gluon.nn.Sequential()
    with net.name_scope():
        net.add(gluon.nn.Dense(1))
    # 权重初始化
    net.initialize()
    # 学习率
    learning_rate = 0.01
    # 迭代周期
    epochs = 100
    # 训练的批数据大小
    batch_size = min(10, y_train.shape[0])
    # 创建训练数据集
    dataset_train = gluon.data.ArrayDataset(X_train, y_train)
    # 读取数据
    data_iter_train = gluon.data.DataLoader(dataset_train, batch_size, shuffle=True)
    # 训练方法SGD
    trainer = gluon.Trainer(net.collect_params(), 'sgd', {'learning_rate': learning_rate})
    # 定义损失函数
    square_loss = gluon.loss.L2Loss()
    # 训练损失
    train_loss = []
    # 测试损失
    test_loss = []
    # 进行训练
    for e in range(epochs):
        for data, label in data_iter_train:
            with autograd.record():
                # 进行预测
                output = net(data)
                # 计算预测值与实际值之间的损失
                loss = square_loss(output, label)
            # 损失进行反向传播
            loss.backward()
            # 更新权重
            trainer.step(batch_size)
        # 保存训练损失
        train_loss.append(square_loss(net(X_train), y_train).mean().asscalar())
        # 保存测试损失
        test_loss.append(square_loss(net(X_test), y_test).mean().asscalar())
    # 绘制损失
    plt.plot(train_loss)
    plt.plot(test_loss)
    plt.legend(['train','test'])
    plt.show()
    return ('learned weight', net[0].weight.data(), 'learned bias', net[0].bias.data())

三阶多项式拟合(正常)

代码语言:javascript
复制
train(X[:num_train, :], X[num_train:, :], y[:num_train], y[num_train:])
代码语言:javascript
复制
('learned weight', 
 [[ 1.22117233 -3.39606118  5.59531116]]
 <NDArray 1x3 @cpu(0)>, 'learned bias', 
 [ 4.98550272]
 <NDArray 1 @cpu(0)>)

线性拟合(欠拟合)

代码语言:javascript
复制
train(x[:num_train, :], x[num_train:, :], y[:num_train], y[num_train:])
代码语言:javascript
复制
('learned weight', 
 [[ 19.74101448]]
 <NDArray 1x1 @cpu(0)>, 'learned bias', 
 [-0.23861444]
 <NDArray 1 @cpu(0)>)

训练量不足(过拟合)

代码语言:javascript
复制
train(X[0:2, :], X[num_train:, :], y[0:2], y[num_train:])
代码语言:javascript
复制
('learned weight', 
 [[ 3.10832024 -0.740421    4.85165691]]
 <NDArray 1x3 @cpu(0)>, 'learned bias', 
 [ 0.29450524]
 <NDArray 1 @cpu(0)>)

结论

  • 训练误差的降低并不一定意味着泛化误差的降低。
  • 欠拟合和过拟合都是需要尽量避免的。我们要注意模型的选择和训练量的大小。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年03月01日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 欠拟合和过拟合
    • 训练误差和泛化误差
      • 欠拟合和过拟合
        • 模型的选择
          • 训练数据集的大小
            • 多项式拟合
              • 创建数据集
                • 定义训练和测试步骤
                  • 三阶多项式拟合(正常)
                    • 线性拟合(欠拟合)
                      • 训练量不足(过拟合)
                        • 结论
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档