北京网页设计公司网站,网站建设排名优化技巧,教育网站如何做经营,济南优化排名公司#x1f468;#x1f393;作者简介#xff1a;一位即将上大四#xff0c;正专攻机器学习的保研er #x1f30c;上期文章#xff1a;机器学习深度学习——权重衰减 #x1f4da;订阅专栏#xff1a;机器学习深度学习 希望文章对你们有所帮助 Drop… 作者简介一位即将上大四正专攻机器学习的保研er 上期文章机器学习深度学习——权重衰减 订阅专栏机器学习深度学习 希望文章对你们有所帮助 Dropout 重新审视过拟合扰动的稳健性实践中的Dropout从零开始实现定义模型参数定义模型训练和测试简洁实现小结 重新审视过拟合
当面对更多特征而样本不足时线性模型常会过拟合。而如果给出更多的样本而不是特征通常线性模型不会过拟合。但线性模型泛化的可靠性是有代价的线性模型没有考虑到特征之间的交互作用。对每个特征线性模型必须指定正的或负的权重而忽略了其他的特征。这也是之前提出隐藏层的缘由。 泛化性和灵活性之间的这种基本权衡称为偏差-方差权衡。线性模型有很高的偏差它们只能表示一小类函数。然而这些模型的方差很低它们在不同的随机数据样本上可以得出相似的结果。 深度神经网络就与线性模型不同它处在偏差-方差谱的另一端它不能查单独查看每个特征而是学习特征之间的交互。但当我们有比特征多得多的样本时深度神经网络也有可能会过拟合。
扰动的稳健性
我们期望的好的预测模型能在未知的数据上有很好的表现为缩小训练与测试性能之间的差距应该以简单模型为目标。简单性就是以较小维度的形式展现之前验证过线性模型的单项式函数时就探讨过这一点了此外上一节的L2正则化-权重衰减时也看到了参数的范数也代表了一种有用的简单性度量。 简单的另一个角度是平滑性即函数不应该对其输入的微小变化敏感。例如当我们对图像进行分类时我们预计像像素添加一些随机噪声应该是基本无影响的。克里斯托弗·毕晓普证明了具有噪声的训练等价于Tikhonov正则化不必管具体原理咱只要知道正则化的作用就是为了权重衰减的这证实了“要求函数光滑”和“要求函数对输入的随机噪声具有适应性”之间的联系。 因此提出了一个想法在训练过程中在计算后续层之前向网络的每一层注入噪声。因为当训练一个有多层的深层网络时注入噪声只会在输入-输出映射上增强平滑性。 这个方法就称为dropoutdropout在前向传播过程中计算每一内部层的同时注入噪声已经成为训练神经网络的常用技术。这种方法在表面上看起来像是在训练过程中丢弃drop out一些神经元。标准暂退法就包括在计算下一层之前将当前层的一些结点置0。 关键在于如何注入这些噪声。一种想法是以一种无偏向的方式注入噪声。这样在固定住其他层时每一层的期望值都等于没有噪声时的值。 在标准暂退法正则化中通过按保留未丢弃的节点的分数进行规范化来消除每一层的偏差。如下所示 h ′ { 0 概率为 p h 1 − p 其他情况 h^{} \begin{cases} \begin{aligned} 0概率为p\\ \frac{h}{1-p}其他情况 \end{aligned} \end{cases} h′⎩ ⎨ ⎧0概率为p1−ph其他情况 显然E[h’]0*p(1-p)*h/(1-p)h
实践中的Dropout
对于一个带有1个隐藏层和5个隐藏单元的多层感知机 当我们将dropout应用到隐藏层以p的概率将隐藏单元置0时结果可以看作一个只包含神经元子集的网络如 因此输出的计算不再依赖h2和h5且它们各自的梯度在反向传播时也会消失。 我们在测试时会丢弃任何节点不用dropout。
从零开始实现
要实现单层的dropout函数我们从均匀分布U[0,1]中抽取样本样本数与这层神经网络的维度一致。 然后我们保留那些对应样本大于p的节点把剩下的丢弃。 在下面的代码中我们实现 dropout_layer 函数 该函数以dropout的概率丢弃张量输入X中的元素 如上所述重新缩放剩余部分将剩余部分除以1.0-dropout。
import torch
from torch import nn
from d2l import torch as d2ldef dropout_layer(X, dropout):assert 0 dropout 1# 在本情况中所有元素都被丢弃if dropout 1:return torch.zeros_like(X)# 在本情况中所有元素都被保留if dropout 0:return Xmask (torch.rand(X.shape) dropout).float()return mask * X / (1.0 - dropout)我们可以通过下面几个例子来测试dropout_layer函数。 我们将输入X通过暂退法操作暂退概率分别为0、0.5和1。
X torch.arange(16, dtype torch.float32).reshape((2, 8))
print(X)
print(dropout_layer(X, 0.))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1.))运行结果 tensor([[ 0., 1., 2., 3., 4., 5., 6., 7.], [ 8., 9., 10., 11., 12., 13., 14., 15.]]) tensor([[ 0., 1., 2., 3., 4., 5., 6., 7.], [ 8., 9., 10., 11., 12., 13., 14., 15.]]) tensor([[ 0., 2., 0., 6., 0., 0., 0., 14.], [16., 18., 20., 0., 0., 26., 28., 0.]]) tensor([[0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0.]])
定义模型参数
同样我们使用Fashion-MNIST数据集。我们定义具有两个隐藏层的多层感知机每个隐藏层包含256个单元。
num_inputs, num_outputs, num_hiddens1, num_hiddens2 784, 10, 256, 256定义模型
我们可以将dropout应用于每个隐藏层的输出在激活函数之后并且可以为每一层分别设置dropout概率常见的技巧是在靠近输入层的地方设置较低的暂退概率。下面的模型将第一个和第二个隐藏层的暂退概率分别设置为0.2和0.5并且dropout只在训练期间有效。
dropout1, dropout2 0.2, 0.5class Net(nn.Module):def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,is_trainingTrue):super(Net, self).__init__()self.num_inputs num_inputsself.training is_trainingself.lin1 nn.Linear(num_inputs, num_hiddens1)self.lin2 nn.Linear(num_hiddens1, num_hiddens2)self.lin3 nn.Linear(num_hiddens2, num_outputs)self.relu nn.ReLU()def forward(self, X):H1 self.relu(self.lin1(X.reshape((-1, self.num_inputs))))# 只有在训练模型时才使用dropoutif self.training True:# 在第一个全连接层之后添加一个dropout层H1 dropout_layer(H1, dropout1)H2 self.relu(self.lin2(H1))if self.training True:# 在第二个全连接层之后添加一个dropout层H2 dropout_layer(H2, dropout2)out self.lin3(H2)return outnet Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)训练和测试
这类似于前面描述的多层感知机训练和测试。
num_epochs, lr, batch_size 10, 0.5, 256
loss nn.CrossEntropyLoss(reductionnone)
train_iter, test_iter d2l.load_data_fashion_mnist(batch_size)
trainer torch.optim.SGD(net.parameters(), lrlr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
d2l.plt.show()运行结果
简洁实现
对于深度学习框架的高级API我们只需在每个全连接层之后添加一个Dropout层将暂退概率作为唯一的参数传递给它的构造函数。在训练时Dropout层将根据指定的暂退概率随机丢弃上一层的输出。在测试时Dropout层仅传递数据。
import torch
from torch import nn
from d2l import torch as d2lnum_inputs, num_outputs, num_hiddens1, num_hiddens2 784, 10, 256, 256dropout1, dropout2 0.2, 0.5net nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),# 在第一个全连接层之后添加一个dropout层nn.Dropout(dropout1),nn.Linear(256, 256),nn.ReLU(),# 在第二个全连接层之后添加一个dropout层nn.Dropout(dropout2),nn.Linear(256, 10))def init_weights(m):if type(m) nn.Linear:nn.init.normal_(m.weight, std0.01)net.apply(init_weights)num_epochs, lr, batch_size 10, 0.5, 256
loss nn.CrossEntropyLoss(reductionnone)
train_iter, test_iter d2l.load_data_fashion_mnist(batch_size)
trainer torch.optim.SGD(net.parameters(), lrlr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
d2l.plt.show()运行结果
小结
1、dropout在前向传播过程中计算每一内部层的同时丢弃一些神经元。 2、dropout可以避免过拟合它通常与控制权重向量的维数和大小结合使用的。 3、dropout将活性值h替换为具有期望值h的随机变量。 4、dropout仅在训练期间使用。