卷积神经网络在计算机视觉中已经有很广泛的应用,比如无人车自动驾驶要靠计算机视觉来检测周围的车、行人和路标,还有他们的距离,人脸识别准确度也因为计算机视觉的发展得到很大提升。大家手机上各种美图软件可能也都应用了深度学习、卷积网络的技术。
在计算机视觉的发展下,许多新型应用以前想都不敢想,现在也依靠大家的创意应运而生。
相关算法不但使计算机视觉得到突飞猛进的发展,与其他领域学科的交叉、想法的碰撞,会让不同行业都得到许多灵感。每个人都可以结合这些算法的思想到自己的研究或者应用方向上去,也许会有出乎意料的成果。
计算机视觉目前比较经典的几种用法有:
- 图片分类问题,比如这张图是不是一只猫,还是一只狗;
- 自动驾驶,识别周围物体和位置以便于避开;
- 风格迁移, 用一张图片的内容和另一张图片的艺术风格合成一张新的图片。
用传统的全连接层的方法构建一个计算机视觉的神经网络,数据量特别大,需要大量计算资源是一个很大的问题。一张 64 px 的图片,features 有 64643=12288 个,而每张 1000px 的图片有 100010003 =300百万的 featrues,如果使用全连接网络的深度神经网络,参数多到难以想象(过亿)!而且很难避免过拟合!
这时候,卷积神经网络就要大显身手了!为了什么是卷积,我们先从边缘检测说起。
边缘检测
边缘检测就是识别图像中物体的边缘,有横有竖,还有弯弯角角和各种不规则的边缘。
卷积运算
卷积运算就是一个filter或者叫kernel,拓印在一张图片上,对应位置元素相乘的积求和,拓印整个图片后得到一组数据。
【图】
image.png
举例子垂直边缘检测器:
image.png
正边和负边
image.png水平边缘 filter
image.pngSobel/Scharr filter
这种滤波器增加了中间一行元素的权重,使得结果的鲁棒性会更高
image.png
filter 和 卷积神经网络有什么关系?
fiter中每个数字作为参数 w 在梯度下降中更新,让神经网络来学习任何它所需要的3*3 (或者其他)的 fiter, 来捕捉数据 的 feature 。它可以检测出45度或者70度,或者任何奇怪角度的边缘。
image.png
Padding
Valid 卷积
用 3 × 3 的 fiter 卷积 6 × 6 的图像,结果是 4 × 4 的矩阵。用数学符号表示,filter 为 f × f ,图像为 n × n ,两者卷积输出结果为 ( n - f + 1 ) × ( n - f + 1 ) 。
【图】
这样的话就有两个缺点:一个是,每次卷积,你的图片都会缩小,几次之后,会不会变到只有 1 × 1? 第二个,处于边缘和角落的像素点,在卷积运算中用到的次数少,图片这些地方的信息就被丢掉了。
【图】
Same 卷积
为了解决这个问题,我们可以给图片边缘填充像素。用 p 表示填充的数量,那么卷积运算的输出就是: ( n + 2p - f + 1 ) × ( n + 2p - f + 1 ) 。
如何确定 p 值: 当你在卷积运算前,想要给的图像填充边缘让输入图像大小等于输出矩阵大小,你可以这样计算:p = ( f - 1 ) / 2. 比如,假设 5 × 5 的 fiter,p 为 2 的时候就可以使得输入和输出一样大。
这样一来,最左上角的点,在卷积运算中被用到 4 次,丢失图像边缘的信息的这个缺点可以稍微削弱一下(此例中图像中心的点被用到9次)。你也可以填充多一点,让 p 为 2 或者更大。
f 一般为奇数: 可能的原因有:
- 如果 f 为偶数,p 就不是整数,实际操作中,会发生不对称的 padding
- 计算视觉中,如果用奇数,则会有个中心像素点,能够方便地指出 filter 的位置
也许这些理由还不是充分条件,也许用偶数的 f 也能得到不错的结果,但作为惯例还是推荐使用奇数的 f.
卷积步长
如果每次进行“拓印相乘”这一步之后,挪动的位置不是之前例子中的 1 ,而是 其他数目,也是可以的,这个叫做步长,我们用 s 表示。这时候有:
image.png
如果公式中除法部分不是整数,就在最后向下取整,那些不能放得下一个 filter 的部分相当于被舍弃了。你可以改变 s, f, p 使得最后结果是整数,但有时候不必如此。
互相关(cross-correlation)
前面说的卷积运算,在数学上不算真正的卷积,只能称其为互相关(cross-correlation)。
数学上的卷积运算之前,会对 filter 进行一个沿水平和垂直方向翻转,进行这样操作会发生这样的效果:(AB)C = A(BC),被称为结合律,常用于信号处理领域。
不过在机器学习中的惯例,我们进行卷积不会进行这一步,这不会对实现卷积网络造成任何影响。
三维图像上如何卷积
目前为止,我们的例子是灰度图像,2D 数据,彩色图像如何卷积呢?彩色图像的矩阵表示为 ( n_H , n_W , n_C )。n_C , channels(depths) 是图像的颜色通道数,RGB图像的 channels是3,我们用来卷积的 filters ,对应的,shape也会变为 ( f , f , n_C ),这样的 filters 一共有 f × f × n_C 个参数 w.
filters的通道数输入必须和图像的(每一层的输入)通道数相同,卷积后得到一个 2D 矩阵。可以选择多个 filters, 每个 filters 相当于普通神经网络里面的一个神经元。多个 filters 的卷积结果堆叠成 3D 数据,成为下一层的输入。下面细讲。
单层卷积网络
图像和每一个filters进行卷积运算后得到 2D 矩阵这一过程,相当于深度学习中的 WX,然后增加偏差 b , 相当于得到 z = WX+b,也就是说,每一个 filter 都对应一个实数 b,b 的数目和 filters 是一样。
然后将这个 z 输入到非线性激活函里面,比如ReLU,输出结果 a 和 z 拥有一样的shape。
每个 filters 都经过这样的步骤,然后把所有结果堆叠起来。因此某一层卷积神经网络的输出,它的 channels 一定和这一层的 filters 个数相同。
参数有多少个?
某个卷积层一共有 10 个 3 × 3 × 3 的 filters ,那么参数个数就是 ( 27 + 1 ) × 10 = 280 个。
不管输入的图片有多大,在这一层,filters 确定好以后参数个数就不会变,这是卷积神经网络的一个特征——能很好地避免过拟合。
总结一下各种变量的表示:
简单卷积网络
卷积到最后一层,会展开矩阵变成一个向量,然后输入全连接层。最后的最后,根据你的目标是什么,使用 logitic 或者 softmax 得到一个预测值的输出,去计算代价函数。
卷积层:Convolution(CONV)
池化层:Pooling(POOL)
全连接层:Full connected(FC)
池化层
池化层也是一种缩减模型大小,提高计算速度,提高提取特征鲁棒性的方式。具体做法就是用一个 filter 以一个步幅拓印输入,在区域内选出最大值或者平均值。池化层的输出的大小计算公式和卷积一样: ( n + 2p - f )/s + 1,然后向下取整 。
Max pooling
如果 filters提取到某个特征,那么保留其最大值,如果没有提取到这个特征,区域中不存在这个特征,因为最大值还是很小。
image.png
池化层没有参数需要学习,梯度下降不需要改变任何值,只要确定了 f 和 s ,就是一个固定的运算。它只是计算神经网络某一层的静态属性。
如果输入不是2D,比如说有 n_c 个 channels , 需要每个 channels 都单独执行最大池化计算,得到的输出,也有 n_c 个 channels。
Average pooling
顾名思义,平均池化就是用 filter 取平均值,其他参数都是一样的。
最大池化比平均池化更常用,例外是:深度很深的神经网络。
池化层的参数
(f)2 × (s)2 的池化层相当于将宽度和高度缩减一半,其次是 3 × 2 。
最大池化很少用到 padding,也有例外。
参数经过手动设置,或者交叉验证。
卷积神经网络示例( LeNet - 5 )
image.png人们在统计一个卷积网络有多少层时,通常只统计具有权重和参数的层,所以池化层一般不会被记为一个单独的层。
对于超级参数,尽量不要自己设置超级参数,而是查看文献中别人采用了那些超级参数,选一个别人任务中效果很好的架构,这些参数很有可能也适用于你自己的参数。
两种经典结构:
(conv + pool) -> (conv + pool ) -> FC -> FC -> softmax
conv -> pool -> conv -> pool -> FC -> FC -> softmax
或者一个或多个卷积层后面跟一个池化层
卷积神经网络的参数,在卷积层并不多,更多的参数存在于全连接层。
列出所有层的激活值,你会发现卷积层的激活值是下降趋势,但是下降太快,也会影响性能。
image.png卷积神经网络的基本模块就是这几个了,卷积层、池化层、全连接层。如何把这些基本模块整合起来,构建高效的神经网络呢?这需要深入的理解和感觉。最好的办法就是大量阅读别人的案例。你也可以将别人的框架应用于自己的应用程序。
网友评论