作为一名人工智能的爱好者,其对CV领域更为感兴趣,本文我将使用CIFAR-10数据集进行图像分类任务,重点在于梳理人工智能项目的运行流程。其中CIFAR-10包含10个类别的60000张32x32彩色图像。我的核心目标是构建一个卷积神经网络(CNN)模型,能够准确地对这些图像进行分类,当然完成了这些基本需求,也可以适当做出扩展例如模型优化调参等等
首先确保你的开发环境中安装了以下工具和库:
Python 3.x,PyTorch,torchvision,matplotlib
可以通过以下命令安装这些库:
pip install torch torchvision matplotlib transform
温馨提示:pytorch和python版本是有对应的,如果你没有pytoch可以去官网https://pytorch.org/get-started/locally/自行下载,也可以使用镜像或者命令在你已知的环境下载。
本文因为电脑显卡有限,我采用服务器进行完成实战,这里我创建了一个py文件,之后的代码我们都将保存到这个py文件
第一步将使用torchvision
库加载和预处理CIFAR-10数据集,数据集这里我开启下载为True,这样如果代码运行的时候检查到data文件夹下面包含了数据集则不下载,若没有包含则自动下载,如果你的电脑下载过慢也可以使用镜像下载
import torch
import torchvision
import torchvision.transforms as transforms
# 数据转换和归一化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])
# 加载数据集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
接下来定义一个简单的卷积神经网络,这里面的卷积层还有参数都是可以自己调整的一般来讲模型越复杂准确率还越高但是训练时间也会越高,当然一味地追求数值未必是正确的,可以会过拟合,这点要注意一下
这里我简单的说明一下,这个类一共包含两个函数__init__
方法: 初始化网络的各个层,这里我采用了两个卷积层一个池化层一个全连接层,;forward
方法: 定义前向传播的过程,这里我使用relu激活函数。
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
self.fc1 = nn.Linear(64 * 8 * 8, 64)
self.fc2 = nn.Linear(64, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
model = SimpleCNN()
设置损失函数和优化器,并进行模型训练,时间原因我训练了10轮,你可以训练20,30,50,,,当然最终只有loss趋于平稳就代表可以了,否则就会过拟合了
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练模型
for epoch in range(10): # 训练10个epoch
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 100 == 99: # 每100个批次打印一次损失
print(f'Epoch {epoch + 1}, Batch {i + 1}, Loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Finished Training')
一个模型的好坏最终还是要在测试集上进行评估,测试集结果高才是真的好
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'Accuracy of the network on the 10000 test images: {100 * correct / total:.2f}%')
下图为评估后的模型结果,因为模型简单且训练轮次不高,这个结果已经出乎意料了
2025-07-25 09:18:39,373 - Accuracy of the network on the 10000 test images: 71.51%
为了更加直观的看到模型的损失还有测试结果,这里增加了两个可视化代码
# 可视化损失值
plt.figure(figsize=(10, 5))
plt.plot(loss_values, label='Training Loss')
plt.xlabel('Batch (x100)')
plt.ylabel('Loss')
plt.title('Training Loss Over Time')
plt.legend()
plt.savefig('training_loss.png') # Save the loss plot
plt.show()
结果来看训练损失值趋于稳定,模型逐渐收敛
def imshow(img, filename=None):
plt.figure() # 为图像创建一个新的图形
img = img / 2 + 0.5 # 反归一化
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
if filename:
plt.savefig(filename) # 保存图像
plt.show()
# 获取一些随机测试图像
dataiter = iter(testloader)
images, labels = next(dataiter)
imshow(torchvision.utils.make_grid(images), 'test_images.png')
outputs = model(images)
_, predicted = torch.max(outputs, 1)
print('Predicted: ', ' '.join(f'{trainset.classes[predicted[j]]}' for j in range(4)))
下图为部分测试图
下表为每个类别的评估指标的整体评估结果
类别 | 精确率 (Precision) | 召回率 (Recall) | F1 分数 (F1 Score) |
---|---|---|---|
airplane | 0.72 | 0.74 | 0.73 |
automobile | 0.86 | 0.81 | 0.84 |
bird | 0.59 | 0.63 | 0.61 |
cat | 0.58 | 0.47 | 0.52 |
deer | 0.62 | 0.67 | 0.65 |
dog | 0.61 | 0.60 | 0.61 |
frog | 0.69 | 0.83 | 0.76 |
horse | 0.84 | 0.71 | 0.77 |
ship | 0.83 | 0.81 | 0.82 |
truck | 0.79 | 0.81 | 0.80 |
最后将训练好的模型保存到文件中,保存后的模型权重可以进行后续微调或者web测试来用
torch.save(model.state_dict(), 'cifar10_model.pth')
本篇文章我们从0到1实战了一个CV小案例,不仅掌握了构建和训练CNN模型的基本流程,还学习了如何评估模型性能和保存模型帮助将来使用的时候得心应手。同时这些技能都是CV工程师的基础能力,若感兴趣可以在案例的基础上进行延伸扩展,试试模型优化参数调优。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。