【第五章:计算机视觉】1.计算机视觉基础-(5)项目实战:利用PyTorch实现一个前馈神经网络和一个卷积神经网络
·
第五章:计算机视觉(Computer Vision)
第一部分:计算机视觉基础
第五节:项目实战:利用 PyTorch 实现一个前馈神经网络和一个卷积神经网络
一、实验目标
-
熟悉 PyTorch 基本结构:
Dataset、DataLoader、nn.Module、Optimizer。 -
分别实现 前馈神经网络(FNN) 和 卷积神经网络(CNN),并在 MNIST 手写数字数据集 上进行训练和测试。
-
比较 FNN 和 CNN 在图像任务上的效果差异。
二、环境准备
安装 PyTorch:
pip install torch torchvision
导入常用库:
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
三、数据集准备
使用 MNIST 手写数字集(28×28 灰度图):
# 数据预处理:转为Tensor并归一化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 训练集 & 测试集
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=True)
testloader = torch.utils.data.DataLoader(testset, batch_size=64, shuffle=False)
四、实现前馈神经网络(FNN)
FNN 将图像拉平成一维向量,直接输入全连接层。
class FeedForwardNN(nn.Module):
def __init__(self):
super(FeedForwardNN, self).__init__()
self.fc1 = nn.Linear(28*28, 256) # 输入层 → 隐藏层
self.fc2 = nn.Linear(256, 128) # 隐藏层 → 隐藏层
self.fc3 = nn.Linear(128, 10) # 输出层(10类)
self.relu = nn.ReLU()
def forward(self, x):
x = x.view(-1, 28*28) # 展平
x = self.relu(self.fc1(x))
x = self.relu(self.fc2(x))
x = self.fc3(x)
return x
五、实现卷积神经网络(CNN)
CNN 保留了图像的空间结构,使用卷积层提取局部特征。
class SimpleCNN(nn.Module):
def __init__(self):
super(SimpleCNN, self).__init__()
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1) # 1 通道 → 32 通道
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1) # 32 通道 → 64 通道
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(64 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
self.relu = nn.ReLU()
def forward(self, x):
x = self.relu(self.conv1(x))
x = self.pool(self.relu(self.conv2(x)))
x = x.view(-1, 64 * 7 * 7)
x = self.relu(self.fc1(x))
x = self.fc2(x)
return x
六、训练与测试函数
def train_model(model, trainloader, criterion, optimizer, epochs=5):
for epoch in range(epochs):
running_loss = 0.0
for images, labels in trainloader:
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {running_loss/len(trainloader):.4f}")
def test_model(model, testloader):
correct, total = 0, 0
with torch.no_grad():
for images, labels in testloader:
outputs = model(images)
_, predicted = torch.max(outputs, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"Accuracy: {100 * correct / total:.2f}%")
七、模型训练对比
1. 前馈神经网络(FNN)
fnn = FeedForwardNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(fnn.parameters(), lr=0.001)
train_model(fnn, trainloader, criterion, optimizer)
test_model(fnn, testloader)
2. 卷积神经网络(CNN)
cnn = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(cnn.parameters(), lr=0.001)
train_model(cnn, trainloader, criterion, optimizer)
test_model(cnn, testloader)
八、实验结果与分析
-
FNN:准确率一般在 92% 左右,因为它没有利用图像的空间信息。
-
CNN:准确率通常超过 98%,明显优于 FNN。
结论:
-
CNN 更适合处理图像任务,因为它能自动学习空间特征。
-
FNN 作为基线模型简单易懂,但在视觉任务上表现有限。
九、总结
本节通过 PyTorch 实现了:
-
前馈神经网络:结构简单,但忽略了图像空间结构。
-
卷积神经网络:利用卷积和池化提取图像特征,性能更强。
实践表明,CNN 在计算机视觉任务中比 FNN 更加适合,几乎成为图像处理任务的默认选择。
更多推荐



所有评论(0)