📌 一、卷积神经网络简介
卷积神经网络是一种专门处理 图像数据 的神经网络。与全连接网络不同,CNN 利用 卷积层(Convolution)和 池化层(Pooling) 提取图像特征,具有:
- 局部感知(感受野小)
- 参数共享(卷积核可复用)
- 高效计算(远少于全连接层参数)
🔧 二、CNN 基本结构
组成模块 | 作用 |
---|---|
卷积层 Conv2d | 提取图像局部特征 |
激活函数 ReLU | 非线性映射 |
池化层 MaxPool | 降采样,压缩特征尺寸 |
全连接层 Linear | 用于分类、回归等决策输出 |
🖼️ 三、输入图像格式
PyTorch 中的图像数据 shape 通常为:
[batch_size, channels, height, width]
例如一张灰度图:[1, 1, 28, 28]
,彩色图像(RGB):[1, 3, 32, 32]
🛠️ 四、CNN 模型结构示例(用于 MNIST 分类)
import torch
import torch.nn as nn
import torch.nn.functional as F
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=5, stride=1, padding=2) # 输出 16x28x28
self.pool = nn.MaxPool2d(kernel_size=2, stride=2) # 输出 16x14x14
self.conv2 = nn.Conv2d(16, 32, 5, 1, 2) # 输出 32x14x14
self.fc1 = nn.Linear(32 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10) # MNIST 是 10 类
def forward(self, x):
x = self.pool(F.relu(self.conv1(x))) # -> 16x14x14
x = self.pool(F.relu(self.conv2(x))) # -> 32x7x7
x = x.view(-1, 32 * 7 * 7) # 展平
x = F.relu(self.fc1(x))
x = self.fc2(x)
return x
📊 五、使用 MNIST 训练 CNN(完整流程)
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader
# 数据预处理
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 加载数据
trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=64, shuffle=True)
testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = DataLoader(testset, batch_size=64, shuffle=False)
🎯 六、模型训练
model = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# 训练
for epoch in range(5):
for images, labels in trainloader:
output = model(images)
loss = criterion(output, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
✅ 七、模型测试
correct = 0
total = 0
model.eval() # 设置为评估模式
with torch.no_grad():
for images, labels in testloader:
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f"测试准确率:{correct / total * 100:.2f}%")
💾 八、模型保存与加载
torch.save(model.state_dict(), 'cnn_mnist.pth')
# 加载
model.load_state_dict(torch.load('cnn_mnist.pth'))
model.eval()
📘 九、小结与拓展
组件 | 描述 |
---|---|
Conv2d | 卷积操作 |
MaxPool2d | 最大池化降采样 |
ReLU | 激活函数 |
Linear | 全连接层 |
view() | reshape 展平层 |
🧪 十、挑战练习
- 修改卷积核尺寸、层数,观察准确率变化。
- 将数据集换成 CIFAR10(RGB 图像)。
- 使用
nn.Sequential
重构 CNN 模型。 - 加入 Dropout 层防止过拟合。
发表回复