【一文读懂】卷积神经网络(CNN)基础详解
《------往期经典推荐------》
一、AI应用软件开发实战专栏【链接】
项目名称 | 项目名称 |
---|---|
1.【人脸识别与管理系统开发】 | 2.【车牌识别与自动收费管理系统开发】 |
3.【手势识别系统开发】 | 4.【人脸面部活体检测系统开发】 |
5.【图片风格快速迁移软件开发】 | 6.【人脸表表情识别系统】 |
7.【YOLOv8多目标识别与自动标注软件开发】 | 8.【基于深度学习的行人跌倒检测系统】 |
9.【基于深度学习的PCB板缺陷检测系统】 | 10.【基于深度学习的生活垃圾分类目标检测系统】 |
11.【基于深度学习的安全帽目标检测系统】 | 12.【基于深度学习的120种犬类检测与识别系统】 |
13.【基于深度学习的路面坑洞检测系统】 | 14.【基于深度学习的火焰烟雾检测系统】 |
15.【基于深度学习的钢材表面缺陷检测系统】 | 16.【基于深度学习的舰船目标分类检测系统】 |
17.【基于深度学习的西红柿成熟度检测系统】 | 18.【基于深度学习的血细胞检测与计数系统】 |
19.【基于深度学习的吸烟/抽烟行为检测系统】 | 20.【基于深度学习的水稻害虫检测与识别系统】 |
21.【基于深度学习的高精度车辆行人检测与计数系统】 | 22.【基于深度学习的路面标志线检测与识别系统】 |
23.【基于深度学习的智能小麦害虫检测识别系统】 | 24.【基于深度学习的智能玉米害虫检测识别系统】 |
25.【基于深度学习的200种鸟类智能检测与识别系统】 | 26.【基于深度学习的45种交通标志智能检测与识别系统】 |
27.【基于深度学习的人脸面部表情识别系统】 | 28.【基于深度学习的苹果叶片病害智能诊断系统】 |
29.【基于深度学习的智能肺炎诊断系统】 | 30.【基于深度学习的葡萄簇目标检测系统】 |
31.【基于深度学习的100种中草药智能识别系统】 | 32.【基于深度学习的102种花卉智能识别系统】 |
33.【基于深度学习的100种蝴蝶智能识别系统】 | 34.【基于深度学习的水稻叶片病害智能诊断系统】 |
35.【基于与ByteTrack的车辆行人多目标检测与追踪系统】 | 36.【基于深度学习的智能草莓病害检测与分割系统】 |
37.【基于深度学习的复杂场景下船舶目标检测系统】 | 38.【基于深度学习的农作物幼苗与杂草检测系统】 |
39.【基于深度学习的智能道路裂缝检测与分析系统】 | 40.【基于深度学习的葡萄病害智能诊断与防治系统】 |
41.【基于深度学习的遥感地理空间物体检测系统】 | 42.【基于深度学习的无人机视角地面物体检测系统】 |
43.【基于深度学习的木薯病害智能诊断与防治系统】 | 44.【基于深度学习的野外火焰烟雾检测系统】 |
45.【基于深度学习的脑肿瘤智能检测系统】 | 46.【基于深度学习的玉米叶片病害智能诊断与防治系统】 |
47.【基于深度学习的橙子病害智能诊断与防治系统】 | 48.【基于深度学习的车辆检测追踪与流量计数系统】 |
49.【基于深度学习的行人检测追踪与双向流量计数系统】 | 50.【基于深度学习的反光衣检测与预警系统】 |
51.【基于深度学习的危险区域人员闯入检测与报警系统】 | 52.【基于深度学习的高密度人脸智能检测与统计系统】 |
53.【基于深度学习的CT扫描图像肾结石智能检测系统】 | 54.【基于深度学习的水果智能检测系统】 |
55.【基于深度学习的水果质量好坏智能检测系统】 | 56.【基于深度学习的蔬菜目标检测与识别系统】 |
57.【基于深度学习的非机动车驾驶员头盔检测系统】 | 58.【太基于深度学习的阳能电池板检测与分析系统】 |
59.【基于深度学习的工业螺栓螺母检测】 | 60.【基于深度学习的金属焊缝缺陷检测系统】 |
61.【基于深度学习的链条缺陷检测与识别系统】 | 62.【基于深度学习的交通信号灯检测识别】 |
63.【基于深度学习的草莓成熟度检测与识别系统】 | 64.【基于深度学习的水下海生物检测识别系统】 |
65.【基于深度学习的道路交通事故检测识别系统】 | 66.【基于深度学习的安检X光危险品检测与识别系统】 |
67.【基于深度学习的农作物类别检测与识别系统】 | 68.【基于深度学习的危险驾驶行为检测识别系统】 |
69.【基于深度学习的维修工具检测识别系统】 | 70.【基于深度学习的维修工具检测识别系统】 |
71.【基于深度学习的建筑墙面损伤检测系统】 | 72.【基于深度学习的煤矿传送带异物检测系统】 |
73.【基于深度学习的老鼠智能检测系统】 | 74.【基于深度学习的水面垃圾智能检测识别系统】 |
75.【基于深度学习的遥感视角船只智能检测系统】 | 76.【基于深度学习的胃肠道息肉智能检测分割与诊断系统】 |
77.【基于深度学习的心脏超声图像间隔壁检测分割与分析系统】 | 78.【基于深度学习的心脏超声图像间隔壁检测分割与分析系统】 |
79.【基于深度学习的果园苹果检测与计数系统】 | 80.【基于深度学习的半导体芯片缺陷检测系统】 |
81.【基于深度学习的糖尿病视网膜病变检测与诊断系统】 | 82.【基于深度学习的运动鞋品牌检测与识别系统】 |
83.【基于深度学习的苹果叶片病害检测识别系统】 | 84.【基于深度学习的医学X光骨折检测与语音提示系统】 |
85.【基于深度学习的遥感视角农田检测与分割系统】 |
二、机器学习实战专栏【链接】,已更新31期,欢迎关注,持续更新中~~
三、深度学习【Pytorch】专栏【链接】
四、【Stable Diffusion绘画系列】专栏【链接】
五、YOLOv8改进专栏【链接】,持续更新中~~
六、YOLO性能对比专栏【链接】,持续更新中~
《------正文------》
目录
- 卷积神经网络(CNN)
- 1、简介
- 2、CNN架构的基础
- 2.1、卷积层
- 2.2.2 卷积核(Kernel):过滤器
- 2.3:填充Padding
- 2.4:步幅Stride
- 2.5:多个过滤器和深度
- 2.6:权重共享
- 2.7:特征图创建
- 2.8、池化层
- 有两种常见的池操作类型:
- 2.9:全连接层
- 完全连接的图层如何工作
- 示例:具有128个神经元的全连接层
- 分类中的作用
- 为什么全连接层很重要
- 3:使用PyTorch构建CNN的分步指南
- 3.1、配置环境
- 3.2、准备数据
- 3.3构建CNN模型
- 3.4、定义模型
- 3.5、训练模型
- 3.6、评估模型
- 3.7、可视化结果
- 4、提高模型性能
- 4.1:数据增强
- 4.2:Dropout
- 4.3:批量标准化
- 4.4、迁移学习
- 结论
卷积神经网络(CNN)
卷积神经网络(CNN)是一类功能强大的深度学习模型,旨在处理图像等网格状数据。他们通过从原始数据中有效地提取分层特征(边缘、纹理和对象),彻底改变了计算机视觉、图像识别和医学成像等领域。
在本文中,我们将使用领先的深度学习框架PyTorch探索CNN的架构、数学和实际实现。从卷积层、池化层、过滤器(或内核)、填充和步幅等核心概念开始,我们将逐步构建和训练CNN模型。此外还介绍了一些先进的技术,如数据增强、DropOut和迁移学习,以提高性能。最后,您将深入了解CNN基础知识以及在现实世界场景中有效应用它们的技能。
1、简介
卷积神经网络(CNN)受到人类视觉皮层的启发,在从结构化网格数据(如图像)中提取特征的空间层次结构方面特别有效。图像自然地被表示为多维阵列-通常是具有对应于高度、宽度和颜色通道的维度的3D张量(例如,红色、绿色和蓝色)。这种结构化表示使图像成为CNN的理想候选者,CNN利用卷积运算来有效地处理输入数据的局部区域。
尺寸为4x 4x 3的红绿蓝(RGB)图像的3D张量。
与将输入数据视为平面向量的传统神经网络不同,CNN通过应用在图像上滑动的过滤器(或内核)来保留数据中的空间关系。这些过滤器检测边缘、纹理和形状等模式,使CNN能够逐层构建越来越复杂的特征表示。这种捕捉空间层次结构的独特能力使CNN非常适合涉及图像、视频和其他网格状结构的任务。
CNN在广泛的应用中已经变得不可或缺,包括:
- 图像分类:识别图像中的对象(例如,区分猫和狗)。
- 对象检测:定位和分类图像中的多个对象(例如,检测街道场景中的行人或车辆)。
- 语义分割:为图像中的每个像素添加标签,实现对场景的细粒度理解(例如,识别卫星图像中的道路、汽车、建筑物和植被)。
2、CNN架构的基础
要了解CNN的工作原理,深入研究其核心概念至关重要。下面,我们将探讨CNN架构的关键要素。
2.1、卷积层
CNN的主干是卷积层,它将过滤器(或内核)应用于输入数据以提取边缘,纹理和模式等特征。这些层负责检测输入中的局部模式并构建数据的分层表示。每个卷积层产生一个或多个特征图,突出显示输入的特定特征。
在数学上,卷积运算涉及在输入矩阵上滑动滤波器并计算滤波器权重与输入的对应区域之间的点积。这个过程捕获空间关系,使网络能够学习有意义的特征。
2.2.2 卷积核(Kernel):过滤器
核(或滤波器)是一个小的权重矩阵,它在输入数据上滑动以执行卷积运算。核的大小决定卷积的感受野,即,对每次计算有贡献的输入的局部区域。常见的内核大小包括3×3、5×5或7×7。
对于给定的大小为H×W的输入矩阵I和大小为K×K的滤波器F,位置(i,j)处的输出特征图O计算为:
每个过滤器检测特定类型的特征,例如水平边缘、垂直边缘或纹理。通过堆叠多个滤波器,卷积层可以并行捕获各种模式。
2.3:填充Padding
填充涉及在输入矩阵的边界周围添加额外的像素(通常为零)。填充可确保输出特征图保持与输入相同的空间维度,或防止边缘处的信息丢失。
有两种常见的填充类型:
- 有效填充:不应用填充,导致输出特征图较小。
- 相同的填充:添加填充以使输出特征图具有与输入相同的空间维度。
例如,如果您将3×3滤波器应用于具有“相同”填充的5×5输入,则输出仍为5×5。如果没有填充,输出大小将由于过滤器与边缘的重叠而缩小。
2.4:步幅Stride
步幅决定了在卷积运算期间滤波器在输入矩阵上移动的程度。步幅为1意味着过滤器一次移动一个像素,而较大的步幅跳过像素,减少输出特征图的空间维度。
在应用具有步幅S的卷积之后,用于计算输出大小的公式为:
其中:
- H和W是输入的高度和宽度,
- K是卷积核大小,
- P是填充大小,
- S是步幅。
例如,步长为2时,过滤器会跳过每隔一个像素,从而有效地将输出特征图的空间维度减半。
2.5:多个过滤器和深度
每个卷积层可以有多个过滤器,每个过滤器检测不同的特征。输出特征图的深度对应于所应用的滤波器的数量。例如,如果您对输入图像应用32个过滤器,则输出将具有32个特征图。
2.6:权重共享
与全连接层不同,卷积层在所有空间位置上共享权重。这减少了参数的数量,并实现了有效的计算。例如,如果将3×3滤波器应用于5×5输入,则在整个输入中重复使用相同的滤波器权重。
2.7:特征图创建
对输入应用过滤器的结果称为特征图。每个特征图突出显示输入数据中的特定模式或特征。例如,一个特征图可能检测水平边缘,而另一个检测垂直边缘。
让我们通过一个例子来巩固这些概念。考虑一个5×5的输入图像和一个3×3的滤波器:
**示例1(无填充,步幅为1):**输入大小:5×5,内核大小:3×3,步幅:1,填充:无
使用公式:输出大小= 15−3 +1 × 15−3 +1 =3×3
输出特征图的尺寸为3×3。
**示例2(相同填充,步幅为2):**输入大小:5×5,内核大小:3×3,步幅:2,填充:相同
使用公式:输出大小= 25−3+2(1)+1 × 25−3+2(1)+1 =3×3
输出特征图将保留与输入相同的空间维度(5×5)。
**示例3(多个过滤器):**假设我们将32个大小为3×3的过滤器应用于5×5的输入,没有填充,步幅为1。每个过滤器产生一个3×3的特征图。由于有32个过滤器,输出将由32个特征图组成,从而产生大小为32×3×3的张量。
通过了解这些基本组件-卷积层,内核,填充,步幅和权重共享-您可以深入了解CNN如何处理图像数据并提取有意义的特征。这些示例说明了每个参数如何影响输出,并展示了CNN在从结构化数据中捕获不同模式方面的灵活性。
2.8、池化层
池层在减少特征映射的空间维度方面发挥着至关重要的作用,使模型的计算效率更高,更不容易过拟合。通过总结特征图的局部区域中的信息,池化有助于保留最重要的特征,同时丢弃不太相关的细节。这种降维也减少了后续层中的参数数量,加快了训练和推理。
有两种常见的池操作类型:
最大池化:最大池化从特征图的每个局部区域获取最大值。例如,如果我们使用一个2×2的窗口来应用最大池化,则位置(i,j)处的输出计算为:
最大池化被广泛使用,因为它保留了每个区域中最突出的特征,例如边缘或纹理,这些特征通常是图像分类等任务中信息量最大的。
例如:考虑一个4×4特征图:
应用步长为2的2×2最大池化会导致:
**平均池化:**平均池化计算每个局部区域的平均值,而不是最大值。此操作平滑了特征图,并提供了输入的更全局的表示。平均池的公式为:
其中K是池化窗口的大小,S是步幅。
示例:使用与上述相同的4×4特征图,应用步长为2的2×2平均池化,结果为:
虽然最大池化强调的是最显著的特征,但平均池化捕捉了更广泛的输入摘要,使其在微妙模式很重要的场景中非常有用。
2.9:全连接层
在CNN的结尾,全连接(FC)层联合收割机结合提取的特征进行预测。这些层基于学习的表示执行分类或回归。在多个卷积层和池化层降低了空间维度并提取了高级特征之后,完全连接的层充当网络的决策组件。
完全连接的图层如何工作
全连接层中的每个神经元都连接到前一层中的每个神经元。全连接层的输出是使用线性变换和激活函数计算的:
其中:
- W是权重矩阵,
- x是输入向量(平坦化特征图),
- B是偏置项。
结果通过激活函数(例如,ReLU、softmax)引入非线性并产生最终输出。
示例:具有128个神经元的全连接层
假设最后一个池化层的输出是一个4×4×64张量(高度= 4,宽度= 4,深度= 64)。在将其馈送到全连接层之前,张量被展平为大小为4×4×64=1024的一维向量。如果全连接层具有128个神经元,则权重矩阵W将具有128×1024的维度,并且偏置向量B将具有128个元素。
全连接层中第一个神经元的计算如下:
对所有128个神经元重复该过程以产生输出向量。
分类中的作用
在分类任务中,最终的全连接层通常使用softmax激活函数来输出每个类别的概率。例如,在一个10类图像分类问题中,softmax层会生成10类的概率分布:
其中z_i是类别i的logit(原始分数)。
为什么全连接层很重要
全连接层集成了卷积层和池化层提取的分层特征,以理解数据。虽然卷积层专注于局部模式,但全连接层提供了全局视图,使网络能够做出明智的预测。
通过了解池化和全连接层的工作原理,您可以全面了解CNN如何将原始像素数据转换为有意义的预测。池化层降低了维度并强调了关键特征,而全连接层联合收割机结合了这些特征来解决分类或回归等特定任务。它们共同构成了现代深度学习架构的支柱。
3:使用PyTorch构建CNN的分步指南
现在我们理解了CNN背后的理论,让我们来看看使用PyTorch构建CNN的过程。
3.1、配置环境
在深入研究代码之前,请确保您的开发环境已正确设置。安装必要的库:
# Install PyTorch (if not already installed)
!pip install torch torchvision matplotlib
# Import necessary libraries
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
import matplotlib.pyplot as plt
3.2、准备数据
下一步是加载和预处理数据集。在这个例子中,我们将使用CIFAR-10数据集,它由10个类中的60,000个32 x32彩色图像组成,每个类6,000个图像。我们将像素值归一化为范围[-1,1],并将数据分为训练集和测试集。
# Define data transformations
transform = transforms.Compose([
transforms.ToTensor(), # Convert images to PyTorch tensors
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # Normalize pixel values to [-1, 1]
])
# Load CIFAR-10 dataset
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
# Create data loaders for batching and shuffling
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
transforms.ToTensor()
:将PIL图像或NumPy数组转换为PyTorch张量。Normalize()
:使用均值和标准差对张量进行归一化。这有助于在训练过程中更快地收敛。DataLoader
:处理数据的重排序和混洗。
3.3构建CNN模型
现在,让我们定义CNN的架构。典型的CNN由卷积层、池化层和全连接层组成。下面是一个简单的CNN架构的例子:
# Define the CNN Model
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
# Convolutional Layer 1: Input channels = 3 (RGB), Output channels = 32, Kernel size = 3x3
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
# Max Pooling Layer: Reduces spatial dimensions by half
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
# Convolutional Layer 2: Input channels = 32, Output channels = 64, Kernel size = 3x3
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
# Fully Connected Layer 1: Input size = 64 * 8 * 8, Output size = 128
self.fc1 = nn.Linear(64 * 8 * 8, 128)
# Fully Connected Layer 2: Output size = 10 (for 10 classes)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
# Apply first convolutional layer followed by ReLU activation and max pooling
x = self.pool(torch.relu(self.conv1(x)))
# Apply second convolutional layer followed by ReLU activation and max pooling
x = self.pool(torch.relu(self.conv2(x)))
# Flatten the tensor for the fully connected layer
x = x.view(-1, 64 * 8 * 8)
# Apply fully connected layer 1 with ReLU activation
x = torch.relu(self.fc1(x))
# Apply fully connected layer 2 (output layer)
x = self.fc2(x)
return x
# Instantiate the model
model = CNN()
print(model)
- 卷积层(
nn.Conv2d
):从输入图像中提取特征。 - Pooling Layers(
nn.MaxPool2d
):减少特征映射的空间维度。 - 全连接层(
nn.线性
):基于提取的特征执行分类。 - ReLU激活:在模型中引入非线性。
3.4、定义模型
在定义了模型架构之后,我们需要指定损失函数、优化器和评估指标。
# Define the loss function and optimizer
criterion = nn.CrossEntropyLoss() # Cross-Entropy Loss for multi-class classification
optimizer = optim.Adam(model.parameters(), lr=0.001) # Adam optimizer with learning rate 0.001
nn.CrossEntropyLoss()
:将nn.LogSoftmax()
和nn.NLLLoss()
组合在一个类中。它通常用于多类分类问题。optim.Adam()
:一种自适应学习率优化算法,广泛用于深度学习。
3.5、训练模型
现在,让我们使用训练数据训练模型,并评估其在测试集上的性能。我们还将在训练期间监测损失。
# Train the model
num_epochs = 10
for epoch in range(num_epochs): # Loop over the dataset multiple times
running_loss = 0.0
for i, data in enumerate(train_loader, 0):
inputs, labels = data
# Zero the parameter gradients
optimizer.zero_grad()
# Forward pass
outputs = model(inputs)
loss = criterion(outputs, labels)
# Backward pass and optimization
loss.backward()
optimizer.step()
# Print statistics
running_loss += loss.item()
if i % 100 == 99: # Print every 100 mini-batches
print(f'Epoch {epoch + 1}, Batch {i + 1}, Loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Finished Training')
- Forward Pass:计算给定输入数据的模型输出。
- 反向传递:计算损失相对于模型参数的梯度。
- 优化步骤:使用计算的梯度更新模型参数。
3.6、评估模型
最后,让我们在测试数据集上评估经过训练的模型,以衡量其准确性。
# Evaluate the model on the test set
correct = 0
total = 0
with torch.no_grad(): # Disable gradient computation for evaluation
for data in test_loader:
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 model on the test set: {100 * correct / total:.2f}%')
# Accuracy of the model on the test set: 70.78%
max()
:返回指定维度沿着最大值的索引,该维度对应于预测类。- 准确度计算:将预测标签与真实标签进行比较,以计算准确度。
3.7、可视化结果
您还可以可视化一些预测,以更好地了解模型的性能。
import numpy as np
import matplotlib.pyplot as plt
import torchvision
# Function to unnormalize and display images
def imshow(img):
img = img / 2 + 0.5 # Unnormalize
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
# Get some random test images
dataiter = iter(test_loader)
images, labels = next(dataiter) # Use Python's built-in next() function
# Display images
imshow(torchvision.utils.make_grid(images))
# Predict the labels
outputs = model(images)
_, predicted = torch.max(outputs, 1)
print('Predicted:', ' '.join(f'{predicted[j]}' for j in range(4)))
4、提高模型性能
虽然CNN功能强大,但可以使用先进技术进一步增强其性能。
4.1:数据增强
数据增强是一种通过对输入图像应用随机变换来人为增加训练数据集的大小和多样性的技术。这有助于模型更好地泛化,将其暴露给更广泛的数据,而不需要额外的标记示例。
以下是如何使用PyTorch实现数据增强:
# Define data augmentation transformations
transform = transforms.Compose([
transforms.RandomHorizontalFlip(p=0.5), # Randomly flip images horizontally
transforms.RandomRotation(10), # Randomly rotate images by up to 10 degrees
transforms.RandomResizedCrop(32, scale=(0.8, 1.0)), # Randomly crop and resize images
transforms.ToTensor(), # Convert images to PyTorch tensors
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # Normalize pixel values
])
# Load CIFAR-10 dataset with augmented data
train_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
RandomHorizontalFlip
:以给定概率水平随机翻转图像(例如,50%)。随机旋转
:在指定范围内以随机角度旋转图像。RandomResizedCrop
:随机裁剪和调整图像大小,引入比例和纵横比的可变性。
这些转换确保模型不会过度拟合训练数据的特定特征,使其对真实世界图像的变化更加鲁棒。
4.2:Dropout
Dropout是一种正则化技术,它随机地“丢弃”(即,使神经元失活)。这可以防止网络变得过于依赖特定的神经元,从而减少过度拟合并提高泛化能力。
class CNNWithDropout(nn.Module):
def __init__(self):
super(CNNWithDropout, self).__init__()
# Convolutional layers
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
# Fully connected layers
self.fc1 = nn.Linear(64 * 8 * 8, 128)
self.fc2 = nn.Linear(128, 10)
# Dropout layer
self.dropout = nn.Dropout(p=0.5) # Dropout with 50% probability
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x)))
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 64 * 8 * 8) # Flatten the tensor
x = torch.relu(self.fc1(x))
x = self.dropout(x) # Apply dropout before the final layer
x = self.fc2(x)
return x
model = CNNWithDropout()
nn.Dropout(p=0.5)
:在训练期间随机将50%的元素归零。删除层通常在完全连接的层之后应用。- 有效性:Dropout有助于防止神经元的共同适应,确保网络学习更强大的特征。
4.3:批量标准化
批量规范化(BatchNorm)将输入转换为每个层,稳定和加速训练过程。它减少了内部协变量移位,这种移位发生在训练过程中输入层的分布发生变化时。
以下是如何将批量归一化集成到CNN中:
class CNNWithBatchNorm(nn.Module):
def __init__(self):
super(CNNWithBatchNorm, self).__init__()
# Convolutional layers with batch normalization
self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=1, padding=1)
self.bn1 = nn.BatchNorm2d(32) # BatchNorm after first convolutional layer
self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)
self.bn2 = nn.BatchNorm2d(64) # BatchNorm after second convolutional layer
# Fully connected layers
self.fc1 = nn.Linear(64 * 8 * 8, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.pool(torch.relu(self.bn1(self.conv1(x)))) # Apply BatchNorm after conv1
x = self.pool(torch.relu(self.bn2(self.conv2(x)))) # Apply BatchNorm after conv2
x = x.view(-1, 64 * 8 * 8) # Flatten the tensor
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
model = CNNWithBatchNorm()
nn.BatchNorm2d(num_features)
:将批量归一化转换为2D特征图。它跨批次维度规范化激活。- 好处:批量归一化提高了训练稳定性,允许更高的学习率,并减少了对仔细权重初始化的需求。
4.4、迁移学习
迁移学习利用预先训练的模型(如ResNet,VGG或Inception),这些模型已经在ImageNet等大型数据集上训练过。通过根据您的特定任务对这些模型进行微调,即使数据有限,您也可以实现高性能。
下面是一个使用预训练的ResNet-18模型进行迁移学习的例子:
import torchvision.models as models
# Load a pre-trained ResNet-18 model
pretrained_model = models.resnet18(pretrained=True)
# Freeze all layers except the final fully connected layer
for param in pretrained_model.parameters():
param.requires_grad = False
# Replace the final fully connected layer for our specific task (10 classes)
num_ftrs = pretrained_model.fc.in_features
pretrained_model.fc = nn.Linear(num_ftrs, 10)
# Move the model to GPU if available
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
pretrained_model = pretrained_model.to(device)
# Define loss function and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(pretrained_model.fc.parameters(), lr=0.001)
- 冻结层: 通过冻结预先训练的层,我们可以防止它们在训练过程中被更新,从而使我们能够专注于微调最终层。
- 微调: 冻结后,我们将最终的全连接层替换为针对特定分类任务定制的新层。
- 优点: 迁移学习大大减少了所需的数据量和计算资源,使其成为小型数据集的理想选择。
结论
卷积神经网络是现代深度学习的基石,可以在图像识别、物体检测等方面实现突破。通过使用PyTorch了解它们的架构、数学和实际实现,您可以构建适合您特定需求的健壮模型。借助数据增强、丢弃和迁移学习等技术,您可以进一步增强其性能并应对复杂的现实挑战。
好了,这篇文章就介绍到这里,喜欢的小伙伴感谢给点个赞和关注,更多精彩内容持续更新~~
关于本篇文章大家有任何建议或意见,欢迎在评论区留言交流!