易 AI - 机器学习卷积神经网络(CNN)

上一篇介绍了如何在 TensorFlow 中加载数据集。从本文开始将以王者荣耀为例,介绍卷积神经网络(CNN)。由于涉及的内容较多,本文主要先介绍以下内容:

  • 卷积神经网络结构
  • TensorFlow 中定义卷积神经网络模型
  • 宏观理解卷积神经网络

卷积神经网络结构

王者荣耀案例网络模型图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
sequential (Sequential)      (None, 224, 224, 3)       0
_________________________________________________________________
rescaling_1 (Rescaling)      (None, 224, 224, 3)       0
_________________________________________________________________
conv2d (Conv2D)              (None, 222, 222, 16)      448
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 111, 111, 16)      0
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 109, 109, 32)      4640
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 54, 54, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 52, 52, 64)        18496
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 26, 26, 64)        0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 24, 24, 128)       73856
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 12, 12, 128)       0
_________________________________________________________________
dropout (Dropout)            (None, 12, 12, 128)       0
_________________________________________________________________
flatten (Flatten)            (None, 18432)             0
_________________________________________________________________
dense (Dense)                (None, 128)               2359424
_________________________________________________________________
dense_1 (Dense)              (None, 3)                 387
=================================================================
Total params: 2,457,251
Trainable params: 2,457,251
Non-trainable params: 0

以上为王者荣耀案例的网络模型图和模型 summary ,可以看出模型分为输入层(Input Layer)、隐藏层(Hidden Layer)、输出层(Ouput Layer)

输入层

输入层指定了输入数据的 shape。案例中的输入为宽高 224 ,通道数 3 的图像,所以,input_shape(224,224,3)

1
2
3
4
    layers.experimental.preprocessing.RandomFlip("horizontal",
                                                 input_shape=(img_height,
                                                              img_width,
                                                              3))

注:由于使用了数据增强,所以 input_shape 的指定包含在了 data_augmentation 中。

隐藏层

在隐藏层中,案例主要是嵌套了几次卷积(Conv2D)最大池化(MaxPooling2D),然后使用 DropoutFlatten,最后使用全连接层(Dense)连接。

1
2
3
4
5
6
7
8
9
10
11
 layers.Conv2D(16, 3, activation='relu'),
 layers.MaxPooling2D(),
 layers.Conv2D(32, 3, activation='relu'),
 layers.MaxPooling2D(),
 layers.Conv2D(64, 3, activation='relu'),
 layers.MaxPooling2D(),
 layers.Conv2D(128, 3, activation='relu'),
 layers.MaxPooling2D(),
 layers.Dropout(0.2),
 layers.Flatten(),
 layers.Dense(128, activation='relu'),

输出层

输出层使用全连接层(Dense)实现分类输出。因为,案例最终分为 3 个英雄,因此指定 Dense 的 units3

1
layers.Dense(len(class_names), activation='softmax')

TensorFlow 中定义卷积神经网络模型

TensorFlow keras 模块 提供了非常便利的 Sequential 来定义模型。利用 Sequential 就可以将网络模型图直接“翻译”成 TensorFlow 代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential

