使用Dropout大幅优化PyTorch模型,实现图像识别

大家好,在机器学习模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象。在训练神经网络时,过拟合具体表现在模型训练数据损失函数较小,预测准确率较高,但是在测试数据上损失函数比较大,预测准确率较低。Dropout可以比较有效的缓解过拟合的发生,在一定程度上达到正则化的效果。

1.机器学习中的Dropout正则化

Dropout正则化是机器学习领域中一种有效的技术,通过随机丢弃神经网络中的某些单元,实现对多个不同网络架构的并行训练。

这种方法对于减少模型在训练过程中的过拟合现象非常关键,有助于提升模型的泛化能力。

图片

深度网络

2.在PyTorch模型中集成Dropout

要在PyTorch模型中加入Dropout正则化,可以使用torch.nn.Dropout类来实现。这个类需要一个Dropout率作为输入参数,表示神经元被关闭的可能性,这可以应用于任何非输出层。

self.dropout = nn.Dropout(0.25)

3.观察Dropout对模型性能的影响

为了研究Dropout的效果,这里将训练一个用于图像分类的模型。最初,训练一个经过正则化的网络,然后是一个没有Dropout正则化的网络。两个模型都将在Cifar-10数据集上训练8个周期。

步骤1:首先,将导入需要实现网络的依赖项和库。

import torch
from torch import nn
from torch import optim
from torch.nn import functional as F
import torchvision
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

import matplotlib.pyplot as plt
import numpy as np

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)

步骤2:将加载数据集并准备数据加载器。

BATCH_SIZE = 32

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root="./data", train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root="./data", train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=BATCH_SIZE,
                                         shuffle=False, num_workers=2)

CLASS_NAMES = ("plane", "car", "bird", "cat",
               "deer", "dog", "frog", "horse", "ship", "truck")

步骤3:加载并可视化一些数据

def show_batch(image_batch, label_batch):
    plt.figure(figsize=(10,10))
    for n in range(25):
        ax = plt.subplot(5,5,n+1)
        img = image_batch[n] / 2 + 0.5     # 取消归一化
        img = img.numpy()
        plt.imshow(np.transpose(img, (1, 2, 0)))
        plt.title(CLASS_NAMES[label_batch[n]])
        plt.axis("off")
sample_images, sample_labels = next(iter(trainloader))
show_batch(sample_images, sample_labels)

输出:

图片

步骤4:在Dropout正则化中实现网络

class Net(nn.Module):
    def __init__(self, input_shape=(3,32,32)):
        super(Net, self).__init__()
        
        self.conv1 = nn.Conv2d(3, 32, 3)
        self.conv2 = nn.Conv2d(32, 64, 3)
        self.conv3 = nn.Conv2d(64, 128, 3)
        
        self.pool = nn.MaxPool2d(2,2)
        
        n_size = self._get_conv_output(input_shape)
        
        self.fc1 = nn.Linear(n_size, 512)
        self.fc2 = nn.Linear(512, 10)
        
        self.dropout = nn.Dropout(0.25)
        
    def _get_conv_output(self, shape):
        batch_size = 1
        input = torch.autograd.Variable(torch.rand(batch_size, *shape))
        output_feat = self._forward_features(input)
        n_size = output_feat.data.view(batch_size, -1).size(1)
        return n_size
    
    def _forward_features(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.pool(F.relu(self.conv3(x)))
        return x
      
    def forward(self, x):
        x = self._forward_features(x)
        x = x.view(x.size(0), -1)
        x = self.dropout(x)
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.fc2(x)
        return x

步骤5:实现训练

def train(model, device, train_loader, optimizer, criterion, epoch, steps_per_epoch=20):
    # 将模型切换到训练模式。这对于像dropout、batchnorm等在训练和评估模式下表现不同的层是必要的
    model.train()

    train_loss = 0
    train_total = 0
    train_correct = 0

    # 我们循环遍历数据迭代器,并将输入数据提供给网络并调整权重。
    for batch_idx, (data, target) in enumerate(train_loader, start=0):
        
        # 从训练数据集中加载输入特征和标签
        data, target = data.to(device), target.to(device)
        
        # 将所有可学习权重参数的梯度重置为0
        optimizer.zero_grad()
        
        # 前向传播:传递训练数据集中的图像数据,预测图像所属的类别(在本例中为0-9)
        output = model(data)
        
        # 定义我们的损失函数,并计算损失
        loss = criterion(output, target)
        train_loss += loss.item()

        scores, predictions = torch.max(output.data, 1)
        train_total += target.size(0)
        train_correct += int(sum(predictions == target))
            
        # 将所有可学习权重参数的梯度重置为0
        optimizer.zero_grad()

        # 反向传播:计算损失相对于模型参数的梯度
        loss.backward()
        
        # 更新神经网络权重
        optimizer.step()

    acc = round((train_correct / train_total) * 100, 2)
    print("Epoch [{}], Loss: {}, Accuracy: {}".format(epoch, train_loss/train_total, acc), end="")

步骤6:实现测试函数

def test(model, device, test_loader, criterion, classes):
    # 将模型切换到评估模式。这对于像dropout、batchnorm等在训练和评估模式下表现不同的层是必要的
    model.eval()

    test_loss = 0
    test_total = 0
    test_correct = 0

    example_images = []
    with torch.no_grad():
        for data, target in test_loader:
            # 从测试数据集中加载输入特征和标签
            data, target = data.to(device), target.to(device)
            
            # 进行预测:传递测试数据集中的图像数据,预测图像所属的类别(在本例中为0-9)
            output = model(data)
            
            # 计算损失,累加批次损失
            test_loss += criterion(output, target).item()
            
            scores, predictions = torch.max(output.data, 1)
            test_total += target.size(0)
            test_correct += int(sum(predictions == target))

    acc = round((test_correct / test_total) * 100, 2)
    print("Test_loss: {}, Test_accuracy: {}".format(test_loss/test_total, acc))

步骤7:初始化网络的损失和优化器

net = Net().to(device)
print(net)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters())

