赞
踩
欢迎来到我的CSDN,今天我将为大家介绍一个深度学习中非常有用的技术——Dropout。
Dropout是一种在神经网络中用于减少过拟合的正则化方法。它由Hinton等人在2012年提出,被广泛应用于卷积神经网络、循环神经网络和全连接神经网络中。
过拟合是指模型在训练集上表现很好,但在测试集上表现差的现象。这是因为模型在训练集上过分拟合了数据,从而无法泛化到新的数据。Dropout通过随机的将一部分神经元的输出设为0,从而强制神经网络学习更加鲁棒的特征,并且减少神经元之间的相互依赖,以达到减少过拟合的目的。
具体来说,Dropout是在训练过程中随机地将一些神经元的输出设为0,这些被随机选中的神经元在这一轮训练中不参与前向传播和反向传播。因此,Dropout相当于在训练过程中对每个神经元随机抽取一个“子网络”,从而让模型能够学习到不同的特征表示。在测试时,所有的神经元都参与前向传播,但是每个神经元的输出要乘上一个保留概率,这个保留概率等于训练时的丢弃概率。
Dropout的实现非常简单,只需要在神经网络的每一层后添加一个Dropout层即可。
- import torch
- import torch.nn as nn
-
- class Net(nn.Module):
- def __init__(self):
- super(Net, self).__init__()
- self.fc1 = nn.Linear(10, 20)
- self.dropout1 = nn.Dropout(p=0.5)
- self.fc2 = nn.Linear(20, 10)
- self.dropout2 = nn.Dropout(p=0.5)
-
- def forward(self, x):
- x = self.fc1(x)
- x = nn.functional.relu(x)
- x = self.dropout1(x)
- x = self.fc2(x)
- x = nn.functional.relu(x)
- x = self.dropout2(x)
- return x
在这个例子中,我们定义了一个两层的全连接神经网络,第一层的输入是10维,输出是20维,第二层的输入是20维,输出是10维。在每一层之间,我们都添加了一个Dropout层,丢弃概率为0.5。
在训练时,我们需要将网络设置为train模式,并且在每次训练迭代中调用zero_grad清空梯度,然后调用backward计算梯度,并且调用step更新参数。这里我们以MNIST手写数字识别数据集为例,进行训练和测试。
- import torch.optim as optim
- import torchvision.datasets as datasets
- import torchvision.transforms as transforms
-
- # 加载MNIST数据集
- train_data = datasets.MNIST(root='./data', train=True, transform=transforms.ToTensor(), download=True)
- test_data = datasets.MNIST(root='./data', train=False, transform=transforms.ToTensor(), download=True)
-
- # 定义模型、损失函数和优化器
- net = Net()
- criterion = nn.CrossEntropyLoss()
- optimizer = optim.SGD(net.parameters(), lr=0.01)
-
- # 开始训练
- net.train()
- for epoch in range(10):
- running_loss = 0.0
- for i, data in enumerate(train_data, 0):
- inputs, labels = data
- inputs = inputs.view(-1, 28*28)
-
- optimizer.zero_grad()
-
- outputs = net(inputs)
- loss = criterion(outputs, labels)
- loss.backward()
- optimizer.step()
-
- running_loss += loss.item()
- if i % 1000 == 999:
- print('[%d, %5d] loss: %.3f' % (epoch+1, i+1, running_loss/1000))
- running_loss = 0.0
-
- # 测试模型
- net.eval()
- correct = 0
- total = 0
- with torch.no_grad():
- for data in test_data:
- inputs, labels = data
- inputs = inputs.view(-1, 28*28)
- outputs = net(inputs)
- _, predicted = torch.max(outputs.data, 1)
- total += labels.size(0)
- correct += (predicted == labels).sum().item()
-
- print('Accuracy: %.2f %%' % (100 * correct / total))
在训练时,我们可以看到每一次训练迭代的损失值。最后,我们在测试集上计算了模型的准确率。这里我们得到的准确率为98.27%。
在这个例子中,Dropout层可以减少模型的过拟合。Dropout层的作用是在训练过程中,随机地将神经元的输出设置为0,从而强制模型学习更加鲁棒的特征,并且减少了神经元之间的相互依赖关系,使得模型的泛化能力更强。在测试时,我们不需要使用Dropout层,因为我们需要对整个模型进行评估。
当然,我们也可以在PyTorch中使用其他的Dropout实现,如torch.nn.AlphaDropout、torch.nn.Dropout2d等。不同的Dropout实现方式可能会有略微的差异,具体使用时需要根据实际情况进行选择。
希望这个例子能够帮助你理解Dropout在神经网络中的应用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。