model = Sequential([
  data_augmentation,
  layers.experimental.preprocessing.Rescaling(1./255),
  layers.Conv2D(16, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(32, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Conv2D(128, 3, activation='relu'),
  layers.MaxPooling2D(),
  layers.Dropout(0.2),
  layers.Flatten(),
  layers.Dense(128, activation='relu'),
  layers.Dense(len(class_names), activation='softmax')
])

其中,每一种 layerConv2D、MaxPooling2D、Dropout、Flatten、Dense) 在 keras 中都有对应的实现,具体可以参见 tf.keras.layers

注:除了 Sequential 其实还有许多方法可以定义模型,不过对于初学者 Sequential 基本够用了,再后续的课程中,我们再介绍其他方式。

宏观理解卷积神经网络

通过以上的讲述,大家已经知道了卷积神经网络的结构,并且知道如何在 TensorFlow 中定义它。但是,为什么卷积神经网络要设计成这样的结构呢?

全连接

为了回答这个问题,我们先来看个例子。

通过人眼看这上图的全局,我们可以直接识别出这是 ;如果机器要去看这张图的全局,其实就是要查看图中所有的像素(224 _ 224 _ 3);对应的网络,其实就是全连接网络

这个网络看起来像是在暴力解决问题,而且准确率低下。原因在于,总是查看全局才能识别出来,就会失去泛化能力,会出现训练集结果很好,测试和验证集效果不好,也就是过拟合(Overfitting)

这里,我打个比方,帮助大家理解。总是查看全局,就相当于要识别刚才的图是 ,那就需要看到他的头、铠甲、手臂、刀、背景、腿等

那么,如果给出上图,那机器就会不认为他是了,但事实上,人家只是秀一下肌肉而已

因此,全连接层的缺点在于,只看全局,缺少泛化能力

采样

看以上两张分辨率不同的图,人眼都能分别出是。这其实是因为,下采样(降低分辨率)后的图,并没有减少大部分的识别特征,图中依旧保留着头、铠甲、手臂、刀、背景、腿等

也就是说,适当地对图像进行下采样处理,并不会影响识别。既然这样,我们就可以在全连接层前面,对图像做一个预处理。这相当于,在全连接网络前面,加一个 MaxPooling 层。

注:关于 MaxPooling 后续会详细讲解,目前大家只需要知道 MaxPooling 的作用就是下采样即可。

这不但降低了模型参数的个数,还一定程度上,提高了泛化的能力

卷积

机器学习计算机视觉基础 中已介绍过卷积的概念。卷积核的本质就像一个滤波器(Filter)卷积实际上可以充当一个对原图像进行二次转化提取特征的作用。相对于全局,特征其实就是局部的意思。

如上图,将分成三块,发现我们还是能很快识别出来。也就是说,我们的大脑具备将分散的图像组合起来识别的能力

在看上图,将三块的位置调换下,发现我们还是能识别出来(虽然没有上面的那么快)。

也就是说:

  • 局部特征加上相对位置,就可以对物体进行识别。
  • 局部与局部之间关联性小,局部的变化,很少影响到另一个局部。

提取局部特征正是卷积具备的能力,因此,在采样前面,还可以加上卷积

但是,一张图像中的局部特征很多单独一个卷积层能提取的特征数量有限。另外,采样层选出来的特征就一定是重要的特征吗?

这时候,兄弟有难大家帮多加几个卷积和采样不就多了帮手吗?加上后,就成为了最终的网络模型。

这其实是级联分类 的思想。我们知道模型训练的时候,其实就是训练一堆的参数。而我们加了几层卷积和采样后,通过训练集数据,就会训练出一组参数,这组参数代表着特征的有效程度

因此,经过每一层卷积核采样后,都会挑出一个最符合要求的分类权值高),删除不想要的数据权值低)。这样,数据经过层层过滤,最后就得到了我们想要的数据。

在这里,每一层都是提取上一层特征后的特征,而采样层又会泛化这个特征,所以,以王者荣耀为例,可以假设地描述为

  • 第一层卷积和采样提取图像的纹理(比如:横、竖、曲等);
  • 第二层在第一层的基础上,提取到了图像的边缘信息(武器、人物、服装轮廓等);
  • 第三层提取到了图像的详细特征(人物头部、武器把手、服装质地等特征);
  • 最后,经过全连接层,比如,识别到了的头、衣服、武器,就认为这个图像里面有

小结

本文为大家介绍了卷积神经网络的网络结构,典型的卷积神经网络由卷积层、采样层、全连接层组成。

  • 卷积层负责提取图像中的局部特征
  • 采样层用来降低参数量级(降维)、防止过拟合
  • 全连接层用来输出想要的结果。

由于篇幅原因,未能将 CNN 知识点讲完。后续的文章会为大家带来更详细的解释,其中包括:卷积层、采样层、全连接层、Dropout、Flatten、Dense 等。因此,如果本文中大家有不理解的地方,不用太担心,后续会逐一细讲,咱们下一篇见。

CatchZeng
Written by CatchZeng Follow
AI (Machine Learning) and DevOps enthusiast.