输出:

Net(
  (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1))
  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
  (conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1))
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc1): Linear(in_features=512, out_features=512, bias=True)
  (fc2): Linear(in_features=512, out_features=10, bias=True)
  (dropout): Dropout(p=0.25, inplace=False)
)

步骤8:开始训练

for epoch in range(8):
    train(net, device, trainloader, optimizer, criterion, epoch)
    test(net, device, testloader, criterion, CLASS_NAMES)

print("Finished Training")

输出:

Epoch [0], Loss: 0.0461193907892704, Accuracy: 45.45 Test_loss: 0.036131812924146654, Test_accuracy: 58.58
Epoch [1], Loss: 0.03446852257728577, Accuracy: 60.85 Test_loss: 0.03089196290373802, Test_accuracy: 65.27
Epoch [2], Loss: 0.029333480607271194, Accuracy: 66.83 Test_loss: 0.027052838513255118, Test_accuracy: 70.41
Epoch [3], Loss: 0.02650276515007019, Accuracy: 70.21 Test_loss: 0.02630699208676815, Test_accuracy: 70.99
Epoch [4], Loss: 0.024451716771125794, Accuracy: 72.41 Test_loss: 0.024404651895165445, Test_accuracy: 73.03
Epoch [5], Loss: 0.022718262011408807, Accuracy: 74.35 Test_loss: 0.023125074282288553, Test_accuracy: 74.86
Epoch [6], Loss: 0.021408387248516084, Accuracy: 75.76 Test_loss: 0.023151200053095816, Test_accuracy: 74.43
Epoch [7], Loss: 0.02033562403023243, Accuracy: 76.91 Test_loss: 0.023537022879719736, Test_accuracy: 73.93
Finished Training

4.没有Dropout正则化的网络

在这里将构建相同的网络,但是没有dropout层。在相同的数据集和周期数上训练网络,并评估Dropout对网络性能的影响,使用相同的训练和测试函数。

步骤1:实现网络

class Net(nn.Module):
    def __init__(self, input_shape=(3,32,32)):
        super(Net, self).__init__()
        
        self.conv1 = nn.Conv2d(3, 32, 3)
        self.conv2 = nn.Conv2d(32, 64, 3)
        self.conv3 = nn.Conv2d(64, 128, 3)
        
        self.pool = nn.MaxPool2d(2,2)
        
        n_size = self._get_conv_output(input_shape)
        
        self.fc1 = nn.Linear(n_size, 512)
        self.fc2 = nn.Linear(512, 10)
        
    def _get_conv_output(self, shape):
        batch_size = 1
        input = torch.autograd.Variable(torch.rand(batch_size, *shape))
        output_feat = self._forward_features(input)
        n_size = output_feat.data.view(batch_size, -1).size(1)
        return n_size
    
    def _forward_features(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = self.pool(F.relu(self.conv3(x)))
        return x
      
    def forward(self, x):
        x = self._forward_features(x)
        x = x.view(x.size(0), -1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

步骤2:损失和优化器

net = Net().to(device)
print(net)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters())

输出:

Net(
  (conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1))
  (conv2): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))
  (conv3): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1))
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (fc1): Linear(in_features=512, out_features=512, bias=True)
  (fc2): Linear(in_features=512, out_features=10, bias=True)
)

