Foundations of Convolutional Neural Networks
Course4很大程度上是从计算机视觉的角度出发的。虽然研究的方向可能和视觉无关,但是CV中的方法也有一些启发性的作用。而且很大程度上是通过CV来学习CNN——卷积神经网络,所以重点要掌握的是CNN的方法。就让我们开始吧!
1.1 计算机视觉(Computer Vision)
当我们操作图片时,一个重点要关注的问题就是输入的特征向量的大小。可能说在之前的联系中,我们只尝试了比如64x64大小的图片,再加上RGB通道,也就是64x64x3的输入大小。但是在实际应用中,我们往往不可能用这么小的图片作为数据,这时候就会有比如1000x1000x3的大小的输入了。那这种时候我们应该怎么去处理呢?
如果希望处理大图,就要使用卷积运算来进行处理,来看下一小节!
1.2 边缘检测示例(Edge detection example)
卷积运算是卷积神经网络最基本的组成部分,我们这里使用边缘检测作为入门样例,希望得到一个较好的理解。
边缘检测
让我们举个例子,给了这样一张图片,让电脑去搞清楚这张照片里有什么物体,你可能做的第一件事是检测图片中的垂直边缘。比如说,在这张图片中的栏杆就对应垂直线,与此同时,这些行人的轮廓线某种程度上也是垂线,这些线是垂直边缘检测器的输出。同样,你可能也想检测水平边缘,比如说这些栏杆就是很明显的水平线,它们也能被检测到。那么要如何进行卷积呢?
卷积的具体操作
看一个例子,这是一个6×6的灰度图像。因为是灰度图像,所以它是6×6×1的矩阵,而不是6×6×3的,因为没有RGB三通道。为了检测图像中的垂直边缘,你可以构造一个3×3矩阵。在共用习惯中,在卷积神经网络的术语中,它被称为过滤器。在论文它有时候会被称为核,而不是过滤器,但在这个视频中,我们将使用过滤器这个术语。对这个6×6的图像进行卷积运算,卷积运算用“
∗
*
∗”来表示,用3×3的过滤器对其进行卷积。
使用这样的过滤器,接下来我们要做的就是将这个过滤器在我们要处理的图像上滑动,每滑动一次,就在其中计算过滤器得到的值,然后将它写到输出矩阵中。
事实上,对于这个卷积器的滑动获取数值方式我之前的博客中有,可以看这个https://blog.csdn.net/Raymond_MY/article/details/83240140
因此6×6矩阵和3×3矩阵进行卷积运算得到4×4矩阵。这些图片和过滤器是不同维度的矩阵,但左边矩阵容易被理解为一张图片,中间的这个被理解为过滤器,右边的图片我们可以理解为另一张图片。这个就是垂直边缘检测器,下一张图中你就会明白。
为什么这个可以做垂直边缘检测呢?用一个简单的例子。这是一个简单的6×6图像,左边的一半是10,右边一般是0。如果你把它当成一个图片,左边那部分看起来是白色的,像素值10是比较亮的像素值,右边像素值比较暗,我使用灰色来表示0,尽管它也可以被画成黑的。图片里,有一个特别明显的垂直边缘在图像中间,这条垂直线是从黑到白的过渡线,或者从白色到深色。
可能你会觉得这个边缘有些夸张。如果你用一个1000×1000的图像,而不是6×6的图片,你会发现其会很好地检测出图像中的垂直边缘。在这个例子中,在输出图像中间的亮处,表示在图像中间有一个特别明显的垂直边缘。从垂直边缘检测中可以得到的启发是,因为我们使用3×3的矩阵(过滤器),所以垂直边缘是一个3×3的区域,左边是明亮的像素,中间的并不需要考虑,右边是深色像素。在这个6×6图像的中间部分,明亮的像素在左边,深色的像素在右边,就被视为一个垂直边缘,卷积运算提供了一个方便的方法来发现图像中的垂直边缘。
1.3 更多边缘检测内容(More edge detection)
我们已经见识到用卷积运算实现垂直边缘检测,现在将进一步学习如何区分正边和负边,这实际就是由亮到暗与由暗到亮的区别,也就是边缘的过渡。
更多的栗子~
还是上一个视频中的例子,这张6×6的图片,左边较亮,而右边较暗,将它与垂直边缘检测滤波器进行卷积,检测结果就显示在了右边这幅图的中间部分。
现在这幅图有什么变化呢?它的颜色被翻转了,变成了左边比较暗,而右边比较亮。现在亮度为10的点跑到了右边,为0的点则跑到了左边。如果你用它与相同的过滤器进行卷积,最后得到的图中间会是-30,而不是30。如果你将矩阵转换为图片,就会是该矩阵下面图片的样子。现在中间的过渡部分被翻转了,之前的30翻转成了-30,表明是由暗向亮过渡,而不是由亮向暗过渡。
看到右边这个过滤器,我想你应该猜出来了,它能让你检测出水平的边缘。提醒一下,一个垂直边缘过滤器是一个3×3的区域,它的左边相对较亮,而右边相对较暗。相似的,右边这个水平边缘过滤器也是一个3×3的区域,它的上边相对较亮,而下方相对较暗。
这里还有个更复杂的例子,左上方和右下方都是亮度为10的点。如果你将它绘成图片,右上角是比较暗的地方,这边都是亮度为0的点,我把这些比较暗的区域都加上阴影。而左上方和右下方都会相对较亮。如果你用这幅图与水平边缘过滤器卷积,就会得到右边这个矩阵。
更多的卷积分类器
这个被人称作是Sobel过滤器,它的优点在于增加了中间一行元素的权重,这使得结果的鲁棒性会更高一些。
这个是Scharr过滤器,它有着和之前完全不同的特性,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。
将分类器中的数字作为参数来学习
随着深度学习的发展,我们学习的其中一件事就是当你真正想去检测出复杂图像的边缘,你不一定要去使用那些研究者们所选择的这九个数字,但你可以从中获益匪浅。把这矩阵中的9个数字当成9个参数,并且在之后你可以学习使用反向传播算法,其目标就是去理解这9个参数。
任何它所检测到的特征,不管是垂直的边缘,水平的边缘,还有其他奇怪角度的边缘,甚至是其它的连名字都没有的过滤器。针对不同的任务来创建不同的分类器,这本身也非常具有针对性。
1.4 Padding
出现的问题
我们在之前视频中看到,如果你用一个3×3的过滤器卷积一个6×6的图像,你最后会得到一个4×4的输出,也就是一个4×4矩阵。那是因为你的3×3过滤器在6×6矩阵中,只可能有4×4种可能的位置。
数学解释是,如果我们有一个
n
∗
n
n*n
n∗n的图像,用
f
∗
f
f*f
f∗f的过滤器做卷积,那么输出的维度就是
(
n
−
f
+
1
)
∗
(
n
−
f
+
1
)
(n-f+1)*(n-f+1)
(n−f+1)∗(n−f+1)。在这个例子里是
6
−
3
+
1
=
4
6-3+1=4
6−3+1=4,因此得到了一个4×4的输出.
这样的话会有两个缺点,第一个缺点是每次做卷积操作,你的图像就会缩小,从6×6缩小到4×4,你可能做了几次之后,你的图像就会变得很小了,可能会缩小到只有1×1的大小。你可不想让你的图像在每次识别边缘或其他特征时都缩小,这就是第一个缺点。
第二个缺点时,如果你注意角落边缘的像素,这个像素点(绿色阴影标记)只被一个输出所触碰或者使用,因为它位于这个3×3的区域的一角。但如果是在中间的像素点,比如这个(红色方框标记),就会有许多3×3的区域与之重叠。所以那些在角落或者边缘区域的像素点在输出中采用较少,意味着你丢掉了图像边缘位置的许多信息。
解决方法
为了解决这些问题,我们可以在卷积操作之前填充这幅图像。在这个案例中,可以沿着图像边缘再填充一层像素。如果你这样操作了,那么6×6的图像就被你填充成了一个8×8的图像。如果你用3×3的图像对这个8×8的图像卷积,你得到的输出就不是4×4的,而是6×6的图像,你就得到了一个尺寸和原始图像6×6的图像。习惯上,你可以用0去填充,如果
p
p
p是填充的数量,在这个案例中,
p
=
1
p=1
p=1,因为我们在周围都填充了一个像素点,输出也就变成了
(
n
+
2
p
−
f
+
1
)
∗
(
n
+
2
p
−
f
+
1
)
(n+2p-f+1)*(n+2p-f+1)
(n+2p−f+1)∗(n+2p−f+1),和输入的图像一样大。这个涂绿的像素点(左边矩阵)影响了输出中的这些格子(右边矩阵)。这样一来,丢失信息或者更准确来说角落或图像边缘的信息发挥的作用较小的这一缺点就被削弱了。
刚才展示了用一个像素点来填充边缘。当然也可以填充两个像素点,也就是说在这里填充一层。实际上你还可以填充更多像素。这里画的这种情况,填充后
p
=
2
p=2
p=2。
两种填充方法
Valid卷积
Valid卷积意味着不填充,这样的话,如果你有一个 n ∗ n n*n n∗n的图像,用一个 f ∗ f f*f f∗f的过滤器卷积,它将会给你一个 ( n − f + 1 ) ∗ ( n − f + 1 ) (n-f+1)*(n-f+1) (n−f+1)∗(n−f+1)维的输出。这类似于我们在前面的视频中展示的例子,有一个6×6的图像,通过一个3×3的过滤器,得到一个4×4的输出。
Same卷积
Same卷积,那意味你填充后,你的输出大小和输入大小是一样的。根据这个公式 ( n − f + 1 ) (n-f+1) (n−f+1),当你填充 p p p个像素点, n n n就变成了 ( n + 2 p ) (n+2p) (n+2p),最后公式变为 ( n + 2 p − f + 1 ) (n+2p-f+1) (n+2p−f+1)。因此如果你有一个的图像,用个像素填充边缘,输出的大小就是 ( n + 2 p − f + 1 ) ∗ ( n + 2 p − f + 1 ) (n+2p-f+1)*(n+2p-f+1) (n+2p−f+1)∗(n+2p−f+1)。如果你想让 ( n + 2 p − f + 1 ) = n (n+2p-f+1)=n (n+2p−f+1)=n的话,使得输出和输入大小相等,如果你用这个等式求解 p p p,那么 p = ( f − 1 ) / 2 p=(f-1)/2 p=(f−1)/2。所以当 f f f是一个奇数的时候,只要选择相应的填充尺寸,你就能确保得到和输入相同尺寸的输出。
习惯上,计算机视觉中,通常
f
f
f是奇数,甚至可能都是这样。你很少看到一个偶数的过滤器在计算机视觉里使用
但是习惯上,我推荐你只使用奇数的过滤器。我想如果你使用偶数f也可能会得到不错的表现,如果遵循计算机视觉的惯例,通常使用奇数值的
f
f
f
1.5 卷积步长(Strided convolutions)
这里的卷积步长就是,我们滑动的时候不再是一格格滑了,而是可能步长为2地滑动,无论是上下左右都是步长为2
这里就不赘述了,相信这个是一个很简单的点,比较好理解。