卷积神经网络
卷积神经网络(Convolutional Neural Network,CNN)是一种非常典型的网络 架构,常用于图像分类等任务。 所谓图像分类,就是给机器一张图像,由机器去判断这张图像的内容。卷积神经网络的设计灵感来自于生物学中的视觉系统,旨在模拟人类视觉处理的方式,已经在图像识别、目标检测、图像生成和许多其他领域取得了显著的进展,成为了计算机视觉和深度学习研究的重要组成部分。
图像原理
图像在计算机中以RGB三个通道的数值表示,数值为0到255。0表示最暗,255表示最亮。
RGB颜色模型可以用宽、高、深来描述,一张图像是一个三维的张量,其中一维代表图像的 宽,另外一维代表图像的高,还有一维代表图像的通道(channel)的数目。
神经网络的输入往往是向量,因此,将代表图像的三维张量“丢”到网络里之前,需要先将它
“拉直”。例如一张图的张量有 100 × 100 × 3 个数字,即这张图像是由 100×100×3 个数字所组成的,把这些数字排成一排就是一个巨大的向量。
卷积
在卷积神经网络中,卷积操作是指将一个可移动的小窗口(称为数据窗口,如下图绿色矩形)与图像进行逐元素相乘然后相加的操作。这个小窗口其实是一组固定的权重,它可以被看作是一个特定的滤波器(filter)或卷积核。这个操作的名称“卷积”,源自于这种元素级相乘和求和的过程。这一操作是卷积神经网络名字的来源。
神经网络
详见
卷积神经网络的特点
卷积神经网络相比于其他传统神经网络的特殊性主要在于权值共享与局部连接两个方面。
感受野(Receptive Field)
感受野这一概念来自于生物神经科学,是指感觉系统中的任一神经元,其所受到的感受器神经元的支配范围。在CNN中,一个神经节点只从输入中的一个局部区域中获取信息,这个局部区域称为当前神经节点的感受野。输入中感受野之外的区域不影响当前神经节点的值,所以要合理地控制感受野的大小,让感受野覆盖整个相关的区域。
权值共享(Parameters Sharing)
卷积核(Kernel)
图像处理时,给定输入图像,输入图像中一个小区域中像素加权平均后成为输出图像中的每个对应像素,其中权值由一个函数定义,这个函数称为卷积核。
在卷积神经网络中,卷积层中的卷积核(即滤波器)类似于一个滑动窗口,在整个输入图像中以特定的步长来回滑动,经过卷积运算之后,从而得到输入图像的特征图,即从卷积层提取出来的局部特征。
权值共享的卷积操作保证了每一个像素都有一个权重系数,只是这些系数被整个图片共享,因此大大减少了卷积核中参数量,降低了网络的复杂度;
卷积神经网络主要结构
CNN中主要包括以下结构:
- 输入层(Input layer):输入数据;
- 卷积层(Convolution layer,CONV):使用卷积核进行特征提取和特征映射;
- 激活层:非线性映射(ReLU)
- 池化层(Pooling layer,POOL):即汇聚层,进行下采样降维;
- 光栅化(Rasterization):展开像素,与全连接层全连接,某些情况下这一层可以省去;
- 全连接层(Affine layer / Fully Connected layer,FC):在尾部进行拟合,减少特征信息的损失;
- 激活层:非线性映射(ReLU)
- 输出层(Output layer):输出结果。
简单来说,卷积神经网络先由若干个卷积和池化层进行局部特征识别和降维,之后再用若干全连接层去分类。如下图所示。
输入层(Input layer)
输入层接收原始图像数据。图像通常由三个颜色通道(红、绿、蓝)组成,形成一个二维矩阵,表示像素的强度值。
卷积层(Convolution layer)
卷积
卷积,就是用一个可移动的小窗口来提取图像中的特征,这个小窗口包含了一组特定的权重,通过与图像的不同位置进行卷积操作,网络能够学习并捕捉到不同特征的信息。如下图,其中蓝色的框就是指一个数据窗口,红色框为卷积核,最后得到的绿色方形就是卷积的结果,计算过程为数据窗口中的数据与卷积核逐个元素相乘再求和。
池化层(Pooling layer)
池化(Pooling),又称汇聚,是一个下采样(Down-sample)过程,用来缩小高、长方向的尺寸,减小模型规模,提高运算速度,同时提高所提取特征的鲁棒性。
下采样
对于一副尺寸为M*N的图像Ⅰ,对其进行s倍下采样,即得到(M/s)*(N/s)尺寸的分辨率图像,当然,s应该是M和N的公约数;如果考虑是矩阵形式的图像,就是把原始图像s*s窗口内的图像变成一个像素,这个像素点的值就是窗口内所有像素的均值或者最大值(也就是Pooling池化操作等)。对图像的缩放操作并不能带来更多关于该图像的信息, 因此图像的质量将不可避免地受到影响。
常用的池化函数有:平均池化(Average Pooling / Mean Pooling)、最大池化(Max Pooling)、最小池化(Min Pooling)和随机池化(Stochastic Pooling)等,其中3种池化方式展示如下。三种池化方式各有优缺点,均值池化是对所有特征点求平均值,而最大值池化是对特征点的求最大值。而随机池化则介于两者之间,通过对像素点按数值大小赋予概率,再按照概率进行亚采样,在平均意义上,与均值采样近似,在局部意义上,则服从最大值采样的准则。
在进行特征提取的过程中,均值池化可以减少邻域大小受限造成的估计值方差,但更多保留的是图像背景信息;而最大值池化能减少卷积层参数误差造成估计均值误差的偏移,能更多的保留纹理信息。随机池化虽然可以保留均值池化的信息,但是随机概率值确是人为添加的,随机概率的设置对结果影响较大,不可估计。
全连接层(Fully Connected layer)
全连接层通常位于神经网络的最后几层,在整个卷积神经网络中起到“分类器”的作用,起到将学到的“分布式特征表示”映射到样本标记空间的作用。
前向传播
前向传播是指数据从输入层经过各层网络到达输出层的过程。在前向传播过程中,每一层的输出会作为下一层的输入,直到生成最终的输出结果。这个过程不涉及参数的更新,只是将输入数据通过网络结构计算输出。
反向传播
卷积层的反向传播
反向传播算法(BackPropagation,BP算法),是“误差反向传播”的简称,是适合于多层神经元网络的一种学习算法,它建立在梯度下降法的基础上。梯度下降法是通过计算损失函数的梯度,并将这个梯度反馈给最优化函数来更新权重以最小化损失函数。
BP算法的学习过程由正向传播过程和反向传播过程组成。在正向传播过程中,输入信息通过输入层经隐含层,逐层处理并传向输出层。如果预测值和教师值不一样,则取输出与期望的误差的平方和作为损失函数(损失函数有很多,这是其中一种)。将正向传播中的损失函数传入反向传播过程,逐层求出损失函数对各神经元权重的偏导数,作为目标函数对权重的梯度。根据这个计算出来的梯度来修改权重,网络的学习在权重修改过程中完成。误差达到期望值时,网络学习结束。
神经网络的反向传播可以分为如下2个步骤
1 计算误差
反向传播,即从后向前传播。因此计算完误差后,需要将这个误差向不断的向前一层传播。向前一层传播时,需要考虑到前一个神经元的权重系数(因为不同神经元的重要性不同,因此回传时需要考虑权重系数)。
2 更新权重
使用下式更新权重
其中η代表学习率,w'是更新后的权重
Python实践-卷积神经网络
使用tensorflow的Keras库来构建和训练一个CNN模型,以对经典的CIFAR-10数据集进行分类。
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
# 加载CIFAR-10数据集
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# 数据预处理:归一化
train_images, test_images = train_images / 255.0, test_images / 255.0
# 构建卷积神经网络模型
model = models.Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(32, 32, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(10)
])
# 编译模型
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 训练模型
history = model.fit(train_images, train_labels, epochs=10,
validation_data=(test_images, test_labels))
# 绘制训练和验证的准确率与损失
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label = 'val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0, 1])
plt.legend(loc='lower right')
plt.show()
# 评估模型
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f"Test accuracy: {test_acc}")
代码详解
1 数据集加载与预处理
CIFAR-10数据集包含60,000张32x32的彩色图像,共分为10类。我们对训练和测试图像进行归一化处理,使其像素值在0到1之间。
2 模型构建
Sequential API用于逐层搭建模型。
使用了三层卷积层(Conv2D),每层后跟一个最大池化层(MaxPooling2D)。最后一层卷积层之后,通过Flatten层将三维张量展平成一维,然后通过两层全连接层(Dense)进行分类。
3 模型编译与训练
使用Adam优化器和稀疏分类交叉熵损失函数进行编译。模型训练10个周期,使用训练数据进行训练,并在测试数据上进行验证。
4 模型评估
训练完成后,模型在测试集上进行评估,输出准确率。
Reference 参考
深度学习详解(苹果书)
【深度学习】一文搞懂卷积神经网络(CNN)的原理(超详细)_卷积神经网络原理-CSDN博客
学习笔记:深度学习(3)——卷积神经网络(CNN)理论篇_cnn理论-CSDN博客