CNN卷积神经网络

CNN

核心特点是卷积操作,它可以在图像上进行滑动窗口的计算,通过滤波器(又称卷积核)和池化层(Max Pooling)来提取出图像的特征。

卷积操作可以有效地减少权重数量,降低计算量,同时也能够保留图像的空间结构信息。

池化层则可以在不改变特征图维度的前提下,减少计算量,提高模型的鲁棒性。

总览

卷积神经网络主要由两部分组成,一部分是特征提取(卷积、激活函数、池化),另一部分是分类识别(全连接层),下图便是著名的手写文字识别卷积神经网络结构图:

在这里插入图片描述

一个“卷积神经网络”(CNN)结构,如下图所示:

在这里插入图片描述

一. 卷积

img

二. 激活

常用的激活函数有sigmoid、tanh、relu等等,前两者sigmoid/tanh比较常见于全连接层,后者ReLU常见于卷积层。

激活函数的作用是用来加入非线性因素,把卷积层输出结果做非线性映射。

在卷积神经网络中,激活函数一般使用ReLU(The Rectified Linear Unit,修正线性单元),它的特点是收敛快,求梯度简单。计算公式也很简单,max(0,T),即对于输入的负值,输出全为0,对于正值,则原样输出。

三. 池化

为了有效地减少计算量,CNN使用的另一个有效的工具被称为“池化(Pooling)”。池化就是将输入图像进行缩小,减少像素信息,只保留重要信息。池化的操作也很简单,通常情况下,池化区域是2*2大小,然后按一定规则转换成相应的值。

最大池化(max-pooling)保留了每一小块内的最大值,也就是相当于保留了这一块最佳的匹配结果(因为值越接近1表示匹配越好)。也就是说,它不会具体关注窗口内到底是哪一个地方匹配了,而只关注是不是有某个地方匹配上了。

四. 全连接层

全连接层在整个卷积神经网络中起到“分类器”的作用,即通过卷积、激活函数、池化等深度网络后,再经过全连接层对结果进行识别分类。

  • 首先将经过卷积、激活函数、池化的深度网络后的结果串起来,如下图所示:
在这里插入图片描述
  • 由于神经网络是属于监督学习,在模型训练时,根据训练样本对模型进行训练,从而得到全连接层的权重(如预测字母X的所有连接的权重):

    在这里插入图片描述
  • 在利用该模型进行结果识别时,根据刚才提到的模型训练得出来的权重,以及经过前面的卷积、激活函数、池化等深度网络计算出来的结果,进行加权求和,得到各个结果的预测值,然后取值最大的作为识别的结果(如下图,最后计算出来字母X的识别值为0.92,字母O的识别值为0.51,则结果判定为X)

在这里插入图片描述

五. 特征提取实例

使用 TensorFlow 构建一个简单的卷积神经网络模型,并利用该模型对 MNIST 数据集的图像进行卷积操作,然后绘制出每个卷积核生成的特征图。

import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np

# 加载mnist数据集
mnist = tf.keras.datasets.mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

# 取10张训练集图片
images = train_images[:10]

# 将图片转换为float32类型,并进行归一化(范围在0到1之间)
images = images.astype('float32') / 255.0
# 将图片reshape成4D张量,大小为(10, 28, 28, 1)
# 也就是第一个维度表示有10张图像,每张图像由28行、28列和1个通道(灰度)组成
images = np.expand_dims(images, axis=3)
# 定义卷积核数量
num_filters = 10

# 定义卷积层
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(num_filters, (3, 3), activation='relu', input_shape=(28, 28, 1)),
])

# 计算卷积后的特征图
features = model.predict(images)

# 绘制卷积后的特征图
fig, axs = plt.subplots(nrows=num_filters, ncols=10, figsize=(10, num_filters))
for i in range(num_filters):
    for j in range(10):
        # 在子图中绘制第 j 张图像的第 i 个卷积核的特征图,使用灰度色彩映射。
        axs[i][j].imshow(features[j, :, :, i], cmap='gray')
        axs[i][j].axis('off')
