打卡2020-02-19

2020-02-19  本文已影响0人  manyGrasses

K折交叉验证

由于验证数据集不参与模型训练,当训练数据不够用时,预留大量的验证数据显得太奢侈。一种改善的方法是K折交叉验证(K-fold cross-validation)。在K折交叉验证中,我们把原始训练数据集分割成K个不重合的子数据集,然后我们做K次模型训练和验证。每一次,我们使用一个子数据集验证模型,并使用其他K-1个子数据集来训练模型。在这K次训练和验证中,每次用来验证模型的子数据集都不同。最后,我们对这K次训练误差和验证误差分别求平均。

k折交叉验证的目的:

  1. 判断模型是否过拟合(估计模型的泛化误差)。(以用来做模型选择)

一个非常好的解释:

一、k折交叉验证的目的(为什么要用k折交叉验证?)
1.根本原因:数据有限,单一的把数据都用来做训练模型,容易导致过拟合。(反过来,如果数据足够多,完全可以不使用交叉验证。)较小的k值会导致可用于建模的数据量太小,所以小数据集的交叉验证结果需要格外注意,建议选择较大的k值。
2.理论上:使用了交叉验证,模型方差“应该”降低了。
在理想情况下,我们认为k折交叉验证可以 O(1/k)的效率降低模型方差,从而提高模型的泛化能力。通俗地说,我们期望模型在训练集的多个子数据集上表现良好,要胜过单单在整个训练数据集上表现良好。(注意:但实际上,由于所得到的k折数据之间并非独立而是存在相关性,k折交叉验证到底能降低多少方差还不确定,同时可能会带来偏差上升。)
二、 从方差偏差的角度来看交叉验证
(1)什么是模型的偏差和方差?
在机器学习中,我们用训练集去训练(学习)一个model(模型),通常的做法是定义一个loss function(误差函数),通过将这个loss最小化过程,来提高模型的性能(performance)。然而我们学习一个模型的目的是为了解决实际的问题(或者说是训练数据集这个领域(field)中的一般化问题),单纯地将训练数据集的loss最小化,并不能保证在解决更一般问题时仍然是最优的,甚至不能保证模型是可用的。这个训练数据集的loss与一般化的数据集的loss之间的差异就叫generalization error=bias+variance。(注意:bias和variance是针对generalization(一般化,泛化)来说的。)
generalization error分为bias和variance两个部分。首先如果我们能够获得所有可能的数据集合,并在这个数据集合上将loss最小化,这样学习到的模型就可以称之为“真是模型”。当然,我们无论如何都不能获得并训练所有可能的数据,所以“真是模型”肯定存在,但是无法获得,我们最终的目标就是去学习一个模型使其更加接近这个“真实模型”。
而bias和variance分别从两个方面来描述我们学习到的模型与真实模型之间的差距。
Bias是“用所有可能的训练数据集训练出的所有模型的输出的平均值(也就是去取期望的步骤)”与“真是模型”的输出值之间的差异;
Variance则是“不同的训练数据集训练出的模型”的输出值之间的差异。也就是说bias反映的是模型在样本上的输出值与真实值之间的差距,即模型本省的精准度(或者说算法本省的拟合能力);variance反映的是模型每次输出结果与模型期望输出之间的误差,即模型的稳定性。
这里需要注意的是我们能够用来学习的训练数据集只是全部数据中的一个子集。
Error=Bais^2 +Variance+Noise
————————————————
版权声明:本文为CSDN博主「Ice Cream_069」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_36103474/article/details/92799657

k的选择

2017年的一项研究给出了另一种经验式的选择方法,作者建议k \approx log(n) 且保证 n / k > 3d即k < n / (3d),n代表了数据量,d代表了特征数。感兴趣的朋友可以对照论文进一步了解。
from https://blog.csdn.net/Li_yi_chao/article/details/82665745

过拟合,欠拟合

一句话,过拟合会出现高方差问题。欠拟合会出现高偏差问题。

防止过拟合的办法

正则

首先正则化主要是为了防止过拟合,而过拟合一般表现为模型对于输入的微小改变产生了输出的较大差异,这主要是由于有些参数w过大的关系,通过对||w||进行惩罚,可以缓解这种问题。而如果对||b||进行惩罚,其实是没有作用的,因为在对输出结果的贡献中,参数b对于输入的改变是不敏感的,不管输入改变是大还是小,参数b的贡献就只是加个偏置而已。举个例子,如果你在训练集中,w和b都表现得很好,但是在测试集上发生了过拟合,b是不背这个锅的,因为它对于所有的数据都是一视同仁的(都只是给它们加个偏置),要背锅的是w,因为它会对不同的数据产生不一样的加权。或者说,模型对于输入的微小改变产生了输出的较大差异,这是因为模型的“曲率”太大,而模型的曲率是由w决定的,b不贡献曲率(对输入进行求导,b是直接约掉的)。
作者:阳仔的下午茶
链接:https://www.zhihu.com/question/66894061/answer/653496474
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

\ell(w_1, w_2, b) = \frac{1} {n} \sum_{i=1}^n \frac{1}{2}\left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right)^2

其中w_1, w_2是权重参数,b是偏差参数,样本i的输入为x_1^{(i)}, x_2^{(i)},标签为y^{(i)},样本数为n。将权重参数用向量\boldsymbol{w} = [w_1, w_2]表示,带有L_2范数惩罚项的新损失函数为

