【深度学习】AlexNet网络实现猫狗分类

news2024/11/20 2:40:12

【深度学习】AlexNet网络实现猫狗分类

AlexNet简介

AlexNet是一种卷积神经网络(Convolutional Neural Network,CNN)模型,它在2012年的ImageNet图像分类挑战赛中取得了重大突破,引发了深度学习在计算机视觉领域的热潮。下面是对AlexNet模型和CNN模型的关系以及原理的解释:

  1. AlexNet模型是一种CNN模型:
  • AlexNet是一种典型的卷积神经网络模型,它由多个卷积层、池化层和全连接层组成,通过这些层的堆叠和组合来提取图像的特征并进行分类。

  • CNN模型的原理:

  • CNN是一种专门用于处理具有网格结构的数据(如图像)的深度学习模型。它通过卷积层和池化层来提取图像的局部特征,并通过全连接层进行分类。

  • 卷积层通过卷积操作对输入图像进行特征提取,通过滑动一个卷积核(filter)在图像上进行局部特征的提取,生成特征图(feature map)。

  • 池化层通过降采样操作减小特征图的尺寸,并保留主要的特征信息。

  • 全连接层将池化层输出的特征图转换为一维向量,并通过全连接神经网络进行分类。

3.AlexNet模型的原理:

  • AlexNet模型是由Alex Krizhevsky等人提出的,它在CNN模型的基础上进行了一些创新和改进。
  • AlexNet模型的网络结构包括多个卷积层、池化层和全连接层,其中使用了ReLU激活函数来增强非线性特性。

4.AlexNet模型的特点包括:

  • 使用多个卷积层和池化层进行特征提取,通过堆叠多个卷积层来逐渐提取更高级别的特征。

  • 使用了局部响应归一化(Local Response Normalization)层来增强模型的泛化能力。

  • 使用了Dropout层来减少过拟合。

  • 使用了大规模的训练数据和数据增强技术来提高模型的性能。

  • AlexNet模型在ImageNet图像分类挑战赛中取得了显著的成绩,为后续的深度学习模型的发展奠定了基础。

总结来说,AlexNet模型是一种经典的CNN模型,它通过卷积层、池化层和全连接层来提取图像的特征并进行分类。AlexNet模型在深度学习的发展中起到了重要的作用,对后续的CNN模型设计和图像分类任务产生了深远的影响。

代码:

1.导入所需的库:
torch:PyTorch库,用于构建和训练神经网络模型。
torch.nn:PyTorch的神经网络模块,包含了构建神经网络所需的类和函数。
torch.optim:PyTorch的优化器模块,包含了各种优化算法。
torchvision.transforms:PyTorch的图像转换模块,用于对图像进行预处理。
warnings:Python的警告模块,用于忽略警告信息。
torch.utils.data:PyTorch的数据加载模块,用于加载和处理数据。
torchvision.datasets:PyTorch的数据集模块,包含了常用的图像数据集。
torchvision.models:PyTorch的预训练模型模块,包含了一些经典的神经网络模型。

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import warnings
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
from torchvision.models import alexnet
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签

2.数据预处理并加载数据:

# 检查是否有可用的GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
#cuda显卡

warnings.filterwarnings("ignore")

# 数据预处理
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# 加载训练数据和测试数据
train_dataset = ImageFolder("dataset/train", transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

test_dataset = ImageFolder("dataset/test", transform=transform)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

通过torch.cuda.is_available()函数判断是否有可用的GPU,并将设备设置为’cuda’或’cpu’。
使用torchvision.transforms.Compose函数定义了一系列的图像转换操作,包括调整大小、转换为张量、归一化等。
使用torchvision.datasets.ImageFolder类加载训练数据集和测试数据集,并应用之前定义的数据预处理操作。
使用torch.utils.data.DataLoader类将数据集包装成可迭代的数据加载器,设置批量大小和是否打乱数据。
3.定义AlexNet模型:

# 定义AlexNet模型
class AlexNet(nn.Module):
    def __init__(self, num_classes=2):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

model = AlexNet()

# 将模型移动到GPU上
model = model.to(device)

创建一个继承自torch.nn.Module的子类AlexNet,其中包含了AlexNet模型的网络结构和前向传播方法。
网络结构包括卷积层、ReLU激活函数、最大池化层和全连接层。
通过self.features定义了卷积层和池化层的结构,通过self.classifier定义了全连接层的结构。
前向传播方法将输入数据经过卷积层、池化层、全连接层等操作,得到输出结果。
创建一个AlexNet模型的实例对象model。
使用model.to(device)将模型移动到之前检查的可用设备上。
4.定义损失函数和优化器:

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

定义交叉熵损失函数nn.CrossEntropyLoss()。
定义随机梯度下降优化器optim.SGD,设置学习率和动量。
5.定义学习率调度器:

# 定义学习率调度器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

使用optim.lr_scheduler.StepLR定义学习率调度器,设置学习率衰减的步长和衰减因子。
6.训练模型:

# 训练模型
epochs = 10  # 修改为您想要的训练轮数
train_loss_list = []
train_acc_list = []
test_acc_list = []
for epoch in range(epochs):
    running_loss = 0.0
    correct = 0
    total = 0
    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    train_accuracy = correct / total
    train_loss = running_loss / len(train_loader)
    train_loss_list.append(train_loss)
    train_acc_list.append(train_accuracy)
 # 测试模型
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images = images.to(device)
            labels = labels.to(device)

            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)

            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    test_accuracy = correct / total
    test_acc_list.append(test_accuracy)

    print("Epoch {} - Training loss: {:.4f} - Training accuracy: {:.4f} - Test accuracy: {:.4f}".format(epoch, train_loss, train_accuracy, test_accuracy))

    # 更新学习率
    scheduler.step()

