- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
文章目录
前言
本项目使用 PyTorch 框架,构建了一个基于卷积神经网络(CNN)的图像分类模型,用于对天气图像进行分类识别。整个流程从数据加载、图像预处理、模型构建、训练测试、性能评估与可视化一应俱全,具备深度学习图像分类任务的完整性与实用性。
一、CNN网络介绍
CNN 是专为图像或类似网格数据设计的神经网络结构,能自动提取图像的空间层级特征,用于分类、检测、分割等任务。
与传统神经网络(如全连接)相比,CNN 能更好地保留空间结构,参数更少。
对于一般的CNN网络来说,都是由特征提取网络和分类网络构成,其中特征提取网络用于提取图片的特征,分类网络用于将图片进行分类。
- nn.Conv2d为卷积层,用于提取图片的特征,传入参数为输入channel,输出channel,池化核大小
- nn.MaxPool2d为池化层,进行下采样,用更高层的抽象表示图像特征,传入参数为池化核大小
- nn.ReLU为激活函数,使模型可以拟合非线性数据
- nn.Linear为全连接层,可以起到特征提取器的作用,最后一层的全连接层也可以认为是输出层,传入参数为输入特征数和输出特征数(输入特征数由特征提取网络计算得到,如果不会计算可以直接运行网络,报错中会提示输入特征数的大小,下方网络中第一个全连接层的输入特征数为1600)
- nn.Sequential可以按构造顺序连接网络,在初始化阶段就设定好网络结构,不需要在前向传播中重新写一遍
一般 CNN 网络结构组成
1. 输入层
- 图像通常以形状
[batch_size, channels, height, width]
输入- MNIST:
[32, 1, 28, 28]
- CIFAR10:
[32, 3, 32, 32]
- MNIST:
2. 特征提取部分(卷积层 + 池化层)
由多个「卷积层 Conv2d」+「激活函数 ReLU」+「池化层 MaxPool2d」组成:
输入图像 → Conv → ReLU → Pool → Conv → ReLU → Pool ...
层类型 | 作用 |
---|---|
Conv2d |
提取局部特征(边缘、纹理等) |
ReLU |
非线性激活,提高模型表达能力 |
MaxPool2d |
降维,提取主特征,减少计算量 |
例如:
nn.Conv2d(in_channels=3, out_channels=16, kernel_size=3)
nn.ReLU()
nn.MaxPool2d(kernel_size=2)
#池化会让宽度、高度减半,每 2×2 区域取最大值
3. Flatten 层(展平)
将多维特征图转为一维向量,以输入全连接层:
x = torch.flatten(x, start_dim=1)
4. 分类器(全连接层 FC)
用于输出最终分类结果:
nn.Linear(特征维度, 中间层)
nn.ReLU()
nn.Linear(中间层, num_classes)
通常形如:
Flatten → FC1 → ReLU → FC2 → 输出
理解难点:
卷积层、池化层只是“网络部件”,forward()
是“怎么把这些部件连起来、一步步走下去”的说明书。
PyTorch 不会自动知道你要怎么使用你创建的那些卷积层、激活函数、全连接层,它只知道你定义了它们。所以你必须告诉它:
输入数据先过哪一层,再过哪一层,最后怎么输出。
示例:常见 CNN 架构(简化版)
class SimpleCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 16, 3, padding=1) # 输出 16×28×28
self.pool1 = nn.MaxPool2d(2) # → 16×14×14
self.conv2 = nn.Conv2d(16, 32, 3, padding=1) # → 32×14×14
self.pool2 = nn.MaxPool2d(2) # → 32×7×7
self.fc1 = nn.Linear(32 * 7 * 7, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.pool1(F.relu(self.conv1(x)))
x = self.pool2(F.relu(self.conv2(x)))
x = torch.flatten(x, start_dim=1)
x = F.relu(self.fc1(x))
return self.fc2(x)
二、前期准备
1.设置GPU
代码如下(示例):
import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os,PIL,pathlib,random
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("当前使用设备:", device)
if torch.cuda.is_available():
print("GPU 名称:", torch.cuda.get_device_name(0))
2.导入数据
代码如下(示例):
data_dir = 'E:/1-DeepLearning/projects