卷积神经网络(CNN)

卷积神经网络(CNN)

简介

Convolutional Neural Network(卷积神经网络,简称CNN)是一种专门用来处理具有类似网格结构的数据的神经网络,例如时间序列数据(可以认为是在时间轴上有规律地采样形成的一维网格)和图像数据(可以看作是二维的像素网格)。卷积神经网络在诸多应用领域都表现优异,尤其在大型图像处理方面。
卷积神经网络是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元。卷积神经网络包括卷积层和池化层,这两个部分是其核心组件。卷积层负责提取图像的特征,而池化层则用于减少数据的维度。在卷积神经网络中,一个神经元会观察局部范围的图片,并将这个范围内的信息转换成一个长的向量输入到神经元中,然后将输出送入下一层的神经元。

卷积神经网络(CNN)是如何工作的

1.假设我们有一张黑白的手写数字图片,这张图片的分辨率是28x28像素,也就是说它是一个28x28的二维矩阵,矩阵中的每个值代表对应像素点的灰度值(0代表黑色,255代表白色)。我们的任务是识别这张图片上的数字是几。

2.现在,我们构建一个卷积神经网络来处理这个任务。网络的第一层是一个卷积层,它包含一些滤波器(也叫卷积核或特征检测器),这些滤波器会在输入图像上滑动,对图像进行卷积运算。每个滤波器都会提取图像的一种特征,比如边缘、角点等。

3.假设我们有一个5x5的滤波器,它会在28x28的图像上滑动,每次移动一个像素。在每个位置上,滤波器都会与其覆盖的图像区域进行对应元素相乘然后求和的操作,得到一个输出值。这样,一个28x28的图像经过一个5x5的滤波器卷积后,会得到一个24x24的输出矩阵(因为28-5+1=24)。这个输出矩阵可以看作是图像的一种特征表示。

4.然后,我们可以再加一个池化层来进一步减少数据的维度。池化层通常会对输入数据进行下采样,比如取每个2x2区域的最大值或平均值。这样,24x24的输出矩阵经过2x2的最大池化后,会得到一个12x12的输出矩阵。通过堆叠多个卷积层和池化层,我们可以提取出图像的多层特征。最后,我们会将这些特征输入到一个全连接层,全连接层会输出一个10维的向量,代表这张图片属于0-9这10个数字的概率。我们可以选择概率最大的那个数字作为最终的识别结果。

流程表示

流程如上:
我们设定一个任务:

任务:识别一张28x28像素的黑白手写数字图片上的数字。
网络结构:

输入层:28x28像素的图片。

卷积层:使用5x5的滤波器(卷积核)进行卷积操作。

池化层:使用2x2的最大池化。

全连接层:输出一个10维向量,代表0-9这10个数字的概率。

现在,我们以表格形式说明每一步的数据维度变化:
网络层数据维度说明
输入层28x28x1输入的原始图片,灰度值,单通道
卷积层24x24xCC是滤波器的数量(假设我们使用多个滤波器以提取多种特征),每个滤波器卷积后得到一个24x24的特征图
池化层12x12xC对卷积层的输出进行2x2的最大池化操作,宽度和高度减半
可以继续添加卷积层和池化层,以进一步提取特征和减小数据维度
输入层10将最后的特征图展平并连接到一个全连接层,输出一个10维的向量,代表这张图片属于每个数字的概率

注意:在实际操作中,可能会有多个卷积层和池化层的堆叠,以便逐步提取更高层次和更抽象的特征。

以下是一个使用pytorch的演示

演示以前请看各api的作用:

  1. torch:

    • PyTorch的主要命名空间,提供了各种张量操作和神经网络构建工具。
  2. torch.nn:

    • PyTorch的神经网络模块,包含了用于构建神经网络的各种层和模型。
  3. nn.Module:

    • PyTorch中所有神经网络模型的基类,提供了模型构建的基本功能,例如参数管理、前向传播等。
  4. nn.Conv2d:

    • 二维卷积层,用于执行二维卷积操作。它可以通过kernel_sizestridepadding参数来定义卷积核的大小、步长和填充方式。
  5. nn.MaxPool2d:

    • 二维最大池化层,用于执行二维最大池化操作。它通过指定池化窗口大小和步长来对输入进行下采样。
  6. nn.Linear:

    • 线性层,也称为全连接层,用于执行线性变换操作。它将输入张量的每个元素与权重相乘,并加上偏置,从而得到输出张量。
  7. torch.relu:

    • ReLU激活函数,用于执行ReLU(修正线性单元)操作。它将输入张量中的负值置零,并保持正值不变。
  8. torch.randn:

    • 生成服从标准正态分布的随机张量,可以用于初始化模型参数或生成随机输入数据。
  9. .size():

    • 用于获取张量的形状(尺寸)。
  10. .view():

    • 用于调整张量的形状,可以将张量展平成一维向量或改变其维度。
  11. print():

    • 用于打印输出,显示模型的输入形状、卷积层输出特征图的形状以及模型输出的形状和值。
代码:
import torch
import torch.nn as nn

# 定义一个简单的CNN模型
class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        # 第一个卷积层,输入通道数为3,输出通道数为16,卷积核大小为3x3,步长为1,填充为1
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1)
        # 第二个卷积层,输入通道数为16,输出通道数为32,卷积核大小为3x3,步长为1,填充为1
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)
        # 最大池化层,池化窗口大小为2x2,步长为2
        self.pool = nn.MaxPool2d(2, 2)
        # 第一个全连接层,输入大小为32*8*8,输出大小为128
        self.fc1 = nn.Linear(32 * 8 * 8, 128)
        # 第二个全连接层,输入大小为128,输出大小为10,对应类别数量
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        # 输出原始输入图像的大小
        print("原始输入图像大小:", x.size())
        # 第一个卷积层后接ReLU激活函数,然后进行最大池化
        x = self.pool(torch.relu(self.conv1(x)))
        # 输出第一个卷积层的特征图大小
        print("第一个卷积层后的特征图大小:", x.size())
        # 第二个卷积层后接ReLU激活函数,然后进行最大池化
        x = self.pool(torch.relu(self.conv2(x)))
        # 输出第二个卷积层的特征图大小
        print("第二个卷积层后的特征图大小:", x.size())
        # 将特征张量展平成一维向量
        x = x.view(-1, 32 * 8 * 8)
        # 第一个全连接层后接ReLU激活函数
        x = torch.relu(self.fc1(x))
        # 第二个全连接层,不使用激活函数,因为通常在损失函数中使用交叉熵损失函数
        x = self.fc2(x)
        return x

# 创建一个随机输入张量(模拟图像数据)
input_tensor = torch.randn(1, 3, 32, 32)  # 输入张量大小为(batch_size, channels, height, width)

# 初始化模型
model = SimpleCNN()

# 使用模型进行前向传播
output = model(input_tensor)


# 打印模型输出形状和值
print("模型输出形状:", output.shape)
print("模型输出值:", output)

代码说明了CNN模型的结构和各层的参数设置,以及模型输出的形状和值

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lanlnan抱抱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值