使用range(epochs)循环进行指定轮数的训练。
在每个epoch中,遍历训练数据集,将数据移动到设备上,通过前向传播计算输出,计算损失并进行反向传播和优化。
计算训练集的准确率和损失,并将其记录在列表中。
在每个epoch结束后,使用测试数据集评估模型的准确率,并将其记录在列表中。
打印每个epoch的训练损失、训练准确率和测试准确率。
使用学习率调度器更新学习率。
7.保存模型:

# 保存模型
torch.save(model.state_dict(), "alexnet.pth")

8.加载预训练的模型参数:

model.load_state_dict(torch.load('alexnet.pth'))

9.将模型移动到CPU上进行预测:

model = model.to('cpu')

10.可视化预测结果:

examples = enumerate(test_loader)
_, (imgs, _) = next(examples)

fig = plt.figure()
# for i in range(len(imgs)):
for i in range(20):

    img = imgs[i].numpy()
    img = img.transpose(1, 2, 0)
    img = (img + 1) / 2

    with torch.no_grad():
        output = model(torch.unsqueeze(imgs[i], 0))
        _, predicted = torch.max(output.data, 1)

    if predicted.item() == 0:
        pre_value = "狗"
    else:
        pre_value = "猫"

    plt.subplot(6, 5, i + 1)
    ###########################
    plt.tight_layout()
    plt.imshow(img)
    plt.title("预测值: {}".format(pre_value))
    plt.xticks([])
    plt.yticks([])

plt.show()

从测试数据集中获取一批图像数据。
对每个图像进行预测,并将预测结果和图像可视化展示出来。

运行结果:

在这里插入图片描述注:数据集可以更换为自己的数据集

完整代码:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import warnings
from torch.utils.data import DataLoader
from torchvision.datasets import ImageFolder
from torchvision.models import alexnet
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签

# 检查是否有可用的GPU
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
#cuda显卡

warnings.filterwarnings("ignore")

