【深度学习】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()
相关推荐
程序员打怪兽1 天前
详解Visual Transformer (ViT)网络模型
深度学习
CoovallyAIHub3 天前
仿生学突破:SILD模型如何让无人机在电力线迷宫中发现“隐形威胁”
深度学习·算法·计算机视觉
CoovallyAIHub3 天前
从春晚机器人到零样本革命:YOLO26-Pose姿态估计实战指南
深度学习·算法·计算机视觉
CoovallyAIHub3 天前
Le-DETR:省80%预训练数据,这个实时检测Transformer刷新SOTA|Georgia Tech & 北交大
深度学习·算法·计算机视觉
CoovallyAIHub3 天前
强化学习凭什么比监督学习更聪明?RL的“聪明”并非来自算法,而是因为它学会了“挑食”
深度学习·算法·计算机视觉
CoovallyAIHub3 天前
YOLO-IOD深度解析:打破实时增量目标检测的三重知识冲突
深度学习·算法·计算机视觉
用户1474853079744 天前
AI-动手深度学习环境搭建-d2l
深度学习
OpenBayes贝式计算4 天前
解决视频模型痛点,TurboDiffusion 高效视频扩散生成系统;Google Streetview 涵盖多个国家的街景图像数据集
人工智能·深度学习·机器学习
OpenBayes贝式计算4 天前
OCR教程汇总丨DeepSeek/百度飞桨/华中科大等开源创新技术,实现OCR高精度、本地化部署
人工智能·深度学习·机器学习
DianSan_ERP5 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet