本讲概述
卷积实际上就是特征提取。本讲我们先了解学习卷积神经网络基础知识,再一步步地学习搭建卷积神经网络,最后会运用卷积神经网络对cifar10 数据集分类。在本讲的最后附上几个经典卷积神经网络:LeNet、AlexNet、VGGNet、InceptionNet和 ResNet 。
一、卷积神经网络基础知识
1.卷积计算过程
卷积计算可认为是一种有效提取图像特征的方法。
一般会用一个正方形的卷积核,按指定步长,在输入特征图上滑动 ,遍历输入特征图中的每个像素点。每一个步长,卷积核会与输入 特征图出现重合区域,重合区域对应元素相乘、求和再加上偏置项 得到输出特征的一个像素点。如图所示:
上图所示的输入特征图的深度为一,即输入特征是是单通道(灰色图片)。如果输入的图片为彩色,则输入特征为三通道(红绿蓝),卷积核的深度也应为三,计算方式如下图所示:
2.感受野(Receptive Field)
定义:卷积神经网络各输出特征图中的每个像素点,在原始输入图片上映射区域的大小。
如上图所示,右边为输出特征图,它的每一个像素点(即一个小方格),映射到原始图片(左边图片)是3*3的区域,所以它的感受野是3。
如上图 ,再对输出的3*3的特征图用绿色的3*3的卷积核作用,会输出一个1*1的输出特征图。这时输出图的一个像素点映射到原始图(最左侧的图)是5*5的区域,所以它的感受野是5。
如果对5*5的原始输入图直接用蓝色的5*5的卷积核作用 ,会输出一个1*1的输出特征图。这个特征图的一个像素点映射到原始图片是5*5的区域,所以它的感受野是5。
由上述过程可知,2 层 3 * 3 卷积核和1 层 5 * 5 卷积核的特征提取能力是一样的,对比两者的计算量,如下图,我们可以知道2 层 3 * 3 卷积核的计算量更小,所以经常会采用多层小卷积核来替换一层大卷积核,在保持感受野相同的情况下减少参数量和计算量。
输出图片边长=(输入图片边长-卷积核高-1)/步长
上图计算量详细推导:
对于两个 3 * 3 卷积核来说,第一个 3 * 3 卷积核输出特征图共有(x – 3 + 1)^2 个像素点,每个像素点需要进行 3 * 3 = 9 次乘加运算,第二个 3 * 3 卷积核输出特征图共有(x – 3 + 1 – 3+ 1)^2 个像素点,每个像素点同样需要进行 9 次乘加运算,则总计算量为 9 * (x – 3 + 1)^2 +9 * (x – 3 + 1 – 3 + 1)^2 = 18 x^2 – 108x + 180;对于 5 * 5 卷积核来说,输出特征图共有(x – 5 + 1)^2 个像素点,每个像素点需要进行 5 * 5 = 25 次乘加运算,则总计算量为 25 * (x – 5 + 1)^2 = 25x^2 – 200x + 400
解18 x^2 – 200x + 400 < 25x^2 – 200x +400,经过简单数学运算可得 x < 22/7 or x > 10,x 作为特征图的边长,在大多数情况下显然会是一个大于 10 的值(非常简单的 MNIST 数据集的尺寸也达到了 28 * 28),所以两层 3 *3 卷积核的参数量和计算量,在通常情况下都优于一层 5 * 5 卷积核,尤其是当特征图尺寸比较大的情况下,两层 3 * 3 卷积核在计算量上的优势会更加明显。
3.全零填充(padding)
为了保持输出图像尺寸与输入图像一致,经常会在输入图像周围进行全零填充,如下图 ,在 5×5 的输入图像周围填 0,则输出特征尺寸同为 5×5。
Tensorflow中使用方式 :
4.批标准化(Batch Normalization,BN)
标准化:使数据符合0均值,1为标准差的分布。
批标准化:对一小批数据(batch),做标准化处理。
Batch Normalization 将神经网络每层的输入都调整到均值为 0,方差为 1 的标准正态分
布,其目的是解决神经网络中梯度消失的问题,如图所示:
BN 操作的另一个重要步骤是缩放和偏移,缩放因子 γ 以及偏移因子 β都是可训练参数,其作用如图所示:
TF描述批标准化 :tf.keras.layers.BatchNormalization(),BN层位于卷积层之后,激活层之前。
5.池化(Pooling)
池化用于减少特征数据量(降维)。 最大值池化可提取图片纹理,均值池化可保留背景特征。如图:
TF描述池化:
6.舍弃(Dropout)
在之前深度学习中叫做随机失活,在神经网络的训练过程中,将一部分神经元按照一定概率从神经网络中暂时舍弃,使用时被舍弃的神经元恢复链接,如图所示:
二、搭建卷积神经网络
1.卷积过程整合
总结:卷积就是特征提取器,就是CBAPD。
2.卷积神经网络搭建示例
主要思路为在卷积神经网络(CNN)中利用卷积核(kernel)提取特征后,送入全连接网络。如下图:
下面以下图所示卷积层和全连接层为例搭建:
Tensorflow 表示:
在此主干的基础上,利用之前写过的使用Keras 来搭建神经网络的“八股”套路。还可以添加其他内容,来完善神经网络的功能,如利用自己的图片和标签文件来自制数据集;通过旋转、缩放、平移等操作对数据集进行数据增强;保存模型文件进行断点续训;提取训练后得到的模型参数以及准确率曲线,实现可视化等。
代码如下:
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Modelnp.set_printoptions(threshold=np.inf)class Baseline(Model):def __init__(self):super(Baseline, self).__init__()self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same') # 卷积层self.b1 = BatchNormalization() # BN层self.a1 = Activation('relu') # 激活层self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same') # 池化层self.d1 = Dropout(0.2) # dropout层self.flatten = Flatten()self.f1 = Dense(128, activation='relu')self.d2 = Dropout(0.2)self.f2 = Dense(10, activation='softmax')def call(self, x):x = self.c1(x)x = self.b1(x)x = self.a1(x)x = self.p1(x)x = self.d1(x)x = self.flatten(x)x = self.f1(x)x = self.d2(x)y = self.f2(x)return ymodel = Baseline()model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/Baseline.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):print('-------------load the model-----------------')model.load_weights(checkpoint_save_path)cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,save_weights_only=True,save_best_only=True)history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])
model.summary()# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:file.write(str(v.name) + '\n')file.write(str(v.shape) + '\n')file.write(str(v.numpy()) + '\n')
file.close()############################################### show ################################################ 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
三、使用卷积神经网络
cifar10 数据集介绍:
该数据集共有 60000 张彩色图像,每张尺寸为 32 * 32,分为 10 类,每类 6000 张。训练集 50000 张,分为 5 个训练批,每批 10000 张;从每一类随机取 1000张构成测试集,共 10000 张,剩下的随机排列组成训练集,如图所示:
利用上面搭建的神经网络对cifar10 数据集进行训练,验证。
在神经网络训练前加上数据导入:
cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
结果如下:
四、经典卷积神经网络
5 个 CNN 经典网络:
1.LeNet
共享卷积核,减少网络参数。
2.AlexNet
激活函数使用 Relu,提升训练速度;Dropout 防止过拟合。TF表示:
3 VGGNet
小卷积核减少参数的同时,提高识别准确率;网络结构规整,适合并行加速。
TF表示:
4.InceptionNe
一层内使用不同尺寸的卷积核,提升感知力(通过 padding 实现输出特征面积一致);
使用 1 * 1 卷积核,改变输出特征 channel 数(减少网络参数)。
TF表示:
5.ResNe
层间残差跳连,引入前方信息,减少梯度消失,使神经网络层数变身成为可能。
TF表示: