admin管理员组文章数量:1032988
AI应用实战课学习总结(10)用CNN做图像分类
最近入坑黄佳老师的《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 删除网络卷积神经网络测试模型数据AI应用实战课学习总结(10)用CNN做图像分类
最近入坑黄佳老师的《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 删除网络卷积神经网络测试模型数据本文标签: AI应用实战课学习总结(10)用CNN做图像分类
版权声明:本文标题:AI应用实战课学习总结(10)用CNN做图像分类 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/jiaocheng/1747990473a2238403.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论