\ell(w_1, w_2, b) + \frac{\lambda} {2n} |\boldsymbol{w}|^2,

其中超参数\lambda > 0。当权重参数均为0时,惩罚项最小。当\lambda较大时,惩罚项在损失函数中的比重较大,这通常会使学到的权重参数的元素较接近0。当\lambda设为0时,惩罚项完全不起作用。上式中L_2范数平方|\boldsymbol{w}|^2展开后得到w_1^2 + w_2^2
有了L_2范数惩罚项后,在小批量随机梯度下降中,我们将线性回归一节中权重w_1w_2的迭代方式更改为

w_1 \leftarrow \left(1- \frac{\eta\lambda}{|\mathcal{B}|} \right)w_1 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_1^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right),\\ w_2 \leftarrow \left(1- \frac{\eta\lambda}{|\mathcal{B}|} \right)w_2 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_2^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right).

可见,L_2范数正则化令权重w_1w_2先自乘小于1的数,再减去不含惩罚项的梯度。因此,L_2范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。

dropout

多层感知机中神经网络图描述了一个单隐藏层的多层感知机。其中输入个数为4,隐藏单元个数为5,且隐藏单元h_ii=1, \ldots, 5)的计算表达式为

h_i = \phi\left(x_1 w_{1i} + x_2 w_{2i} + x_3 w_{3i} + x_4 w_{4i} + b_i\right)

这里\phi是激活函数,x_1, \ldots, x_4是输入,隐藏单元i的权重参数为w_{1i}, \ldots, w_{4i},偏差参数为b_i。当对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为p,那么有p的概率h_i会被清零,有1-p的概率h_i会除以1-p拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量\xi_i为0和1的概率分别为p1-p。使用丢弃法时我们计算新的隐藏单元h_i'

h_i' = \frac{\xi_i}{1-p} h_i

由于E(\xi_i) = 1-p,因此

E(h_i') = \frac{E(\xi_i)}{1-p}h_i = h_i

即丢弃法不改变其输入的期望值。让我们对之前多层感知机的神经网络中的隐藏层使用丢弃法,一种可能的结果如图所示,其中h_2h_5被清零。这时输出值的计算不再依赖h_2h_5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h_1, \ldots, h_5都有可能被清零,输出层的计算无法过度依赖h_1, \ldots, h_5中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法

dropout示例

dropout实现:

def dropout(X, drop_prob):
    X = X.float()
    assert 0 <= drop_prob <= 1
    keep_prob = 1 - drop_prob
    # 这种情况下把全部元素都丢弃
    if keep_prob == 0:
        return torch.zeros_like(X)
    mask = (torch.rand(X.shape) < keep_prob).float()
    
    return mask * X / keep_prob

RNN

  1. RNN的数学表达
    简单的RNN可以看作是一个只有一个隐藏层的全连接神经网络,RNN模型关键的参数只有W_eW_h两个矩阵,在所有时间步这两个矩阵都是一样的。理解RNN关键的一点是在计算H_t的时候会用到上一步的H_{t-1}

\boldsymbol{X}_t \in \mathbb{R}^{n \times d}是时间步t的小批量输入,\boldsymbol{H}_t \in \mathbb{R}^{n \times h}为t时刻的隐藏层结果,则:
\boldsymbol{H}_t = \phi(\boldsymbol{X}_t \boldsymbol{W}_{e} + \boldsymbol{H}_{t-1} \boldsymbol{W}_{h} + \boldsymbol{b}_h).
其中,\boldsymbol{W}_{e} \in \mathbb{R}^{d \times h}(d为embedding的维度,h为隐藏层的神经元的个数),\boldsymbol{W}_{h} \in \mathbb{R}^{h \times h}\boldsymbol{b}_{h} \in \mathbb{R}^{1 \times h}\phi函数是非线性激活函数。由于引入了\boldsymbol{H}_{t-1} \boldsymbol{W}_{h}H_{t}能够捕捉截至当前时间步的序列的历史信息。由于H_{t}的计算基于H_{t-1},上式的计算是循环的。
在时间步t,输出层的输出为:
\boldsymbol{O}_t = \boldsymbol{H}_t \boldsymbol{U} + \boldsymbol{b}_q.
其中\boldsymbol{U} \in \mathbb{R}^{h \times q}\boldsymbol{b}_q \in \mathbb{R}^{1 \times q},q为输出的类别的个数,一般为词汇量的个数vocab_size。

  1. RNN的损失函数

J^{(t)}(\theta) = CE(y^{(t)}, \hat y^{(t)})\\ = -\sum_{w \in V} y_w ^{(t)} log \hat y_w^{(t)}\\ = - log \hat y^{(t)}_{y^{(t)}} \\ = - log \hat y^{(t)}_{x_{t+1}}
y^{(t)}为x_{t+1}也就是下一个时刻对应的词,是一个one-hot表达。\hat y^{(t)}是第t步的预测输出。
J(\theta) = \frac{1}{T} \sum_{t=1}^T J^{(t)}(\theta) \\ = - \frac{1}{T} \sum_{t=1}^T log \hat y^{(t)}_{y_{(t)}}

上一篇下一篇

猜你喜欢

热点阅读