plt.show()

提问

  1. 关于数据集:
  • 数据集是 MNIST,它包含手写数字的灰度图像。
  • MNIST 数据集中的图像是单通道的灰度图像,每个图像都是28x28像素,像素值介于0到255之间,表示不同灰度级别。
  1. 为什么要将图像数据转换为float32类型?
  • 数值精度和范围:在深度学习中,使用 float32 类型可以提供更高的数值精度,相比于整数类型(如 uint8),float32 可以存储更大范围的数值,同时具有足够的精度来处理复杂的数学运算和模型训练。
  • 计算准确性:深度学习模型在训练和推断过程中涉及大量的数值计算,包括梯度计算、权重更新等。使用 float32 类型可以减少数值计算中的舍入误差,从而提高模型的计算准确性和稳定性。
  • 硬件优化:现代的 GPU 和其他加速器通常更有效地处理 float32 类型的数据。因此,使用 float32 类型可以利用硬件加速器的优化,加快模型的训练速度。
  • 模型兼容性:大多数深度学习框架和模型都默认使用 float32 类型作为输入数据的标准类型。保持数据类型的一致性有助于避免类型转换错误,并确保模型能够正常运行和收敛。
  1. 定义卷积层:
model = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(num_filters, (3, 3), activation='relu', input_shape=(28, 28, 1)),
])
  • tf.keras.models.Sequential([]):使用 Keras 中的 Sequential 模型,这是一种简单的模型堆叠方式,适用于顺序的层堆叠结构。
  • tf.keras.layers.Conv2D:这是一个 2D 卷积层的类,用于处理二维图像数据。
  • num_filters:指定卷积核(滤波器)的数量,即输出的通道数。
  • (3, 3):指定每个卷积核的大小为 3x3 像素。
  • activation='relu':激活函数使用 ReLU(修正线性单元),在卷积层后应用非线性。
  • input_shape=(28, 28, 1):指定输入图像的形状。这里是高度为28像素、宽度为28像素、通道数为1(灰度图像)的图像。

结果呈现

请添加图片描述

六. LeNet——数字识别实例

下面来介绍一下 CNN 的经典模型:手写字体识别模型 LeNet5。LeNet5 诞生于 1994 年,是最早的卷积神经网络之一, 由 Yann LeCun 完成,推动了深度学习领域的发展。在那时候,没有 GPU 帮助训练模型,甚至 CPU 的速度也很慢,因此,LeNet5 通过巧妙的设计,利用卷积、参数共享、池化等操作提取特征,避免了大量的计算成本,最后再使用全连接神经网络进行分类识别,这个网络也是最近大量神经网络架构的起点,给这个领域带来了许多灵感。

LeNet5 的网络结构示意图如下所示:
img

LeNet5 由 7 层 CNN(不包含输入层)组成,上图中输入的原始图像大小是 32×32 像素,卷积层用 Ci 表示,子采样层(pooling,池化)用 Si 表示,全连接层用 Fi 表示。下面逐层介绍其作用和示意图上方的数字含义。

  1. C1 层(卷积层):6@28×28

​ 该层使用了 6 个卷积核,每个卷积核的大小为 5×5,这样就得到了 6 个 feature map(特征图)。

  • 特征图大小:

    每个卷积核(5×5)与原始的输入图像(32×32)进行卷积,这样得到的 feature map(特征图)大小为(32-5+1)×(32-5+1)= 28×28

  • 参数个数:

    由于参数(权值)共享的原因,对于同个卷积核每个神经元均使用相同的参数,因此,参数个数为(5×5+1)×6= 156,其中 5×5 为卷积核参数,1 为偏置参数

  • 连接数:

    卷积后的图像大小为 28×28,因此每个特征图有 28×28 个神经元,卷积核参数为(5×5+1)×6,因此,该层的连接数为(5×5+1)×6×28×28=122304

  1. S2 层(下采样层,也称池化层):6@14×14
  • 特征图大小:

