问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

卷积神经网络CNN入门教程

创作时间:
作者:
@小白创作中心

卷积神经网络CNN入门教程

引用
CSDN
1.
https://blog.csdn.net/F_Hawk__/article/details/137653232

卷积神经网络(CNN)是深度学习领域中处理图像数据的核心模型之一。本文将从CNN的产生动机出发,详细讲解其核心组件(卷积层、池化层、全连接层)的工作原理,并通过一个在MNIST数据集上的简单实现案例,帮助读者全面理解CNN的基本概念和应用方法。

产生的动机

卷积神经网络(Convolutional Neural Networks,CNNs)产生的动机主要来自对视觉处理和模式识别的需求。

  1. 生物学启发:卷积神经网络的设计灵感来源于对生物视觉系统的研究。在大脑中,视觉皮层的神经元对于视觉信息的处理呈现出一种局部感知和层次结构,这种结构对于处理视觉信息的效率和鲁棒性非常重要。

  2. 数据量的增长:随着互联网的发展和传感器技术的进步,我们可以获取到大量的图像数据。传统的方法在处理大规模数据时往往效率低下,而CNNs在大规模数据上的表现更加优秀,并且通常具有较强的泛化能力。

深层前馈神经网络面临着参数过多,梯度消失,非凸优化,可解释性等问题。在这个背景下,CNNs的出现为解决深层前馈神经网络(DNNs)所面临的问题提供了一种有效的解决方案。

CNN利用参数共享局部连接的特性,在处理图像等数据时能够更加高效地捕捉局部特征,减少了模型的参数数量,提高了模型的泛化能力。

局部连接:卷积层(假设L层)中的每个神经元都只和上一层中某个局部窗口内的神经元 相连,构成一个局部连接网络。

卷积层的操作

卷积层(Convolutional Layer)是卷积神经网络(CNNs)的核心组成部分,它通过卷积操作对输入数据进行特征提取。下面是卷积层的操作步骤:

1.定义卷积核:在卷积层中,有一个或多个卷积核(也称为滤波器)用于特征提取。每个卷积核都是一个小的权重矩阵,其大小通常是正方形,例如3x3或5x5。

卷积核(kernel):可以理解成NN中的权重,图像像素点想象成神经元,只不过只和 局部信息进行连接。

2.卷积操作:卷积核在输入数据上进行滑动操作,并与输入数据进行逐元素相乘,然后将相乘的结果进行求和,得到卷积操作的输出。卷积核的每一次滑动都会生成一个输出值,从而形成输出特征图(Feature Map)。

在卷积操作之后用非线性函数进行激活。 激活函数(Activation function)一般使用线性整流(ReLU)函数。

3.步幅(Stride):卷积操作中可以指定滑动的步幅,即每次滑动的距离。步幅通常设置为1,但也可以设置为其他值。步幅的选择会影响输出特征图的尺寸。

4.填充(Padding):为了控制输出特征图的尺寸,有时在输入数据的边界周围添加额外的值(通常是0),这称为填充操作。填充可以保持输入和输出的尺寸一致,也可以用于控制卷积核在边缘处的影响。

还有一些需要padding的情况,如:55的输入图,设置22的kernel,stride=2 时, 如果不做padding补0,边缘数据无法被卷积,会造成数据丢失。

5.多通道处理:如果输入数据具有多个通道(例如彩色图像具有RGB通道),则每个卷积核也有相应数量的通道,它们分别与输入数据的相应通道进行卷积操作,并将结果相加得到输出。

卷积层(Convolutional Layer )运算的目的是提取输入特征 我们往往运用多个卷积核,来产生多张Feature Map

池化层

池化层(Pooling Layer)是卷积神经网络(CNNs)中的另一个重要组成部分,用于减少特征图的空间尺寸,从而降低模型复杂度并提高计算效率。常用的池化操作包括最大池化(Max Pooling)和平均池化(Average Pooling)。

做法:将特征切成几个区域,取其最大值或平均值,得到新的、维度较小的特征。

使用池化层的原因

在卷积神经网络中,通过卷积操作获得的特征图往往具有较高的维度,直接将这些特征用于分类任务会导致非常大的计算量和参数数量,容易产生过拟合。

池化操作可以通过计算特征图中一块区域的均值或最大值等方式来减少特征图的维度,从而降低了计算量和参数数量。同时,池化操作还可以改善模型的泛化能力,减轻过拟合的现象,因为池化过程中保留了图像的主要特征,而舍弃了部分细节信息,有助于模型更好地泛化到新的数据上。

池化层往往只改变尺寸size,不改变深度。

全连接层

通常在卷积神经网络(CNNs)的架构中,全连接层(Fully Connected Layer)常常用于在卷积层和最终输出之间进行特征提取和分类。全连接层的作用是将卷积层提取的特征映射到最终的输出类别上。

卷积神经网络例子

卷积 + 激活(CONV+RELU):卷积操作通过滤波器提取图像的特征,而激活函数引入了非线性,增强了网络的表达能力。每一轮卷积可以提取图像的不同层次和抽象级别的特征,使得网络能够逐渐理解更深层次的图像信息。

池化(POOL):池化操作降低了特征图的空间维度,从而压缩了数据和减少了参数量。这不仅降低了计算复杂度,还有助于减小过拟合的风险,提高了模型的泛化能力。

全连接层:全连接层位于卷积神经网络的末尾,它将卷积层提取的特征映射到最终的输出分类上。在全连接层中,所有神经元都与前一层的所有神经元相连接,这样的设计使得网络能够将提取的特征进行整合和分类,完成最终的分类任务。

在MNIST数据集上的CNN简单实现

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader

# 定义数据预处理
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

# 加载 MNIST 数据集
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 = DataLoader(trainset, batch_size=64, shuffle=True)
testloader = DataLoader(testset, batch_size=64, shuffle=False)

# 定义卷积神经网络模型
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3)
        self.conv2 = nn.Conv2d(32, 64, 3)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(64 * 5 * 5, 128)
        self.fc2 = nn.Linear(128, 10)

    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 * 5 * 5)
        x = torch.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 实例化模型、损失函数和优化器
model = CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 训练模型
for epoch in range(5):  # 迭代 5 次
    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 个 mini-batches 输出一次损失
            print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 100))
            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('Accuracy on the test images: %d %%' % (100 * correct / total))

经典卷积神经网络

  1. LeNet-5:由 Yann LeCun 等人于 1998 年提出,是最早的卷积神经网络之一,用于手写数字识别任务。

  2. AlexNet:由 Alex Krizhevsky 等人于 2012 年提出,是第一个在 ImageNet 大规模视觉识别挑战赛中取得优异成绩的卷积神经网络模型。

  3. VGG:由 Karen Simonyan 和 Andrew Zisserman 在 2014 年提出,以其简单而有效的结构而闻名,具有统一的卷积层设计。

  4. GoogLeNet (Inception):由 Google 的研究团队在 2014 年提出,通过引入 inception 模块实现了网络的宽度和深度的平衡,同时大大减少了参数数量。

  5. ResNet:由 Kaiming He 等人于 2015 年提出,以其深层次的网络结构和残差连接(residual connections)而著名,成功解决了深度网络训练过程中的梯度消失和梯度爆炸问题。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号