# 数据预处理
transform = transforms.Compose([
    transforms.Resize((224, 224)),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

# 加载训练数据和测试数据
train_dataset = ImageFolder("dataset/train", transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

test_dataset = ImageFolder("dataset/test", transform=transform)
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

# 定义AlexNet模型
class AlexNet(nn.Module):
    def __init__(self, num_classes=2):
        super(AlexNet, self).__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(64, 192, kernel_size=5, padding=2),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
            nn.Conv2d(192, 384, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(384, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.Conv2d(256, 256, kernel_size=3, padding=1),
            nn.ReLU(inplace=True),
            nn.MaxPool2d(kernel_size=3, stride=2),
        )
        self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
        self.classifier = nn.Sequential(
            nn.Dropout(),
            nn.Linear(256 * 6 * 6, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(inplace=True),
            nn.Linear(4096, num_classes),
        )

    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = torch.flatten(x, 1)
        x = self.classifier(x)
        return x

model = AlexNet()

# 将模型移动到GPU上
model = model.to(device)

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 定义学习率调度器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.1)

# 训练模型
epochs = 10  # 修改为您想要的训练轮数
train_loss_list = []
train_acc_list = []
test_acc_list = []
for epoch in range(epochs):
    running_loss = 0.0
    correct = 0
    total = 0
    for images, labels in train_loader:
        images = images.to(device)
        labels = labels.to(device)

        optimizer.zero_grad()

        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        running_loss += loss.item()

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

    train_accuracy = correct / total
    train_loss = running_loss / len(train_loader)
    train_loss_list.append(train_loss)
    train_acc_list.append(train_accuracy)

    # 测试模型
    correct = 0
    total = 0
    with torch.no_grad():
        for images, labels in test_loader:
            images = images.to(device)
            labels = labels.to(device)

            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)

            total += labels.size(0)
            correct += (predicted == labels).sum().item()

    test_accuracy = correct / total
    test_acc_list.append(test_accuracy)

    print("Epoch {} - Training loss: {:.4f} - Training accuracy: {:.4f} - Test accuracy: {:.4f}".format(epoch, train_loss, train_accuracy, test_accuracy))

    # 更新学习率
    scheduler.step()

# 保存模型
torch.save(model.state_dict(), "alexnet.pth")

# 加载预训练的模型参数
model.load_state_dict(torch.load('alexnet.pth'))

# 将模型移动到CPU上进行预测
model = model.to('cpu')

examples = enumerate(test_loader)
_, (imgs, _) = next(examples)

fig = plt.figure()
# for i in range(len(imgs)):
for i in range(20):

    img = imgs[i].numpy()
    img = img.transpose(1, 2, 0)
    img = (img + 1) / 2

    with torch.no_grad():
        output = model(torch.unsqueeze(imgs[i], 0))
        _, predicted = torch.max(output.data, 1)

    if predicted.item() == 0:
        pre_value = "狗"
    else:
        pre_value = "猫"

    plt.subplot(6, 5, i + 1)
    ###########################
    plt.tight_layout()
    plt.imshow(img)
    plt.title("预测值: {}".format(pre_value))
    plt.xticks([])
    plt.yticks([])

plt.show()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C知道】帮我答疑解惑:java的entity字段是map,如何映射到数据库

目录 一、问题场景描述 二、跟【C知道】第一次沟通 (1)我问 (2)他答 (3)我说 三、跟【C知道】第二次沟通 (1)我问 (2)他答 (3&#xff0…

iptables 命令说明

摘要 iptables是一个用于Linux系统的网络包过滤工具。它是一个基于内核的防火墙系统,用于配置和管理网络规则以控制网络流量。iptables可以对数据包进行过滤、转发、修改目的地、屏蔽IP等操作,可通过定义不同的规则和策略来确保网络的安全性和可靠性。 …

猫咪口味大考验:最受欢迎的猫罐头品牌揭晓!

养猫的这几年德罐也买了不少了,很早以前德罐给我的感觉就是,物美价廉,而且质量保障也不错,很美丽。但最近的德罐恕在下高攀不起了。 作为一个已经离职的宠物医生,我也发现不少人有这样的困扰吧!其实&#x…

Linux 高级管理,基于域名的虚拟Web主机

实验环境 某公司的网站服务器使用的公网IP地址为192.168.184.50并使用该IP地址注册了两个域名 www.bdqn1.com和www.jbit.com。服务器中已经安装好了 CentOS 7操作系统.并通过源码编译的 方式安装了Web服务器软件httpd-2.4.25.现需要对httpd服务进行配置.以支持同时运行这两个 W…

mybatis多表映射-分步查询

1、建库建表 create database mybatis-example; use mybatis-example; create table t_book (bid varchar(20) primary key,bname varchar(20),stuid varchar(20) ); insert into t_book values(b001,Java,s001); insert into t_book values(b002,Python,s002); insert into …

LinuxC中进程通信

LinuxC中进程通信 信号(Signals):Linux 提供了信号机制,允许一个进程向另一个进程发送信号以通知特定事件的发生。这是一种轻量级的通信机制,通常用于处理异步事件。您可以使用 kill 命令或 kill 函数来发送信号&…

小米路由器4A千兆版如何刷OpenWRT并使用固定地址远程访问

文章目录 前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 前言 OpenWRT是一个高度模块化、高度自…

基于微服务架构的餐饮系统的设计与实现-计算机毕设 附源码 86393

基于微服务架构的餐饮系统的设计与实现 摘 要 近年来,我国经济和社会发展迅速,人们物质生活水平日渐提高,餐饮行业更是发展迅速,人们对于餐饮行业的认识和要求也越来越高。传统形式的餐饮行业都是以人为本,管理起来需要很多人力、物力、财力,既不方便管理者的管理,也不方便顾…

大创项目推荐 卷积神经网络手写字符识别 - 深度学习

文章目录 0 前言1 简介2 LeNet-5 模型的介绍2.1 结构解析2.2 C1层2.3 S2层S2层和C3层连接 2.4 F6与C5层 3 写数字识别算法模型的构建3.1 输入层设计3.2 激活函数的选取3.3 卷积层设计3.4 降采样层3.5 输出层设计 4 网络模型的总体结构5 部分实现代码6 在线手写识别7 最后 0 前言…

GaussDB数据库语法及gsql入门

一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例,那连接数据库后如何使用数据库呢?那么我们今天就带大家了解一下GaussDB,以下简称GaussDB的基本语法。 关于如何连接数据库,请戳这里。 学习本节课程之后&#xff0c…

C语言——输出菱形

法一&#xff1a; #include<stdio.h> #define N 7 //假设输出7层菱形 int main(){int i;//i控制第几行 int j;//j控制每一行空格的循环个数 int k;//k控制每一行*的循环次数 for(i1;i<4;i){//将图形分为两部分,前四行(第一部分) for(j1;j<4-i;j){//输出第i行的…

【带头学C++】----- 九、类和对象 ---- 9.11 面向对象模型

❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️麻烦您点个关注&#xff0c;不迷路❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️❤️ 目 录 9.11 面向对象的框架模型 9.11.1 成员变量与函数的存储架构 代码举例说明&#xff1a; 9.11.2 this指针 9.11.4 this指针的应用…

线程互斥与同步

用户级线程 内核的LWP Linux线程 OS概念中经常说的 用户级线程 和 内核级线程 也就是线程实现真的是在OS内部实现&#xff0c;还是应用层或用户层实现 很明显Linux是属于用户级线程 用户级执行流&#xff08;用户级线程&#xff09; &#xff1a;内核lwp 1 : 1 也有1&…

Anaconda+Pytorch(GPU版)深度学习环境配置笔记

主要参考以下文章进行配置&#xff1a; https://blog.csdn.net/qq_43757976/article/details/131173301 配置版本略有更新&#xff0c;最新版本时间为2023.12.11 一、准备工作 个人电脑配置&#xff1a;laptop RTX4060 win11 个人配置版本&#xff1a;cuda&#xff08;12.1&…

虹科Pico汽车示波器 | 汽车免拆检修 | 2019款别克GL8豪华商务车前照灯水平调节故障

一、故障现象 一辆2019款别克GL8豪华商务车&#xff0c;搭载LTG发动机&#xff0c;累计行驶里程约为10.7万km。车主反映&#xff0c;车辆行驶过程中组合仪表提示前照灯水平调节故障。 二、故障诊断 接车后试车&#xff0c;起动发动机&#xff0c;组合仪表上提示“前照灯水平调节…

OWASP ESAPI 预防XSS跨站脚本攻击

跨站脚本攻击XSS案例&#xff1a;跨站脚本攻击XSS案例及其解决方案_xss攻击案例-CSDN博客 Java集成&#xff1a; 1、引入maven <!--OWASP ESAPI&#xff0c;防御 XSS跨站攻击--><dependency><groupId>org.owasp.esapi</groupId><artifactId>esa…

90%的人都值得学习微信商城的准备工作,7个关键步骤

如何做一个小程序卖东西&#xff1f;90%的人都不知道微信商城的准备工作 近几年&#xff0c;随着疫情的影响和电商的崛起&#xff0c;实体生意大家都变得越来越难做&#xff0c;越来越多的企业老板开始把矛头转向成本费用比实体门店更加低的微商城小程序&#xff0c;通过小程序…

微信小程序 bindtap 事件多参数传递

在微信小程序中&#xff0c;我们无法直接通过 bindtap"handleClick(1,2,3)" 的方式传递参数&#xff0c;而是需要通过自定义属性 data- 的方式进行传递&#xff0c;并在事件回调函数中通过 event.currentTarget.dataset 来获取这些参数。然而&#xff0c;这种传参方式…

【FPGA】数字电路设计基础

数字电路基础 1 什么是数字电路 在学习数字电路之前&#xff0c;我们先要了解下什么是数字电路。想要搞明白数字电路&#xff0c;就要搞明白生活中有 两种概念&#xff0c; 数字信号和模拟信号&#xff0c;模拟信号一般包括压力、气温、速度等信号&#xff0c;模拟量的值是可…

4s店3D虚拟云展厅让看车变得更加便捷和高效

汽车企业7203D虚拟全景展示的特点和优势主要体现在以下几个方面&#xff1a; 逼真的观赏和试乘体验&#xff1a;7203D虚拟全景展示利用虚拟现实技术&#xff0c;提供了高度逼真的汽车观赏和试乘体验。消费者可以在虚拟环境中更加深入地了解汽车的外观、内饰和功能特点&#xff…