步骤3:开始训练

for epoch in range(8):
    train(net, device, trainloader, optimizer, criterion, epoch)
    test(net, device, testloader, criterion, CLASS_NAMES)

print("Finished Training")

输出:

Epoch [0], Loss: 0.04425342482566833, Accuracy: 48.29 Test_loss: 0.03506121407747269, Test_accuracy: 59.93
Epoch [1], Loss: 0.0317487561249733, Accuracy: 63.97 Test_loss: 0.029791217082738877, Test_accuracy: 66.4
Epoch [2], Loss: 0.026000032302737237, Accuracy: 70.83 Test_loss: 0.027046055325865747, Test_accuracy: 69.97
Epoch [3], Loss: 0.022179243130385877, Accuracy: 75.11 Test_loss: 0.02481114484965801, Test_accuracy: 72.95
Epoch [4], Loss: 0.01933788091301918, Accuracy: 78.26 Test_loss: 0.024382170912623406, Test_accuracy: 73.55
Epoch [5], Loss: 0.016771901984512807, Accuracy: 81.04 Test_loss: 0.024696413831412793, Test_accuracy: 73.53
Epoch [6], Loss: 0.014588635778725148, Accuracy: 83.41 Test_loss: 0.025593858751654625, Test_accuracy: 73.94
Epoch [7], Loss: 0.01255791916936636, Accuracy: 85.94 Test_loss: 0.026889967443048952, Test_accuracy: 73.69
Finished Training

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/742876.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI小白的大模型探险之旅:从入门到精通的奇妙旅程

前言 在数字化浪潮汹涌的时代,人工智能(AI)技术如同一位神秘的魔法师,以其强大的力量改变着世界的面貌。而在这魔法世界中,大模型技术无疑是那颗璀璨的明珠,引领着AI技术的新潮流。今天,我们就…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS Semaphore做同步使用

信号量作为同步使用 创建一个Semaphore对象,并指定一个初始的计数值(通常称为“许可”或“令牌”的数量)。这个计数值表示当前可用的资源数量或可以同时访问共享资源的线程数。当一个线程需要访问共享资源时,它会尝试从Semaphore…

Sectigo或RapidSSL DV通配符SSL证书哪个性价比更高?

在当前的网络安全领域,选择一款合适的SSL证书对于保护网站和用户数据至关重要。Sectigo和RapidSSL作为市场上知名的SSL证书提供商,以其高性价比和快速的服务响应而受到市场的青睐。本文将对Sectigo和RapidSSL DV通配符证书进行深入对比,帮助用…

怎么免费SSL证书有效期越来越短了

其实说到SSL证书,很多人的第一印象都是免费SSL证书,主要是由于国内网络发展的历程相对于国外而言较晚,SSL证书的普及程度也远没有国外那么广泛,因此在国内前期的基础SSL证书会由各个云厂商和CA免费提供,之前在国内的一…

谨慎投稿!On Hold 期刊影响因子不降反升?附目前On Hold期刊影响因子变化表

【SciencePub学术】大家有没有发现一个现象,就是现在“on hold”期刊貌似越来越频繁了。一旦期刊在发文量、国人占比、引用异常、撤稿频繁等方面稍微碰触红线,便会喜提一个“on hold”标识~ 近日,2023JCR正式发布,今天小编带大家看…

Ansible自动化运维,(1)模块

ansible是基于Python语言实现的,模块化:调用特定的模块完成特定的任务,支持自定义模块,可使用任何编程语言写模块(账号,软件等)。部署简单,基于python和SSH,相对安全,基于OpenSSH。 …

论文阅读MVBench: A Comprehensive Multi-modal Video Understanding Benchmark

摘要(Abstract): 论文介绍了MVBench,这是一个全新的多模态视频理解基准测试,旨在评估多模态大型语言模型(MLLMs)在视频理解方面的能力。 目前许多基准测试主要集中在静态图像任务的空间理解上,而忽视了动…

会声会影2024免费版下载无需激活码序列号

