卷积神经网络(CNN)是一种专门用于处理具有网格结构数据的神经网络架构,最常见的应用领域是图像处理。
与传统的全连接神经网络不同,CNN 通过局部感知和参数共享来有效地处理高维数据,使其在图像分类、目标检测、语义分割等任务中表现出色。
图片
卷积神经网络的基本结构
卷积神经网络的核心思想是通过局部感知区域和权重共享来有效减少参数数量,同时保留空间信息。它通常由卷积层、池化层以及全连接层组成。
卷积层
卷积层是 CNN 的核心部分,用来提取输入数据的局部特征。
卷积层通过多个卷积核对输入进行卷积操作,生成特征图(feature maps)。
如下图所示,对于大小为 7x7x3 的输入,应用两个卷积核,每个卷积核通过对三个输入通道进行卷积来提取不同的特征图。
图片
卷积核是一组权重,它们通过滑动窗口的方式在输入上进行卷积运算。
每个卷积核会与输入的局部区域进行点积,生成一个值,这些值组成输出特征图。
图片
卷积层通常有三个重要参数
- 卷积核大小
通常为 3x3 或 5x5,它用来定义卷积核的尺寸。 - 步幅(Stride)
卷积核在输入上滑动时的步长。
步幅越大,输出特征图的尺寸越小。 - 填充(Padding)为了保持输出特征图的大小,通常在输入图像边界处填充0。这可以控制输出的尺寸,并避免输入尺寸缩小过快。
图片
池化层
池化层用于对卷积层输出的特征图进行下采样,减少特征图的尺寸,从而减少计算量和内存需求,同时提高模型的鲁棒性。
池化层通常有最大池化(Max Pooling)和平均池化(Average Pooling)两种。
- 最大池化(Max Pooling)
最大池化从一个池化窗口中选取最大值 - 平均池化(Average Pooling)
平均池化是对池化窗口中的元素求平均值
图片
全连接层
全连接层与普通的前馈神经网络类似,是 CNN 的后几层,它通常用在卷积层和池化层提取到的特征图之后,用来进行分类或回归任务。
全连接层的主要作用是对卷积层提取的特征进行进一步的组合和处理,从而输出模型的最终预测结果。
图片
案例分享
以下是一个使用卷积神经网络(CNN)进行手写数字识别的案例代码,基于经典的 MNIST 数据集。
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
train_images = train_images.reshape((train_images.shape[0], 28, 28, 1)).astype('float32') / 255
test_images = test_images.reshape((test_images.shape[0], 28, 28, 1)).astype('float32') / 255
# 搭建 CNN 模型
model = models.Sequential()
# 第一层卷积层:卷积核大小为 3x3,输出 32 个特征图
model.add(layers.Conv2D(32, (3, 3), activatinotallow='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2))) # 2x2 最大池化层
# 第二层卷积层
model.add(layers.Conv2D(64, (3, 3), activatinotallow='relu'))
model.add(layers.MaxPooling2D((2, 2)))
# 第三层卷积层
model.add(layers.Conv2D(64, (3, 3), activatinotallow='relu'))
# 将特征图展平
model.add(layers.Flatten())
# 全连接层
model.add(layers.Dense(64, activatinotallow='relu'))
model.add(layers.Dense(10, activatinotallow='softmax'))
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()
history = model.fit(train_images, train_labels, epochs=5,
validation_data=(test_images, test_labels))
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print(f'\nTest accuracy: {test_acc}')
# 可视化训练过程
plt.plot(history.history['accuracy'], label='Accuracy rate')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')
plt.show()
图片