​ 池化单元为 2×2,因此,6 个特征图的大小经池化后即变为 14×14。

  • 参数个数:

​ S2 层由于每个特征图都共享相同的 w 和 b 这两个参数,因此需要 2×6=12 个参数

  • 连接数:

​ 下采样之后的图像大小为 14×14,因此 S2 层的每个特征图有 14×14 个神经元,每个池化单元连 接数为 2×2+1(1 为偏置量),因此,该层的连接数为(2×2+1)×14×14×6 = 5880

  1. C3 层(卷积层):16@10×10

​ C3 层有 16 个卷积核,卷积模板大小为 5×5。

  • 特征图大小:

​ 与 C1 层的分析类似,C3 层的特征图大小为(14-5+1)×(14-5+1)= 10×10

  • 参数个数:

    需要注意的是,C3 与 S2 并不是全连接而是部分连接,有些是 C3 连接到 S2 三层、有些四层、甚至达到 6 层,通过这种方式提取更多特征,连接的规则如下表所示:

img

  • 连接数:

​ 卷积后的特征图大小为 10×10,参数数量为 1516,因此连接数为 1516×10×10= 151600

  1. S4(下采样层,也称池化层):16@5×5
  • 特征图大小:

​ 与 S2 的分析类似,池化单元大小为 2×2,因此,该层与 C3 一样共有 16 个特征图,每个特征图的大小为 5×5

  • 参数个数:

​ 与 S2 的计算类似,所需要参数个数为 16×2 = 32

  • 连接数:

​ 连接数为(2×2+1)×5×5×16 = 2000

  1. C5 层(卷积层):120
  • 特征图大小:

    该层有 120 个卷积核,每个卷积核的大小仍为 5×5,因此有 120 个特征图。由于 S4 层的大小为 5×5,而该层的卷积核大小也是 5×5,因此特征图大小为(5-5+1)×(5-5+1)= 1×1。这样该层就刚好变成了全连接,这只是巧合,如果原始输入的图像比较大,则该层就不是全连接了。

  • 参数个数:

​ 与前面的分析类似,本层的参数数目为 120×(5×5×16+1) = 48120

  • 连接数:

​ 由于该层的特征图大小刚好为 1×1,因此连接数为 48120×1×1=48120

  1. F6 层(全连接层):84
  • 特征图大小:

    F6 层有 84 个单元,之所以选这个数字的原因是来自于输出层的设计,对应于一个 7×12 的比特图,如下图所示,-1 表示白色,1 表示黑色,这样每个符号的比特图的黑白色就对应于一个编码。
    img
    该层有 84 个特征图,特征图大小与 C5 一样都是 1×1,与 C5 层全连接。

  • 参数个数:

    由于是全连接,参数数量为(120+1)×84=10164。跟经典神经网络一样,F6 层计算输入向量和权重向量之间的点积,再加上一个偏置,然后将其传递给 sigmoid 函数得出结果。

  • 连接数:

​ 由于是全连接,连接数与参数数量一样,也是 10164。

  1. OUTPUT 层(输出层):10

​ Output 层也是全连接层,共有 10 个节点,分别代表数字 0 到 9。如果第 i 个节点的值为 0,则 表示网络识别的结果是数字 i。

  • 特征图大小:

​ 该层采用径向基函数(RBF)的网络连接方式,假设 x 是上一层的输入,y 是 RBF 的输出,则 RBF 输出的计算方式是:

img
上式中的 Wij 的值由 i 的比特图编码确定,i 从 0 到 9,j 取值从 0 到 7×12-1。RBF 输出的值越接 近于 0,表示当前网络输入的识别结果与字符 i 越接近。

  • 参数个数:

​ 由于是全连接,参数个数为 84×10=840

  • 连接数:

​ 由于是全连接,连接数与参数个数一样,也是 840

通过以上介绍,已经了解了 LeNet 各层网络的结构、特征图大小、参数数量、连接数量等信息, 下图是识别数字 3 的过程,可对照上面介绍各个层的功能进行一一回顾:

img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值