AI应用实战课学习总结(10)用CNN做图像分类

大家好,我是Edison。最近入坑黄佳老师的《AI应用实战课》,记录下我的学习之旅,也算是总结回顾。今天是我们的第10站,一起了解CNN卷积神经网络 以及 通过CNN做图像分类任务的案例。CNN卷积神经网络介绍卷积神经网络(CNN)是一种用

AI应用实战课学习总结(10)用CNN做图像分类

大家好,我是Edison。

最近入坑黄佳老师的《AI应用实战课》,记录下我的学习之旅,也算是总结回顾。

今天是我们的第10站,一起了解CNN卷积神经网络 以及 通过CNN做图像分类任务的案例。

CNN卷积神经网络介绍

卷积神经网络(CNN)是一种用于图像识别和处理的人工神经网络,其灵感来自于动物视觉皮层的生物过程。它们由具有可学习权重和偏差的神经元组成。

CNN在至少一个层中使用一种称为卷积的技术,而不是一般的矩阵乘法,卷积是一种特殊的线性运算

下图展示了一个典型的CNN架构:输入的是图像,输出的是图像的标签。例如下图中输入了一张卡通人物(崔弟鸟)的图片,输出的是几个可能得标签及其概率,其中AI认为Tweety(动画片 崔弟鸟的名字)的概率最高。

那么,从输入到输出之间都经历了什么呢?

输入层一般是图像,这里的图像通常来说图像的张量,它是神经网络能够读取的图片的结构。然后,通过卷积层(Convolution)做图像特征的提取(一般是局部特征),再通过池化(Pooling)降低特征空间的维度,然后继续多次卷积和池化,提取上一层中的特征图的特征,随诊深度网络的加深,特征也就越来越纯,会变得越来越抽象,但神经网络可以理解。最后,经历一个展平层(Flatten Layer)进入全连接层(Fully connected Layer)做一个Softmax激活(激活函数),完成分类输出,上图中输出了3个分类,所有分类的概率值加起来之和为0.7+0.2+0.1=1。

CIFAR-10数据集

接下来,我们要做一个基于CNN的图像分类的案例,那么,就需要一个输入的图片数据集。

这里,我们了解一下CIFAR-10数据集,10代表10种常见物体,大概有6万张这10种物体的图片,这个数据集也常用于图像分类问题的教学任务。

这些图片全都是32*32的尺寸,类别包括:飞机、汽车、鸟、猫、鹿、狗、蛙、马、船、卡车,每个类别都有5000张训练图片和1000张测试图片

对于我们用PyTorch来做Demo来说,不需要我们自己将整个数据集手动下载下来并保存到某个目录,使用PyTorch提供的图像库函数会自动帮我们下载和加载到程序中,十分方便。

当程序代码完成下载后,CIFAR-10数据集也就会保存到你当前应用程序的目录下:

需要注意的是,下载下来的文件目录中的内容并不是原始的一张张图片,而是已经转化为适合PyTorch读取的格式。

基于CNN做图像分类案例

基线模型:ResNet-18

这里我们使用预训练好的ResNet-18模型作为预训练网络(或者说基线模型),它是一个典型的用于图像识别的CNN神经网络模型。它本身采用了ImageNet的大量图片做了训练,这里我们将其下载下来对我们的CIFAR10数据集做二次训练,也可以称为“迁移学习”。

对于深度学习来说,建议在GPU上进行训练,在CPU上训练会很慢很慢。

Step1. 导入所需要的库

代码语言:javascript代码运行次数:0运行复制
# 1. 导入所需要的库
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms

Step2. 下载CIFAR-10数据集

代码语言:javascript代码运行次数:0运行复制
# 2. 下载CIFAR-10数据集
# 设置图像预处理: 图像增强 + 转换为张量 + 标准化
transform = transforms.Compose(
    [transforms.RandomHorizontalFlip(),
     transforms.RandomCrop(32, padding=4),
     transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# 下载训练集和测试集
print("[LOG] Now loading CIFAR-10 dataset for Training...")
trainset = torchvision.datasets.CIFAR10(root='CIFAR10', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
                                          shuffle=True, num_workers=2)
print("[LOG] Now loading CIFAR-10 dataset for Testing...")
testset = torchvision.datasets.CIFAR10(root='CIFAR10', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
                                         shuffle=False, num_workers=2)
print("[LOG] Loading CIFAR-10 dataset finished.")

Step3. 下载预训练的ResNet-18模型

这里torchvision的models中已经带了resnet-18模型,用起来十分方便。

代码语言:javascript代码运行次数:0运行复制
# 3. 使用ResNet-18作为预训练网络
# 下载预训练的ResNet-18模型
print("[LOG] Now loading model RestNet-18...")
resnet18 = torchvision.models.resnet18(pretrained=True)
print("[LOG] Loading model ResNet-18 finished.")
# 由于CIFAR-10有10个类,我们需要调整ResNet的最后一个全连接层
num_classes = 10
resnet18.fc = nn.Linear(resnet18.fc.in_features, num_classes)

需要注意的是:由于CIFAR-10有10个类别,因此需要调整一下基线模型的最后一个全连接层,将其num_classes改为10。

Step4. 微调预训练CNN网络

这里开始定义损失函数和优化器,然后一轮又一轮地训练这个网络,并打印出损失。

代码语言:javascript代码运行次数:0运行复制
# 4. 微调预训练的CNN网络
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(resnet18.parameters(), lr=0.001, momentum=0.9)
# 迁移到GPU上(如果有的话)
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print("[LOG] Current running device: ", device)
resnet18.to(device)
# 训练网络
print("[LOG] Start training...")
for epoch in range(10):  # 就演示训练10个epochs
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # 获取输入数据
        inputs, labels = data[0].to(device), data[1].to(device)
        # 清零参数梯度
        optimizer.zero_grad()
        # 前向 + 反向 + 优化
        outputs = resnet18(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        if i % 200 == 199:  # 每200批次打印一次
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 200))
            running_loss = 0.0
print('[LOG] Training finished')

Step5. 测试训练结果(网络性能)

最后,在测试集中进行测试,并打印出该网络的准确度。

代码语言:javascript代码运行次数:0运行复制
# 5. 测试网络性能
correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data[0].to(device), data[1].to(device)
        outputs = resnet18(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()
print('[LOG] Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

刚好我这里有一个GPU Runner跑了几分钟出来了结果:

可以看到,我们借助ResNet-18在几分钟时间内就训练好了一个接近80%准确度的用于CIFAR-10数据集的模型,成本是真的很低,上手也是很快的。

当然,你也可以选择自己写一个CNN网络来做这个处理,但开发成本会高一些,而且效果也不一定有直接基于这些已有CNN网络模型做迁移的效果好。

小结

本文介绍了CNN的基本概念 以及 如何基于预训练的CNN模型对于CIFAR-10数据集做图像分类的案例。基于预训练好的CNN模型作为基线模型,针对你自己的图片数据集做二次训练(迁移学习),通常可以兼顾成本和性能,是值得采用的实践方式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-03,如有侵权请联系 cloudcommunity@tencent 删除网络卷积神经网络测试模型数据

发布者:admin,转转请注明出处:http://www.yc00.com/web/1747990438a4715846.html

相关推荐

  • AI应用实战课学习总结(10)用CNN做图像分类

    大家好,我是Edison。最近入坑黄佳老师的《AI应用实战课》,记录下我的学习之旅,也算是总结回顾。今天是我们的第10站,一起了解CNN卷积神经网络 以及 通过CNN做图像分类任务的案例。CNN卷积神经网络介绍卷积神经网络(CNN)是一种用

    5小时前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信