实战篇中,人脸识别模型的搭建看似非常复杂,其实都是由一些常用的神经网络层搭建而来,只要我们明白了这些网络层,搭建一个模型就不再困难了
神经网络搭建的方式有2种:顺序模型和函数式API
计算机视觉常用的神经网络层:全连接层、二维卷积层、池化层、BN层、dropout层、flaten层
下面我们分别介绍他们
全连接层
全连接层的每一个节点都和上一层所有的节点相连,从而把之前提取到的特征综合起来。如下图所示:
- 图中的圆圈称为神经单元
- Layer1:称为输入层
- layer4:称为输出层
- Layer2、layer3:称为隐藏层
- X 0 X_0 X0、 X 1 X_1 X1、 X 2 X_2 X2:为输入特征
- a 0 a_0 a0、 a 1 a_1 a1、 a 2 a_2 a2:为输入值X经过激活函数后的值
- W:为输入特征对应的权值,初始化后,通过反向传播修正它的值
- Z : 为a与W之间点乘的结果,比如图中的 Z 1 ( 2 ) Z_1^{(2)} Z1(2) = W 1 , 0 ( 1 ) a 0 ( 1 ) W_{1,0}^{(1)}a_0^{(1)} W1,0(1)a0(1) + W 1 , 1 ( 1 ) a 1 ( 1 ) W_{1,1}^{(1)}a_1^{(1)} W1,1(1)a1(1) + W 1 , 2 ( 1 ) a 2 ( 1 ) W_{1,2}^{(1)}a_2^{(1)} W1,2(1)a2(1)
keras调用代码
Dense(units = 4,activation = 'relu')
- units :是一个正数,表示输出空间的维度
- activation:激活函数,默认不使用激活函数,即线性激活,输入与输出相同
- use_bias:布尔型变量,代表该层是否使用偏置向量
- kernel_initializer:kernel权值矩阵的初始化器
- bias_initializer:偏置向量的初始化器
- kernel_regularizer:运用到kernel的正则化函数
- bias_regularizer:运用到偏置向量的正则化函数
- activity_regularizer:运用到输出结果的正则化函数
- kernel_constraint:运用到kernel权值矩阵的约束函数
- bias_constraint:运用到偏置向量的约束函数
总结
其实看得出,全连接层的参数非常多,参数量也非常大,从而导致计算量非常大,早期的神经网络是只有全连接的,比如我们将一张320*320的图片传入全连接,输入层的神经单元就有102400个,而且将每一个像素当做特征值输入,也十分容易出现过拟合现象。
二维卷积
在深度学习之前的人脸识别,大都采用Haar特征,Haar特征是通过不同模板来对图片进行特征提取,最后筛选出比较具有代表性的特征再使用强分类器进行分类。这个Haar特征对特征的提取方式,让我感觉像是卷积的雏形。卷积相对模块来说,它可以根据反向传播来纠正自己的“模板”中的数值,让提取特征更加有效。
工作方式
如下图:黄色的卷积核(黄色)对图片(绿色)从左到右,从上到下进行扫描并点乘,提取出右边(粉红)的特征图(feature map)。
特点
- 卷积层中使用参数共享可以来控制参数的数量,因此用卷积来替代前期的全连接,参数量更少
- 相对于全连接,可以减少过拟合现象
- 二维卷积扫描方式有“valid”和“same”2种,“same”扫描前会填充数据,以至于扫描后的特征图长宽相对于原图不会减少
- 卷积尺寸一般都不大,常用的有1x1、3x3、7x7、9x9,其中3X3最常用
- 常用的集合函数是:ReLU
keras代码
kears.layers.Conv2D(filters,kernel_size,strides=(1,1),padding='valid',data_format = None,dilation_rate=(1,1),activation = None,use_bias = true,kernel_initializer = 'glorot_uniform',bias_initializer='zeros',kernel_regularizer=None,bias_regularizer=None,activity_regularizer = None,kernel_constraint=None,bias_constraint=None)
- filters :卷积核的个数,即卷积操作后输出空间的维度
- kernel_size:可以是整数也可以是一个元祖,表示卷积窗口的宽度和高度
- strides:可以是一个整数也可以是一个元祖,表面卷积沿宽度和高度方向的步长,即卷积操作每一步移动的步长
- padding:只能为“valid”或者“same”,设置图像在卷积过程中边界像素如何填充。
- data_format:可以设置为“channels_last”(默认)或“channels_first”二者之一,表示输入中维度的顺序。
- dilation_rate:可以是一个整数,也可以是一个元祖,指定膨胀卷积的膨胀率。
- activation:卷积层要使用的激活函数。默认不激活,输入输出相同,即f(x) = x
- use_bias:布尔型变量,代表该层是否使用偏置向量
- kernel_initializer:偏置向量的初始化器
- bias_initializer:偏置向量的初始化器
- kernel_regularizer:运用到kernel的正则化函数
- bias_regularizer:运用到偏置向量的正则化函数
- activity_regularizer:运用到输出层(他的激活值)的正则化函数
- kernel_constraint:运用到kernel权值矩阵的约束函数
- bias_constraint:运用到偏置向量的约束函数
池化层
池化层也称为抽样层,他的扫描方式和卷积相似,计算的方式不再是扫描框与被扫描的区域点乘,池化运算方法有以下3种:
- 均值池化:提取被扫描区域中有所值的均值
- 随机池化:提取被扫描区域中的任意一个值
- 最大池化:提取被扫描区域中值最大的一个(最常用的)。
优点
- 可以压缩数据,改善结果,是神经网络不容易发生过拟合 。
- 和卷积层一起使用,有效的减少数据量,起到了降采样的作用,相当于对卷积后进一步的特征提取与压缩。
keras代码(MaxPooling2D)
MaxPooling2D(pool_size=(2,2),strides=None,padding='valid',data_format = None)
- pool_size:池化的窗口,可以是整数或者元祖,整数的话,表示长宽一样
- strides:可以是整数、元祖或者None,默认值None代表与pool_size相同
- padding:取值为为“valid”或者“same”
- data_format:可以设置为“channels_last”(默认)或“channels_first”二者之一,表示输入中维度的顺序。“channels_first”表示颜色通道在最前面,(3,64,64)。“channels_last”则相反
另外:平均池化:AveragePooling2D
全局池化
全局池化与普通池化的区别在于,全局池化不需要池化窗口在输入数据上进行滑动采样,也就是说池化过程的输入是前一个卷积层输出得到的特征图,
- 包含全局平均池化、全局最大池化。
- 全局平均池化替代全连接层,减少卷积神经网络中的参数(GoogleNet 结合了全局平均池化层,所以全连接层总参数还不到700万)
- 替代全连接层,同时不需要dropout层
- 全局平均池化层更有意义且容易解释其内在原理
缺点
代码
keras.layers.GlobalAveragePooling2D(data_fromat=None)/GlobalMaxPooling2D(data_format=None)
BN层
Batch Normalization层,称为批量标准化层。这是一种优化深度学习神经网络的方式,我们常将它夹杂在各层之间,对数据进行归一化处理,比如:min-max标准化、Z-score等。
- 对数据标准化可以提高网络的训练速度。
- 可以解决Internal Covariate Shift现象
- 让数据满足IID独立同分布
- 对训练中的每一批次的数据进行处理,使其平均值接近0,标准差接近1.
Internal Covariate Shift
google称为ICS现象
深度神经网络涉及到很多层的叠加,而每一层的参数更新会导致上层的输入数据分布发生变化,通过层层叠加,高层的输入分布变化会非常剧烈,这就使得高层需要不断去重新适应底层的参数更新。为了训好模型,我们需要非常谨慎地去设定学习率、初始化权重、以及尽可能细致的参数更新策略。
IID独立同分布
IID独立同分布假设就是假设训练数据与测试数据是满足相同分布的,那么通过训练数据获得的模型能够在测试集上获得较好的效果
keras代码
keras.layers.BatchNormalization(axis=-1,momentum=0.99,epsilon=0.11,center=True,scale=True,beta_initializer='zeros',gamma_initializer='ones',moving_mean_initializer='zeros',moving_variance_initializer='ones',beta_regularizer=None,gamma_regularizer=None,beta_constraint=None,gamma_constraint=None)
- axis:需要标准化的轴,一般是特征轴。例如在data_format='channels_first’的Conv2D层的后面。将BN层的axis参数设置为1
- momentum:超参数,移动均值和移动方差的动量值
- epsilon:正则化的超参数,这是一个很小的浮动数值,用以避免在除法的过程中除数为零。
- center:如果为True,把β的偏移量加到标准化的张量上;如果为False,则忽略。
- scale:缩放,如果为True,乘以γ;如果为False,则不使用。当下一层为线性层时。这个参数可以被禁用,因为缩放将由下一层完成
- beta_initializer:β权重初始化方法。
- gamma_initializer:γ权重的初始化方法。
- moving_mean_initializer:移动均值的初始化方法。
- moving_variance_initializer:移动方差的初始化方法。
- beta_regularizer:可选的β权重的正则化方法。
- gamma_regularizer:可选的γ正则化方法。
- beta_constraint:可选的β的权重的约束方法
- gamma_constraint:可选的γ权重的约束方法
dropout层
dropout层的作用是为了解决参数量过大带来的过拟合现象,所以的它的原理是,对每一个全连接层,按照一定的概率将其中的神经网络单元暂时从网络中随机丢弃。从而简化了神经网络结构,如下图所示:
- 左图是未droput的神经网络,右图是droput的神经网络
- dropout层是随机选择丢弃的,且每次丢弃的都不一样
- 我们可以设置丢弃的比例
- 丢弃的方式是:将全连接的输入单元按照比例随机的设置为0
keras代码
keras.layers.Dropout(rate,noise_shape = None,seed = None)
- rete:0-1 的浮点数,指定需要断开连接的比例
- noise_shape:表示将与输入数据相乘的二进制dropout掩层的形状,一般默认即可。
- seed:生成随机数的随机数种子数。
flatten层
将输入数据展平,他不会影响数据的大小,一般我们将它放在卷积层和全连接层中间,起到转换数据的作用。因为卷积层输出的数据是一个多维张量(一般是二维),Flatten层将其转换为向量序列的形式,如下如所示:
keras代码
keras.layers.Flatten(data_format = None)
总结
好了,常用的而神经网络层就这些了,此时你再去看实战篇中的模型搭建,就会觉得简单很多了