一、引言
1、什么是卷积神经网络?
卷积神经网络(Convolutional Neural Network,简称CNN)是一种特殊的神经网络,其结构基于输入数据为图像的假设,主要由卷积层、池化(Pooling)层和全连接层构成。卷积层负责在原始图像上平移以提取特征,激活层增加非线性分割能力;池化层通过稀疏特征参数降低网络的复杂度;最后全连接层用于损失计算与分类。相比常规神经网络,卷积神经网络在前向传播函数实现上更高效,且大幅度降低了网络中参数的数量。
卷积神经网络结构图:(解释下面代码中的卷积神经网络(CNN)模型)
2、建立模型所需库
from torch.utils.data import Dataset, DataLoader
import torch
import numpy as np
from torchvision import transforms
from PIL import Image
3、建立训练模型并保存模型
详见:训练模型
详见:保存模型
二、测试模型(代码)
代码汇总:
#导入必要的库:
from torch.utils.data import Dataset, DataLoader
import torch
import numpy as np
from torchvision import transforms
from PIL import Image
#定义一个图像预处理流程,将图像调整为256x256大小,并将其转换为张量格式:
transform = transforms.Compose([
transforms.Resize([256,256]),
transforms.ToTensor()])
#加载图像,并对其进行预处理:
image = Image.open('img.png')#放入你想放的图片
image =transform(image)
image = image.unsqueeze(0) # unsqueeze是PyTorch中的一个函数,用于增加tensor的维度
#检查可用的设备(CPU、CUDA或MPS),并将设备设置为第一个可用的设备:
device = "cuda" if torch.cuda.is_available() else "mps" if torch.backends.mps.is_available() else 'cpu'
print(f"Using {device} device")
#此行根据支持 CUDA 的 GPU 和 MPS 的可用性设置变量。
# 它使用 检查启用了 CUDA 的 GPU 是否可用。如果为 true,则设置为“cuda”。
# 否则,它将使用 检查 MPS 是否可用。如果为 true,则设置为“mps”。如果两个条件都为 false,则设置为“cpu”。
#定义一个卷积神经网络(CNN)模型:
from torch import nn
#此行从 PyTorch 库中导入(神经网络)模块,该模块提供了用于构建神经网络的各种类和函数。
class CNN(nn.Module):
def __init__(self):
super(CNN,self).__init__()#此代码定义一个名为从该类继承的类。该方法是类的构造函数,用于初始化对象。
self.conv1 = nn.Sequential(
nn.Conv2d(
in_channels=3,
out_channels=16,
kernel_size=5,
stride=1,
padding=2,
),#一个 2D 卷积层,它接受具有 星火模型 个通道的输入,产生 16 个输出通道,使用内核大小为 5x5、步幅为 星火模型 和填充为 2。
nn.ReLU(),#应用逐元素整流线性单元 (ReLU) 激活的激活函数。
nn.MaxPool2d(kernel_size=2),#最大池化层,以 2 的步幅执行 2x2 池化操作。
)#此代码定义了第一个卷积层。它是用于按顺序堆叠多个图层创建的。
self.conv2 = nn.Sequential(
nn.Conv2d(16,32,5,1,2),
nn.ReLU(),
nn.Conv2d(32,32,5,1,2),
nn.ReLU(),
nn.MaxPool2d(2),
)#此代码定义了第二个卷积层。它遵循与输入和输出通道大小相似的结构,但具有不同的输入和输出通道大小。
self.conv3 = nn.Sequential(
nn.Conv2d(32, 64, 5, 1, 2),
nn.ReLU(),
)
self.out=nn.Linear(64*64*64,20)
#这一行定义了输出层,它是一个全连接(线性)层。它接受前面卷积层的平坦化输入(32 * 7 * 7)并生成一个大小为10的输出,与分类任务中的类别数匹配。
def forward(self,x):
#forward方法定义了模型的前向传播。它指定了输入x如何流经网络的不同层
x=self.conv1(x)
x = self.conv2(x)
x = self.conv3(x)
x=x.view(x.size(0),-1)
#在这种情况下,输入x通过conv1和conv2,然后通过展平操作(view)将输出展平。
x=self.out(x)
# 最后,展平后的张量被送入输出层(self.out),并返回结果。
return x
#创建一个模型实例,并将其移动到指定的设备上:
model=CNN().to(device)
# print(model)
#从磁盘加载预训练的模型参数:
model=torch.load('best.pt')
#将模型设置为评估模式(这很重要,因为它会关闭如dropout等只在训练时使用的层):
model.eval()
#创建一个数据加载器,用于在预测过程中迭代图像:
test_dataloader=DataLoader(image,batch_size=1,shuffle=True)
#在数据加载器中迭代图像,将图像移动到指定的设备上,并使用模型进行预测:
for X in test_dataloader:
X=X.to(device)
pred=model.forward(X)
print(pred)
print((pred.argmax(1).tolist())[0])
#解释```python`print((pred.argmax(1).tolist())[0])`这行代码的作用是将模型的输出(一个概率分布)转换为预测的类别标签。首先,`argmax(1)`函数找到概率分布中最大值的索引(即最有可能的类别),然后`tolist()`函数将索引转换为Python列表,最后`[0]`取出列表中的第一个元素(因为我们只有一个图像,所以列表只有一个元素)。
代码结果:
输出预测输入图片对应的标签