模型选择
本质上,我的理解对于模型选择来说就是在一个合适的模型下训练出来一个合适的参数来使得模型能够带来一个在模型没有的数据上得到一个比较好的结果。
说的简单一点就是,别过拟合也别欠拟合,在测试集上的误差能够在合理的能接受的范围之内。
训练误差、泛化误差
训练误差很好理解,在使用训练集的时候,每一轮训练都会使模型的参数有所更新,可以把他看成一个新的模型,用这些数据训练,再用这些数据进行测试,得到的就是训练误差
泛化误差,在这本书上的定义是一个比较理想的值。但是我的理解就是在训练好的模型下,模型没有见过的数据来测试的误差就是泛化误差。同样的感觉就是他指的就是测试误差
K折交叉验证
K折交叉验证指的是在原始训练数据集上将其分成K份,每次选择其中的一份作为验证数据集,其他的作为训练数据,来对模型进行训练。能够避免一些特殊的随机抽样导致的结果较为特殊和不正常的情况,同时也可以检验当前超参数下训练误差和验证误差一个较为合理的误差值,尽可能的避免因为数据抽样带来的干扰。
拟合程度
过拟合与欠拟合
模型容量
拟合各种函数的能力
以K阶多项式来举例,阶数越高,模型复杂性就越大。模型复杂性直观来讲也可以举例的是神经网络的深度越大复杂性越大。这个概念较为直觉。
模型数据集大小
数据集的大小可以指很多方面:
- 样本的个数
- 样本的元素数(每个样本的特征的数量)
- 时间、空间结构(图片、视频)
- 多样性(数据的种类有很多)
几者的关系
模型容量需要匹配数据复杂度,否则可能导致过拟合和欠拟合
代码实现
在本节构建数据集来演示过拟合和欠拟合的数据集时,看了半天我才看明白他其实跟其他的教材讲解过拟合的例子不是特别的一样
生成数据集
给定 x x x,我们将[使用以下三阶多项式来生成训练和测试数据的标签:]
( y = 5 + 1.2 x − 3.4 x 2 2 ! + 5.6 x 3 3 ! + ϵ where ϵ ∼ N ( 0 , 0. 1 2 ) . y = 5 + 1.2x - 3.4\frac{x^2}{2!} + 5.6 \frac{x^3}{3!} + \epsilon \text{ where } \epsilon \sim \mathcal{N}(0, 0.1^2). y=5+1.2x−3.42!x2+5.63!x3+ϵ where ϵ∼N(0,0.12).)
噪声项
ϵ
\epsilon
ϵ服从均值为0且标准差为0.1的正态分布。
在优化的过程中,我们通常希望避免非常大的梯度值或损失值。
这就是我们将特征从
x
i
x^i
xi调整为
x
i
i
!
\frac{x^i}{i!}
i!xi的原因,
这样可以避免很大的
i
i
i带来的特别大的指数值。
max_degree = 20 # 多项式的最大阶数
n_train, n_test = 100, 100 # 训练和测试数据集大小
true_w = np.zeros(max_degree) # 分配大量的空间
true_w[0:4] = np.array([5, 1.2, -3.4, 5.6])
"""
通过阅读下面的代码以及对下面的代码做测试,感觉这个数据集好像只是生成一维的特征,也就是跟上面公式没对
做区分一样
并不是在其他视频中看到的多做几维特征,然后修改每一维对应的指数来说明过拟合和欠拟合的
"""
features = np.random.normal(size=(n_train + n_test, 1)) # 生成列向量,也就是每个样本
# display(features)
np.random.shuffle(features) # 随机打乱
# 这里运用了广播机制,使得feature中的每一行都复制成了max_degree份
poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))
print(poly_features)
for i in range(max_degree):
poly_features[:, i] /= math.gamma(i + 1) # gamma(n)=(n-1)!,除以阶乘
# labels的维度:(n_train+n_test,)
labels = np.dot(poly_features, true_w) # 算出样本
labels += np.random.normal(scale=0.1, size=labels.shape) # 给样本加上噪声