pytorch基础操作(七)暂退法(dropout)

1、暂退法

暂退法在前向传播过程中,计算每⼀内部层的同时注⼊噪声,这已经成为训练神经⽹络的常⽤技术。这种⽅法之所以被称为暂退法,因为我们从表⾯上看是在训练过程中丢弃(dropout)⼀些神经元。 在整个训练过程的每⼀次迭代中,标准暂退法包括在计算下⼀层之前将当前层中的⼀些节点置零。
在这里插入图片描述
通常,我们在测试时不⽤暂退法。给定⼀个训练好的模型和⼀个新的样本,我们不会丢弃任何节点,因此不需要标准化。

2、实现单层暂退法

import torch
from torch import nn

def dropout_layer(X, dropout):
    """dropout_layer 函数,该函数以dropout的概率丢弃张量输⼊X中的元素,如上所述重新缩放剩余部分:将剩余部分除以1.0-dropout。"""
    assert 0 <= dropout <= 1
    # 在本情况中,所有元素都被丢弃
    if dropout == 1:
        return torch.zeros_like(X)

    # 在本情况中,所有元素都被保留
    if dropout == 0:
        return X

    mask = (torch.randn(X.shape) > dropout).float()

    return mask * X / (1.0 - dropout)
X= torch.arange(16, dtype = torch.float32).reshape((2, 8))
print(X)
print(dropout_layer(X, 0.0))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1.0))

在这里插入图片描述

1、读取服装分类数据集 Fashion-MNIST

'''
  1、读取服装分类数据集 Fashion-MNIST
'''
import torchvision
from torch.utils import data
from torchvision import transforms


def get_dataloader_workers():
    """使⽤4个进程来读取数据"""
    return 4



def get_mnist_data(batch_size, resize=None):
    trans = [transforms.ToTensor()]

    if resize:
        # 还接受⼀个可选参数resize,⽤来将图像⼤⼩调整为另⼀种形状
        trans.insert(0,transforms.Resize(resize))
    trans = transforms.Compose(trans)

    mnist_train = torchvision.datasets.FashionMNIST(
        root='../data',train=True,transform=trans,download=False
    )


    mnist_test = torchvision.datasets.FashionMNIST(
        root='../data',train=False,transform=trans,download=False
    )
    # 数据加载器每次都会读取⼀⼩批量数据,⼤⼩为batch_size。通过内置数据迭代器,我们可以随机打乱了所有样本,从⽽⽆偏⻅地读取⼩批量
    # 数据迭代器是获得更⾼性能的关键组件。依靠实现良好的数据迭代器,利⽤⾼性能计算来避免减慢训练过程。
    train_iter = data.DataLoader(mnist_train,batch_size=batch_size,shuffle=True,num_workers=get_dataloader_workers())
    test_iter = data.DataLoader(mnist_test,batch_size=batch_size,shuffle=True,num_workers=get_dataloader_workers())

    return (train_iter,test_iter)

2、定义模型参数

'''
2、定义模型参数

我们定义具有两个隐藏层的多层感知机,每个隐藏层包含256个单元。
'''
num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

3、定义模型,搭建网络

'''
3、定义模型,搭建网络
'''

# 我们可以将暂退法应⽤于每个隐藏层的输出(在激活函数之后),并且可以为每⼀层分别设置暂退概率:
# 常⻅的技巧是在靠近输⼊层的地⽅设置较低的暂退概率。
dropout1, dropout2 = 0.2, 0.5

class Net(nn.Module):
    def __init__(self,num_inputs, num_outputs, num_hiddens1, num_hiddens2,is_training = True):
        super(Net, self).__init__()
        self.num_inputs = num_inputs
        self.is_training = is_training
        self.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))))
        # 只有在训练模型时才使⽤dropout
        if self.is_training == True:
            # 在第⼀个全连接层之后添加⼀个dropout层
            H1 = dropout_layer(H1, dropout1)
        H2 = self.relu(self.lin2(H1))
        if self.is_training == True:
            # 在第⼆个全连接层之后添加⼀个dropout层
            H2 = dropout_layer(H2, dropout2)
        out = self.lin3(H2)
        return out

net = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

4、loss函数

'''
  4、loss函数
'''
loss = nn.CrossEntropyLoss(reduction='none')

5、训练

'''
  5、训练
'''
# 将迭代周期数设置为10,并将学习率设置为0.1
num_epochs = 10
lr = 0.5
batch_size = 256

