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

【深度学习】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()
相关推荐
&永恒的星河&9 分钟前
基于TarNet、CFRNet与DragonNet的深度因果推断模型全解析
深度学习·因果推断·cfrnet·tarnet·dragonnet
Blossom.1181 小时前
使用Python和Flask构建简单的机器学习API
人工智能·python·深度学习·目标检测·机器学习·数据挖掘·flask
量子-Alex1 小时前
【反无人机检测】C2FDrone:基于视觉Transformer网络的无人机间由粗到细检测
网络·transformer·无人机
MYH5162 小时前
深度学习在非线性场景中的核心应用领域及向量/张量数据处理案例,结合工业、金融等领域的实际落地场景分析
人工智能·深度学习
Lilith的AI学习日记2 小时前
什么是预训练?深入解读大模型AI的“高考集训”
开发语言·人工智能·深度学习·神经网络·机器学习·ai编程
Jeremy_Lee1232 小时前
grafana 批量视图备份及恢复(含数据源)
前端·网络·grafana
Q同学2 小时前
TORL:工具集成强化学习,让大语言模型学会用代码解题
深度学习·神经网络·llm
禺垣2 小时前
图神经网络(GNN)模型的基本原理
深度学习
洛神灬殇3 小时前
【LLM大模型技术专题】「入门到精通系列教程」基于ai-openai-spring-boot-starter集成开发实战指南
网络·数据库·微服务·云原生·架构
上海云盾第一敬业销售3 小时前
高防IP可以防护什么攻击类型?企业网络安全的第一道防线
网络·tcp/ip·web安全