卷积神经网络原理及其C++/Opencv实现(1)

2近年来,深度学习大火,在无人驾驶、智能机器人、图片识别及分类、目标检测、预测未来、疾病诊断等等领域,无一不是深度学习发挥着重大、关键作用。那么深度学习到底是什么,真的有那么神秘吗?其实也不然,就像大脑由一个个脑细胞构成一样,深度学习也是由一个个神经元构成的,如果只看单个细胞或者神经元,觉得没那么复杂,但是很多很多个细胞或者神经元组合起来形成一个整体,就变得那么的神奇与伟大。那么深度学习与神经网络又有什么关系呢?很简单,神经网络的层数加深之后,就成为深度学习神经网络了。

接下来的系列文章中,我们将使用C++和Opencv来实现一个5层的卷积神经网络来对手写数字图片进行分类(整体结构如下图所示)。麻雀虽小五脏俱全,虽然只有5层(2个卷积层C1、C3,2个池化层S2、S4,一个全连接层O5),但基本涵盖了深度学习网络的各个组成部分。准备好了吗?让我们一步步揭开深度学习与神经网络的神秘面纱吧~

1. 总体认知

我们首先不看神经网络里面的数据处理细节,只看输入端与输出端:输入端是我们输入神经网络的数据,输出端是我们想要得到的经过神经网络处理之后的数据。所以神经网络的本质是一种数据处理模型,这个数据处理模型有很多参数,这些参数决定着该数据处理模型的输出。如下图所示:

那么怎么样才能使输出数据是自己想要的数据呢,这就涉及到调参的问题,也即调整神经网络里面的参数,这个调整参数的过程我们称为学习或者训练,神经网络正常工作之前必须经过学习训练。因此准备并制作好训练数据非常关键。训练数据包括输入数据标签,标签就是我们对输入数据的期待输出数据,比如输入1,我们期待输出2,那么(1, 2)就组成了一个训练数据。

训练的大概过程如下图所示,具体怎么使用输出数据与标签来调节参数,我们在后续内容再详细说明。

2. 神经元的概念

这里说的神经元是计算机科学领域的神经元,不过它是人们由生物科学领域的神经元启发而提出来的。不得不感慨大自然万物的奇妙之处,我们人类需要向自然万物学习的东西还有很多很多~

如下图所示,一个神经元包括输入信号x1、x2,权重w1、w2,偏执b,激活函数f(x)、输出信号y。当然,实际输入信号可能不仅有2个,也可能有1个、3个或者多个,对应的,权重也是可能有1个或更多个。

通常在示意图中,人们喜欢把乘法、加法、偏置、激活函数合成一部分,如下图所示:

根据上图,神经元的输出y按照下式计算:

如果有多个输入信号,那么按照下式计算:

神经网络由多个神经元级联而成,前一个神经元的输出作为后一个神经元的输入,比如下图

3. 激活函数

最常见的激活函数有Sigmoid函数和Relu函数。这里我们作为入门,只讲这两种激活函数,其它的激活函数后续再逐一道来。

(1) Sigmoid函数的表达式和函数曲线如下:


(2) Relu函数的表达式和函数曲线如下:

4. 卷积神经元

卷积神经元与神经元类似,主要区别在于神经元是输入信号乘以权重,卷积神经元则是输入信号与卷积核(相当于权重)进行卷积。

首先我们来讲一下卷积的操作,其实原理很简单。假设有一张m行n列的图像,以及一个r行c列的卷积核(r和c都是奇数,且m>r,n>c)。举个例子,取r=c=3,那么对于图像中任意一点A,其卷积值为:在图像上取以点A为中心的3*3窗口,得到9个点的像素值,与3*3卷积核中9个点的值进行对应位置的相乘,最后把9个乘积的结果累加起来,就是卷积值。如上图所示,x1与k1位置对应、x2与k2位置对应、...、x9与k9位置对应,那么任意点A的卷积值按照下式计算:

卷积的过程相当于按照从左往右、从上往下的顺序计算原图像中像素点的卷积值,将计算所得的所有卷积值按照行列排序组成一个二维矩阵,即是卷积结果。这里有有一个步长step的说法

(1) 若步长为1,则从左往右、从上往下地计算原图像所有点的卷积值。

(2) 若步长为2,则从左往右、从上往下地计算原图像中间隔为1的点的卷积值。

(3) 若步长为3,则从左往右、从上往下地计算原图像中间隔为2的点的卷积值。

如果步长为4、5、6也类似。不过我们通常默认步长为1,本文后续内容以及后续文章中也均默认步长为1

看到这里也许有人会有疑问了,如果图像上每个点都取以它为中心的矩形窗口,那么边缘点怎么办呢,根本取不到完整的窗口呀?这就需要边缘填充0值了,也称为padding操作。根据padding的行列数不同,可以把卷积模式分为Full、Same、Valid三种模式,下面分别说明。

(1) Full模式

在Full模式下,输出m+r-1行n+c-1列的卷积结果。

图像的顶部、底部分别需要填充的行数为:

p_r=r-1

图像的左侧、右侧分别需要填充的列数为:

p_c=c-1

填充如下图所示,黑色虚线框内区域为原图像,蓝色区域为边缘填充之后的图像,红色虚线框内的所有点均需要计算卷积值,因此最后输出(m+r-1)*(n+c-1)的卷积结果

(2) Same模式

在Same模式下,输出m行n列的卷积结果。

图像的顶部、底部分别需要填充的行数为:

p_r=(r-1)/2

图像的左侧、右侧分别需要填充的列数为:

p_c=(c-1)/2

填充如下图所示,红色虚线框内区域为原图像,蓝色区域为边缘填充之后的图像,红色虚线框内的所有点均需要计算卷积值,因此最后输出m*n的卷积结果

(3) Valid模式

在Valid模式下,输出(m-r+1)行(n-c+1)列的卷积结果。在该模式下,不需要进行padding操作,直接在原图像计算卷积,如下图所示,红色框内区域为原始图像,灰色区域中的所有点均要计算卷积值,因此最后输出(m-r+1)*(n-c+1)的卷积结果

好了,讲完二维图像的卷积原理,接着我们来讲卷积神经元吧。卷积神经元与上文所述的神经元类似,只是乘以权重的操作变成卷积操作了。如下图所示,其中:

(1) 两个卷积结果的相加操作,也即矩阵中对应位置值的相加。

(2) 加上偏执的操作,也即矩阵中每个值都加上相同的偏执b。

(3) 通过激活函数的操作,也即矩阵中每个值都输入激活函数,然后所有的激活函数输出值组成相同维度的矩阵,该矩阵就是卷积神经元的输出。

与神经网络相似,卷积神经网络也由多个卷积神经元级联而成,前一个卷积神经元的输出作为后一个卷积神经元的输入。同样,一个卷积神经元的输入不仅如上图那样有两张图像,也可能有1、3、4、5......张图像。

本文就讲到这里啦,下一篇文章我们继续哈,敬请期待~

欢迎扫码关注以下微信公众号,接下来会不定时更新更加精彩的内容噢~

posted @ 2021-03-08 20:10  萌萌哒程序猴  阅读(307)  评论(0编辑  收藏  举报