# 梯度下降
trainer = torch.optim.SGD(net.parameters(),lr=lr)

# 加载数据
train_iter, test_iter = get_mnist_data(batch_size)


from EpochTrainClass import epoch_train, evaluate_accuracy


def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater):
    for epoch in range(num_epochs):
        print(f"epoch: {epoch + 1}")
        train_metrics = epoch_train(net,train_iter,loss,updater)
        print(f'训练loss: {train_metrics[0]},训练精确率: {train_metrics[1]}')
        test_acc = evaluate_accuracy(net,test_iter)
        print(f'测试精确率: {test_acc}')

train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

在这里插入图片描述

6、模型的预测

'''
6、模型的预测
'''
def get_fashion_mnist_labels(labels):
    """返回Fashion-MNIST数据集的⽂本标签"""
    text_labels = ['t-shirt', 'trouser', 'pullover', 'dress', 'coat',
'sandal', 'shirt', 'sneaker', 'bag', 'ankle boot']
    return [text_labels[int(i)] for i in labels]


def predict_ch3(net,test_iter, n=8):

    for X,y in test_iter:
        trues = get_fashion_mnist_labels(y[0:n])
        preds = get_fashion_mnist_labels(
        net(X).argmax(axis=1)[0:n]
    )

        print('trues:',trues)
        print('preds:',preds)
        break


predict_ch3(net,test_iter)

在这里插入图片描述

3、暂退法的简洁实现

'''
  二、暂退法的简洁实现
'''
from torch.nn import Sequential, Flatten, Linear,ReLU,Dropout


# 搭建神经网络
class Net2(nn.Module):

    def __init__(self):
        super(Net2, self).__init__()
        self.model = Sequential(
            Flatten(),
            Linear(in_features=784, out_features=256),
            ReLU(),
            # 在第⼀个全连接层之后添加⼀个dropout层
            Dropout(dropout1),
            nn.Linear(256, 256),
            ReLU(),
            # 在第⼆个全连接层之后添加⼀个dropout层
            Dropout(dropout2),
            Linear(256, 10)
        )

    def forward(self, X):
        X = self.model(X)
        return X



def init_weights(m):
    if type(m) == nn.Linear:
        nn.init.normal_(m.weight, std=0.01)

net = Net2()
net.apply(init_weights)


# 梯度下降
trainer = torch.optim.SGD(net.parameters(),lr=lr)

train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用PyTorch中的nn.Dropout()函数来实现dropout方法。以下是在FashionMNIST数据集中使用dropout方法的代码示例: ```python import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms # 定义转换 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,)) ]) # 加载数据集 train_dataset = datasets.FashionMNIST('./data', train=True, download=True, transform=transform) test_dataset = datasets.FashionMNIST('./data', train=False, transform=transform) # 定义模型 class Net(nn.Module): def __init__(self): super(Net, self).__init__() self.fc1 = nn.Linear(784, 512) self.fc2 = nn.Linear(512, 256) self.fc3 = nn.Linear(256, 10) self.dropout = nn.Dropout(p=0.5) # 定义dropout层,丢弃概率为0.5 def forward(self, x): x = x.view(-1, 784) x = self.dropout(torch.relu(self.fc1(x))) x = self.dropout(torch.relu(self.fc2(x))) x = self.fc3(x) return x model = Net() # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.parameters(), lr=0.01) # 训练模型 for epoch in range(10): running_loss = 0.0 for data, target in train_loader: optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() optimizer.step() running_loss += loss.item() print('[Epoch %d] loss: %.3f' % (epoch+1, running_loss/len(train_loader))) # 测试模型 correct = 0 total = 0 with torch.no_grad(): for data, target in test_loader: output = model(data) _, predicted = torch.max(output.data, 1) total += target.size(0) correct += (predicted == target).sum().item() print('Accuracy on test set: %d %%' % (100 * correct / total)) ``` 在上述代码中,我们定义了一个名为`Net`的类来表示我们的神经网络模型。在`Net`的构造函数中,我们定义了三个全连接层和一个dropout层,丢弃概率为0.5。在`forward`函数中,我们首先将输入数据展开为一维向量,然后通过全连接层和dropout层进行前向传播。 在训练过程中,我们使用交叉熵损失函数和随机梯度下降优化器来训练模型。在测试过程中,我们使用准确率作为评价指标来评估模型的性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值