😊你好,我是小航,一个正在变秃、变强的文艺倾年。
🔔本文讲解卷积神经网络:图像识别实战,一起卷起来叭!


目录

  • ​​一、“卷”​​
  • ​​二、LeNet-5网络​​



【人工智能原理自学】卷积神经网络:图像识别实战_人工智能

一、“卷”

这节课我们来看如何把卷积运算融入到神经网络中,我们还是以上节的“5”为例:

【人工智能原理自学】卷积神经网络:图像识别实战_人工智能_02


这是一张 8 * 8 的灰度图,用一个 3 * 3 的卷积核对它进行卷积,输出一个 6 * 6 的结果,我们把这个做卷积运算的一层称为卷积层。卷完以后我们把结果拆成一个数组,送入到后面的全连接层神经网络中。

那么问题来了,​​卷积核中的各个值​​​是多少呢?实际上,我们不必管它,随机初始化这些值就好,卷积核的值也是通过​​训练学习​​而来的。

💡那么如何​​反向传播​​调整参数呢?

【人工智能原理自学】卷积神经网络:图像识别实战_卷积_03


我们知道,卷积的过程就是:卷积核依次和这些小图(局部数据)​​对应元素相乘再相加​​得到一个值。

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_04


这个 3 * 3 的小区域的每个元素值是​​输入数据​​​,​​卷积核上的值​​​可以看作是对应输入数据的​​权值参数W​​。对应元素相乘并相加得到了一个线性函数:

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_05


当然偏置项b、激活函数也不能少:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积_06


不过还需要注意几个细节:

  • 首先这四个​​神经元的输出​​​是根据卷积的过程排列而成的​​二维​​​的结构,所以我们在送入全连接层时需要手动进行​​平铺​​。
  • 然后这四个​​神经元的输入​​​并不相同,实际上是​​同一个图片的不同区域​
  • 最后这四个神经元的​​权值参数并不是独立​​​的,它们都来自​​同一个卷积核​​​,所以实际上它们的权值参数(包括偏置项b)是一样的,我们只是把一个东西强行拆开平铺成4个。也就是说这​​四个神经元复用了同一套权重参数​​​,这就是所谓的​​参数共享​​。

【人工智能原理自学】卷积神经网络:图像识别实战_人工智能_07


相比之下我们使用全连接层,需要特别多的参数:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积核_08


而对于卷积层,由于使用参数共享,只需要使用10个参数:

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_09


实际上你想要提取多少特征就搞多少个卷积核就可以

【人工智能原理自学】卷积神经网络:图像识别实战_人工智能_10


我们都知道灰度图片是一个通道的,而彩色图片有三个通道的:

【人工智能原理自学】卷积神经网络:图像识别实战_cnn_11


此时我们的卷积运算也需要在三维上运算:

【人工智能原理自学】卷积神经网络:图像识别实战_人工智能_12

二、LeNet-5网络

在卷积网络发展的早期,深度学习领域巨头人物​​LeCun​​​在​​1988​​​年提出了一种经典的卷积神经网络结构:​​LeNet-5​

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_13


可以看出,LeNet-5就卷了两次之后再送入全连接层。

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_14


这两层立方块就是所谓的​​“池化层”​​​,我们从这个数据的左上角开始,框出 2 * 2 区域,相加取平均值,这就是所谓​​“平均池化”​​​ (当然也可以取最大值,称为​​“最大池化”​​)

【人工智能原理自学】卷积神经网络:图像识别实战_cnn_15


🔨我们简单的复现一下​​LeNet-5网络​​​:​​LeNet-5.py.py​​简单的补充说明一下:

X_train数据说明:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积_16


卷积前后图像大小的计算:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积核_17


卷积-Same模式:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积_18


卷积-Valid模式:

【人工智能原理自学】卷积神经网络:图像识别实战_深度学习_19

# 导入数据集
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import SGD
# One-Hot编码转化
from keras.utils import to_categorical
# 2D卷积层
from keras.layers import Conv2D
# 二维平均池化层
from keras.layers import AveragePooling2D
# 数组平铺
from keras.layers import Flatten

(X_train, Y_train), (X_test, Y_test) = mnist.load_data()
# 减少差距,加快梯度下降,归一化操作
X_train = X_train.reshape(60000, 28, 28, 1) / 255.0
X_test = X_test.reshape(10000, 28, 28, 1) / 255.0

Y_train = to_categorical(Y_train, 10)
Y_test = to_categorical(Y_test, 10)

model = Sequential()
# 卷积层部分
model.add(
Conv2D(
filters=6, # 卷积核/过滤器数量
kernel_size=(5, 5), # 卷积核尺寸
strides=(1, 1), # 步长
input_shape=(28, 28, 1), # 输入形状
padding='valid', # 填充模式(越卷越小)
activation='relu' # 激活函数
)
)
# 池化窗口大小为 2*2
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(
Conv2D(
filters=16, # 卷积核/过滤器数量
kernel_size=(5, 5), # 卷积核尺寸
strides=(1, 1), # 步长
padding='valid', # 填充模式(越卷越小)
activation='relu' # 激活函数
)
)
model.add(AveragePooling2D(pool_size=(2, 2)))
model.add(Flatten())
# 全连接层部分
model.add(Dense(units=120, activation='relu'))
model.add(Dense(units=84, activation='relu'))
model.add(Dense(units=10, activation='softmax'))

# 送入训练
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.05), metrics=['accuracy'])
model.fit(X_train, Y_train, epochs=100, batch_size=256)

# 评估测试集
loss, accuracy = model.evaluate(X_test, Y_test)
print("loss" + str(loss))
print("accuracy" + str(accuracy))

🚩训练结果与测试结果如下:

【人工智能原理自学】卷积神经网络:图像识别实战_卷积_20

📌 [ 笔者 ]   文艺倾年
📃 [ 更新 ] 2023.1.23
❌ [ 勘误 ] /* 暂无 */
📜 [ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!
🔍 [ 代码 ] https://github.com/itxaiohanglover/ai_lesson