丢弃法——dropout

《动手学深度学习pytorch》部分学习笔记,仅用作自己复习。

丢弃法——dropout

除了权重衰减以外,深度学习模型常使⽤丢弃法(dropout) 来应对过拟合问题。丢弃法有一些不同的变体。本节中提到的丢弃法特指倒置丢弃法(inverted dropout)。

单隐藏层的多层感知机,其中输⼊个数为4,隐藏单元个数为5,且隐藏单元 的计算表达式为

从零开始实现

# dropout 函数将以 drop_prob 的概率丢弃 X中的元素。
%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
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.randn(X.shape) < keep_prob).float()
    return mask * X / keep_prob

运行几个例⼦来测试一下 dropout 函数。其中丢弃概率分别为0、0.5和1。

X = torch.arange(16).view(2, 8)
dropout(X, 0)
dropout(X, 0.5)
dropout(X, 1.0)

定义模型参数

(softmax回归的从零开始实现)中介绍的Fashion-MNIST数据集。我们将定义一个包含两个隐藏层的多层感知机,其中两个隐藏层的输出个数都是256。

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256,256
W1 = torch.tensor(np.random.normal(0, 0.01, size=(num_inputs,num_hiddens1)), dtype=torch.float, requires_grad=True)
b1 = torch.zeros(num_hiddens1, requires_grad=True)
W2 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens1,num_hiddens2)), dtype=torch.float, requires_grad=True)
b2 = torch.zeros(num_hiddens2, requires_grad=True)
W3 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens2,num_outputs)), dtype=torch.float, requires_grad=True)
b3 = torch.zeros(num_outputs, requires_grad=True)
params = [W1, b1, W2, b2, W3, b3]

定义模型

下面定义的模型将全连接层激活函数ReLU串起来,并对每个激活函数的输出使⽤丢弃法。我们可以分别设置各个层的丢弃概率。通常的建议是把靠近输入层的丢弃概率设得⼩一点。实验中,我们把第一个隐藏层的丢弃概率设为0.2,把第二个隐藏层的丢弃概率设为0.5。我们可以通过参数 is_training 函数来判断运行模式为训练还是测试,并只需在训练模式下使⽤用丢弃法

# 把靠近输入层的丢弃概率设得⼩一点
drop_prob1, drop_prob2 = 0.2, 0.5
def net(X, is_training=True):
    #  这里通过 view 函数将每张原始图像改成长度为 num_inputs 的向量。
    X = X.view(-1, num_inputs)
    H1 = (torch.matmul(X, W1) + b1).relu()
    if is_training: # 只在训练模型时使⽤用丢弃法
        H1 = dropout(H1, drop_prob1) # 在第⼀层全连接后添加丢弃层
    H2 = (torch.matmul(H1, W2) + b2).relu()
    if is_training:
        H2 = dropout(H2, drop_prob2) # 在第二层全连接后添加丢弃层
    return torch.matmul(H2, W3) + b3

 在 对 模 型 评 估 的 时 候 不 应 该 进 行 丢 弃 , 所 以 我 们 修 改一 下 d2lzh_pytorch 中 的evaluate_accuracy 函数:

# 本函数已保存在d2lzh_pytorch
def evaluate_accuracy(data_iter, net):
    # 初始化
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        if isinstance(net, torch.nn.Module):
            net.eval() # 评估模式, 这会关闭dropout
            acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
            net.train() # 改回训练模式
         else: # 自定义的模型
            if('is_training' in net.__code__.co_varnames): # 如果有is_training这个参数
                # 将is_training设置成False
                acc_sum += (net(X, s_training=False).argmax(dim=1)==y).float().sum().item()
            else:
                acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
     return acc_sum / n

训练和测试模型

num_epochs, lr, batch_size = 5, 100.0, 256
loss = torch.nn.CrossEntropyLoss()
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,batch_size, params, lr)

输出:

epoch 1, loss 0.0044, train acc 0.574, test acc 0.648
epoch 2, loss 0.0023, train acc 0.786, test acc 0.786
epoch 3, loss 0.0019, train acc 0.826, test acc 0.825
epoch 4, loss 0.0017, train acc 0.839, test acc 0.831
epoch 5, loss 0.0016, train acc 0.849, test acc 0.850

简洁实现

在PyTorch中,我们只需要在全连接层后添加 Dropout 层并指定丢弃概率。在训练模型时, Dropout层 将 以 指 定 的 丢 弃 概 率 随 机 丢 弃 上 ⼀ 层 的 输 出 元 素 ; 在测试模型时 ( 即 model.eval()后), Dropout 层并不发挥作用

net = nn.Sequential(
d2l.FlattenLayer(),
nn.Linear(num_inputs, num_hiddens1),
nn.ReLU(),
nn.Dropout(drop_prob1),
nn.Linear(num_hiddens1, num_hiddens2),
nn.ReLU(),
nn.Dropout(drop_prob2),
nn.Linear(num_hiddens2, 10)
)
for param in net.parameters():
    nn.init.normal_(param, mean=0, std=0.01)

训练并测试模型。

optimizer = torch.optim.SGD(net.parameters(), lr=0.5)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs,batch_size, None, None, optimizer)

输出:

epoch 1, loss 0.0045, train acc 0.553, test acc 0.715
epoch 2, loss 0.0023, train acc 0.784, test acc 0.793
epoch 3, loss 0.0019, train acc 0.822, test acc 0.817
epoch 4, loss 0.0018, train acc 0.837, test acc 0.830
epoch 5, loss 0.0016, train acc 0.848, test acc 0.839

小结

  • 我们可以通过使用丢弃法应对过拟合。
  • 丢弃法只在训练模型时使用。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
丢弃Dropout)是一种常用于神经网络的正则化方,它可以减少过拟合现象的发生,提高模型的泛化能力。 具体来说,丢弃是通过随机地将神经网络中的部分神经元设置为0来达到正则化的目的。这些被设置为0的神经元在前向传播和反向传播过程中都会被忽略,从而使得网络的训练过程具有随机性,可以有效地防止过拟合。 下图展示了一个具有两个隐藏层的神经网络,其中每个隐藏层都包含4个神经元。在使用丢弃时,我们可以随机地将每个隐藏层中的一定比例的神经元设置为0,如下图所示: ![Dropout](https://img-blog.csdn.net/20170726230329227?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMzcyOTQzNzQ=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/70) 如图所示,我们将第一个隐藏层中的第1、3个神经元和第二个隐藏层中的第2、4个神经元设置为0,这样就形成了一个新的、被丢弃了部分神经元的神经网络。在正向传播和反向传播过程中,我们都会忽略这些被丢弃的神经元,从而提高模型的泛化能力。 需要注意的是,在测试阶段,我们不再使用丢弃,而是使用所有的神经元进行前向传播。这是因为在测试阶段,我们需要得到一个确定的输出结果,而丢弃会对每次测试的结果产生随机性。因此,在测试阶段,我们需要使用所有的神经元来得到一个确定的输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clark-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值