卷积神经网络CNN由纽约大学的Yann Lecun于1998年提出,其本质是一个多层感知机,成功的原因在于其所采用的局部连接和权值共享的方式:
- 一方面减少了权值的数量使得网络易于优化
- 另一方面降低了模型的复杂度,也就是减小了过拟合的风险
该优点在网络的输入是图像时表现的更为明显,使得图像可以直接作为网络的输入,避免了传统识别算法中复杂的特征提取和数据重建的过程,在二维图像的处理过程中有很大的优势。
- 如网络能够自行抽取图像的特征包括颜色、纹理、形状及图像的拓扑结构。在处理二维图像上,特别是识别位移、缩放以及其他形式扭曲不变性的应用上具有良好的鲁棒性和运算效率等。
- CNNs可以自动从(通常是大规模)数据中学习特征,并把结果向同类型未知数据泛化。
目前所说的卷积神经网络一般指的是深层结构的卷积神经网络,层数从几层到几十上百层不定。浅层卷积神经网络因为准确度和表现力等原因很少使用。
通过机器进行模式识别 ,通常可以被认为有四个阶段:
- 数据获取: 比如数字化图像
- 预处理: 比如图像去噪和图像几何修正
- 特征提取:寻找一些计算机识别的属性,这些属性用以描述当前图像与其它图像的不同之处
- 数据分类:把输入图像划分给某一特定类别
CNN是目前图像领域特征提取最好的方式,也因此大幅度提升了数据分类精度
网络结构:
- 基础的CNN由 卷积(convolution), 激活(activation), and 池化(pooling)三种结构组成。
- 卷积层的输出结果是每幅图像的特定特征空间。
- 处理图像分类任务时,我们会把卷积层输出的特征空间输入到全连接层或全连接神经网络(fully connected neural network, FCN)中。使用全连接层来完成从输入图像到标签集的映射,即分类功能。
- 整个过程最重要的是通过训练数据迭代调整网络权重,这里使用的是反向传播算法,即BP算法。
- 阶段(stage)
- 根据功能不同,我们称这些前后连接的结构处于不同阶段(stage)。
- 在主流CNNs中,不同stage里CNN会有不同的单元和结构,比如卷积核 (kernel)大小可能不同,激活函数(activition function) 可能不同,pooling操作可能不存在。
- 一个stage中的一个CNN,通常会由三种映射体积(Maps Volume)组成:
- 输入映射空间(input maps volume)
- 特征映射空间(feature maps volume)
- 池化映射空间(pooled maps volume)
- 为什么称为映射体积呢,因为我们的输入一般是RGB图像,那么输入的maps volume就是由红、黄、蓝三通道构成的。所以说我们输入的图像实际上就是由高度,宽度和深度三种信息构成的,可以被形象的理解为是一种体积。高度和宽度就是图片的分辨率,深度就是红黄蓝三通道,在RGB图像中深度就是3,在灰度图像中,深度就是1。
卷积:
-
CNN中,最基本的操作就是卷积convolution,准确的说CNN所用的卷积是一种2D卷积。意思就是卷积核kernel只能在x,y轴上滑动,不能在深度(跨通道)上位移。
-
如下图,对于RGB图像,采用了三个独立的2-D kernel,如黄色部分所示,所以这个完整的kernel的维度是:
其中X和Y是kernel的宽高。
在基础CNN的不同stage中,kernel的深度都应当一致,等于输入图像的通道数。 -
卷积需要输入两个参数,其实质是二维空间滤波,滤波的性质与kernel的选择有关,CNN的卷积是在一个2D kernel (可以是多个2D的kernel,但是在进行卷积操作的时候是一个一个进行的)和输入的 2D input map(也就是二维图像) 之间,RGB中的各图像通道中分别完成。
- 假设某一卷积输出点为(x,y)
- 卷积核的大小为p*q
- kernel权重为 ω
- 图像亮度为v
- 则卷积过程就是kernel 所有权重与其在输入图像上对应元素亮度之和,可以表示为:
-
例如:
其计算方式如下:
随着卷积核kernel在x,y轴上平扫,就可以得到输出空间,假设输入图像的大小是512*512,卷积核 是3*3,在不考虑零填充(zero padding)的情况下,其输出是
- 注意:卷积层的kernel可能不止一个,扫描步长,方向也有不同:
- 可以采用多个卷积核设为n ,同时扫描,得到的feature map会增加n个维度,通常认为是多抓取n个特征。
- 可以采用不同的扫描步长(stride),如果上面的例子中采用的步长为n,那么输出图像大小就是:
- padding,上面的例子中卷积过后的图像是被缩减的,因为边缘部分被压缩到中间,其卷积后的图像大小将会被缩减。这其实这个问题可以在图像周围填充0来保证卷积后的feature map与原始图像大小不变。
- 深度升降,例如增加一个1*1的kernel来增加深度,其实就相当于复制一层当前通道作为feature map
- 跨层传递feature map,不再局限于输入即输出,例如ResNet的跨层传递特征。
激活:
-
卷积之后,通常会加入偏置(bias),并引入非线性激活函数(activation function)进行激活。
-
设偏置为b,激活函数为h(),则激活函数为:
这个Zx,y就是卷积后输出的(x,y)点的激活值。 -
bias和元素位置无关,也就是说和x,y值无关,只与层有关。
-
主流的激活函数有:
- 线性整流单元(ReLU):
- Sigmoid函数:
- tanh函数:
- 根据实际参数大小等性质调整。
- 线性整流单元(ReLU):
-
feature map是可以可视化的。
-
例如,采用277*277的RGB图像,如果采用96个11x11x3的kernel同时扫描(这就是上面说的采用多个卷积核,使feature map增加n个维度),就可以得到输出的feature map是96个267x267的二维feature map,原本的3通道在积分的时候会被作为一个元素加起来。feature map在可视化之后,有些表示边缘特征,有些是模糊化的输入,有些强调的是灰度变化,有的强调眼睛,有的强调某一通道的表现。
池化:
- 池化(pooling),是一种降采样操作(subsampling),主要目标是降低feature maps的特征空间,或者可以认为是降低feature maps的分辨率。因为feature map参数太多,而图像细节不利于高层特征的抽取。
- 目前,主要的池化操作有:
- 最大值池化 Max pooling:如上图所示,2 * 2的max pooling就是取4个像素点中最大值保留
- 平均值池化 Average pooling: 如上图所示, 2 * 2的average pooling就是取4个像素点中平均值值保留
- L2池化 L2 pooling: 即取均方值(先计算4个数的平方的和,然后开平方)
- 池化操作的主要目的就是降低feature maps的分辨率,降低参数。这种暴力降低在计算力足够的情况下是不是必须的并不确定。目前,一些大的CNNs网络只是偶尔使用pooling。
上面就是CNN stage的基本结构,这个结构是可变的,目前的大部分网络都是根据基本结构堆叠调整参数,或者跳层连接而成的。CNN输出的feature maps不仅可以输入到全连接网络中做分类,也可以接入另一个“镜像”的CNN用来做像素级的标注,即图像分割。
全连接网络:
- 出现在CNN中的全连接网络(fully connected network)主要目的就是为了分类。
- 全连接网络不同于CNN的滑动卷积,全连接网络的每一层都与上一层完全连接。意思就是上一层的一个神经元与下一层的每一个神经元都有连接。
- 对于全连接网络,除了输入层和输出层的其他层,都被认为是隐含层。
- 对于第L层的第i个神经元,它的输出计算方式是:
- 使用激活函数后,其输出是:
- 计算这一层的所有神经元的输出作为下一层的输入。
目标函数和训练方法:
- 训练误差一般都是使用损失函数来衡量的。目前比较流行的损失函数有均方误差(MSE Mean Square Error)和K-L散度(K-L divergence),对于输出层的损失值计算公式如下:
- MSE(前边乘以1/2就是为了求导好算,当然对于损失函数来说,并没有太大影响。):
- K-L divergence(前边的系数也是为了求导好算。):
是真实值,
是L层的第j个神经元的输出。
- 通常K-L divergence的权重更新会比MSE更快。
- Backpropagation Pass反向传播:
- 预测值和真实值(label)之间必然存在误差,反向传播就是要把这个误差信息回传给每一层,让这些层修改他们的去权值,使预测更准确。
- BP算法使用的是梯度下降更新权值的,其更新公式如下:
- 其中 η是梯度下降的学习率(learning rate),如果learning rate取值过大,可能会收敛于震荡,如果learning rate取值过小,可能收敛速度太慢。
- 可以看到梯度下降法是利用误差对旧参数的梯度进行新参数的更新,所以权值更新的目标就是让每一层得到这样的梯度,然后更新。
- 很明显参数的更新依靠Wold和bold以及误差E,然而E又是由Wold和bold计算得出,因此这就是一个多参数优化问题,其解题思路就是先固定一方,更新另一方。
- Backpropagation算法,大概可以分为两步:
- 首先前向传播,通过输入图像和初始化权重,获得输出。
- 得到输出后,通过损失函数计算出误差E,通过误差对权重的偏导值对权重进行更新,通过误差对偏置的偏导值对偏置进行更新。
- 这里有可能难以理解,其实也并不难理解,我们假设内层第L层的某一连接的权重值为wLi,由于该连接的输出为wLi*x + bLi,其值与其他传入下一层的同一个神经元的所有值相加后,经过激活函数h() 作为下一层的某一神经元的输入,那么下一个神经元的x就成了h(∑wLi*x + bLi)。然后这个整体作为输入x再次乘以该神经元的某个连接的权重和偏置传递给下一层直到传到最后一层。 由于相加的内容只有其中一项是包含wLi的,那么剩余项求导为0(相当于常数求导为0),这样一来,我们用误差E对某一权重求偏导,使用的是复合函数求导,求导到该权重层即可。这时得到的偏导数值即是所需梯度,用原来的权重值减去学习率乘以这个梯度得到的新值就是参数更新所需的新值。
- 由于激活函数以及多层的嵌套运算,对于偏置的更新也需要和权重一样进行求导。不同的是在求到最接近的那一层,对w求导是x,而对b求导是1。
- 权重和偏置更新后,就认为完成了一次训练。称从来自训练集的输入向量到权重和偏置更新为一个纪元(epoch)。
- 当MSE误差稳定不变,或者到达某个迭代次数后,BP算法停止,模型训练结束。
总结:
- 所以对于神经网络模型,就是一个模拟人脑工作所得出来的,卷积神经网络更是如此。
- 卷积操作是不是很像多个神经元接收到的外部信息通过轴突传给某些个神经元的树突。
- 激活函数是不是像电压刺激达到一定程度产生的神经递质。
- 池化操作又或许是某些神经元传递到同一个神经细胞进行的信息简化。
- 每个神经细胞都带有自身权重,经过不断的犯错,调整,不断的调整自身权重,加强某个连接,减弱某个连接,从而达到更高的识别准确率。
主要CNN算法:
名称 | 特点 |
---|---|
LeNet5 | 没啥特点,不过是第一个CNN应该要知道 |
AlexNet | 引入了ReLU和dropout,引入数据增强、池化相互之间有覆盖,三个卷积一个最大池化+三个全连接层 |
VGGNet | 采用11和33的卷积核以及2*2的最大池化使得层数变得更深。常用VGGNet-16和VGGNet19 |
Google Inception Net | 这个在控制了计算量和参数量的同时,获得了比较好的分类性能,和上面相比有几个大的改进:1、去除了最后的全连接层,而是用一个全局的平均池化来取代它; 2、引入Inception Module,这是一个4个分支结合的结构。所有的分支都用到了11的卷积,这是因为11性价比很高,可以用很少的参数达到非线性和特征变换。3、Inception V2第二版将所有的55变成2个33,而且提出来著名的Batch Normalization;4、Inception V3第三版就更变态了,把较大的二维卷积拆成了两个较小的一维卷积,加速运算、减少过拟合,同时还更改了Inception Module的结构。 |
微软ResNet残差神经网络(Residual Neural Network) | 1、引入高速公路结构,可以让神经网络变得非常深2、ResNet第二个版本将ReLU激活函数变成y=x的线性函数 |