亲爱的影像爱好者们,今天我要和大家分享的是一款让我彻底着迷的软件——会声会影2024!自从用了它,我的视频编辑技能简直突飞猛进,每次上传作品到小红书都能收获满满的赞👍。接下来,就让我带你一起探索这个神…

华为VPN通过安当ASP身份认证系统快速实现认证

华为VPN通过安当ASP身份认证系统实现认证的过程,主要涉及到Radius OTP(一次性密码)认证技术的使用。以下是实现这一过程的详细步骤: 1. 前提条件: 确保系统已经激活了Radius模块,并在安全设置中的RADIUS配…

ppdetection-2.7

1, pip install -r requirement.txt 2、 ValueError: paddle.load can not parse the file:C:\Users\HX/.cache/paddle/weights\deepsort_pcb_pyramid_r101.pdparams. 重新下载模型 3、 declarative() got an unexpected keyword argument看一下参数是否写对,比如…

Python文本挖掘数据分析——竞争分析(1)

文章目录 前言项目背景与目标品类分布分析数据准备与处理查看数据类目作图查看占比的不同 适用对象作图查看适用对象占比 产品结构分析对商品分类汇总定义作图函数拜耳安速科凌虫控 前言 数据说明: 项目背景与目标 该项目旨在分析三个品牌(拜耳、安速、科凌虫控&…

lambdastreammaven

1.Lambda &#xff08;1&#xff09;Java 8 Lambda 表达式 在 Java 8 以前&#xff0c;若我们想要把某些功能传递给某个方法&#xff0c;总要去写内部类 或匿名内部类类。代码示例&#xff1a; list.sort(new Comparator<User>() { Override public int compare(User …

java实现一个图的最短路径算法

import java.util.*; //java实现一个图的最短路径算法 public class Test_34 { // 定义一个常量INF&#xff0c;表示无穷大。private static final int INF Integer.MAX_VALUE; // 定义一个方法dijkstra&#xff0c;接受一个二维数组图和一个起始节点作为参数。public s…

apk反编译修改教程系列-----去除apk软件更新方法步骤列举 记录八种最常见的去除方法

在前面几期博文中 有说明去除apk软件更新的步骤方法。我们在对应软件反编译去除更新中要灵活运用。区别对待。同一个软件可以有不同的去除更新方法可以适用。今天的教程对于软件更新去除列举几种经常使用的修改步骤。 通过基础课程可以了解 1-----软件反编译更新去除的几种常…

经典游戏案例:仿植物大战僵尸

学习目标&#xff1a;仿植物大战僵尸核心玩法实现 游戏画面 项目结构目录 部分核心代码 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; using Random UnityEngine.Random;public enum…

CSS打印设置页眉页脚

之前写过一篇文章CSS实现自动分页打印同时每页保留重复的自定义内容&#xff0c;可以实现window.print()打印时多张页面保留相同的内容&#xff08;如header、footer&#xff09;&#xff0c;但其并不是真正意义上的页眉页脚&#xff0c;footer内容在最后一张页面未撑满时不能置…

Java高级重点知识点-12-Collection、iterator迭代器、泛型

文章目录 Collection集合Iterator迭代器泛型&#xff08;难点&#xff09; Collection集合 集合是java中提供的一种容器&#xff0c;可以用来存储多个数据。 集合框架 单列集合java.util.Collection双列集合java.util.Map 集合类继承体系图&#xff1a; List集合的特点&am…

【大数据】大数据的核心特征与挑战:Volume、Velocity、Variety、Veracity

目录 Volume&#xff1a;海量数据的挑战与机遇 挑战 技术挑战 机遇 Velocity&#xff1a;数据处理的速度与实时性 挑战 技术挑战 机遇 Variety&#xff1a;数据类型的多样性与复杂性 挑战 技术挑战 机遇 Veracity&#xff1a;数据的真实性与质量控制 挑战 技术挑…

【Chapter7】虚拟存储系统,计算机操作系统教程,第四版,左万利,王英

文章目录 [toc]零、前言一、外存资源管理1.1 外存空间划分1.2 外存空间分配1.2.1 空闲块链(慢)1.2.2 空闲块表(UNIX)1.2.3 字位映像图 1.3 进程与外存对应关系 二、虚拟页式存储系统2.1 基本原理2.2 内存页框分配策略2.3 外存块的分配策略2.4 页面调入时机2.5 置换算法2.5.1 最…

Oracle详情数据库索引事务视图触发器分区发生死锁数据字典【Oracle】

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…