什么是卷积神经网络

学到卷积神经网络,搜索到的资料一般都是这样的

神经网络

或是这样的

神经网络

这尼玛什么鬼,故弄玄虚忽悠投资人的吧。。再搜一下什么BP神经网络,深度神经网络,所有的教材都像下图一样,一大堆圈圈,无数跟线连起来,显得那么装逼,可菜鸟们就是看不懂到底是啥。

神经网络

0x00 瞎扯淡 - 什么是卷积

我第一次接触到卷积是本科2年级,为了做图像识别,准备把这些基础知识恶补一下。可是翻开教材,满书的“傅里叶变换”“线性时不变系统”…… 果断的就放弃了。。

  • 难懂之因:为了数学美,拆卸了脚手架。教科书书常用“定义—定理”的体系,先给出数学定义,然后给出若干性质,从公式到公式,逐步推导。有的教科书采用用信号“反褶、平移、相乘、积分”给出几何解释,属于用数学解释数学,提问者不满足这种解释。这不是当年发明卷积的大师们的“需求–猜想—发现—证明—应用”的路径,大师们建设好“卷积”大厦后,为了数学美,拆卸了脚手架,现在人们看到的是炼成的钢铁,看不出钢铁是怎样炼成的。造成了部分非数学专业学生的一个难点。——唐常杰

其实卷及根本就没那么麻烦,编书的老师简直就在卖弄自己的数学功底。看看下面的解释,卷积这个高达上的名词瞬间就变得通俗易懂了。

1. 给卷积一个通俗的解释——关于卷积的一个血腥的讲解

因为关于卷积的内容太血腥,于是我把它移到了附录里面。按几下空格或者PageDown即可观看

0x01 什么是神经网络

神经网络形象的可以表示成本文开始的那张图,一堆圈圈分成一层一层的被一些线连接起来。那么每一部分是什么意思呢,让我们从神经元开始讲起。

1. 神经元(感知机)

学过高中生物的都知道,神经元分为树突(dendrite)轴突(axon)胞体。其中,树突具有接受刺激并将冲动传入细胞体的功能,细胞体对输入的刺激进行计算,最后由轴突的分枝把神经冲动传给其他神经元或效应器。上个世纪六十年代(1958年)感知机模型被提出,如下图所示。感知机的左边是的树突,可以接受传入信号(x1,x2,x3);右边是轴突,负责输出信号。那么如何处理输入信号呢,为了简化模型,我们先认为如果输入的都是1,那么输出1,否则输出0

简化的感知机模型未免也太弱智了,必须所有的传入神经同时刺激胞体才能使此神经元有响应(激活)。于是科学家们把弱智的神经元胞体改造了一下,成为下面这样子(图片来自网络,所以下图的y对应于上图的output)

这就有点高级了,首先,每个传入信号$x_i$都被标注了权重$w_i$,还增加了偏置b(bias)。其中c是组合函数(通常情况是求和),a为激活函数(这个有点复杂,有兴趣的自行google)。别被上面的图搞糊涂,其实神经元(感知机)就是一个数学公式:$y=(x_1 * w_1+x_2 * w_2+…+x_n * w_n+b)*a$ 即首先对所有的输入数据乘以对应的权重并求和,最后与激活函数相乘。

也许你会发现_卧槽这么简单,小学乘法呀,那有什么卵用_。感知机能(且一定能)将线性可分的数据集分开,想不明白的可以看这篇文章的第一节感知机能做什么?。除了区分线性可分数据集以外,缺失没什么卵用了,连异或(XOR)问题都解决不了。

2. 我们把神经元连接起来(多层感知机)

自从发现感知机对除了线性可分的数据外没什么卵用以后,感知机的研究进入了寒冬,直到有个大神把几个感知机链接起来成下面的样子:

对于异或(XOR)问题,只要像上图一样,把三个神经元连接成两层,第一层神经元分别激活x+y>0 x+y<2,第二层的神经元像刚开始的弱智神经元一样,如果第一层神经元的输出都为1,那么输出为1即可。

这么简单的思路,为什么还会进入那么久的寒冬?其实不是上个世纪的人智商太低,而是因为这种多层网络无法训练。也就是说,以当时的技术无法确定神经元中w的值,所以对于输入信号多层感知机就不知道怎么激活了。直到BP算法的出现(BP算法请自行google)。其实1968年BP算法就被作者认识到了,并在1974年写在了毕业论文中,只是因为寒蝉效应没人理他。直到1986年这种方法才流行开来。

可以证明,多层神经元可以表达所有连续函数。因此,理论上讲,只要网络足够大,层数足够多,神经网络是可以拟合各种问题的!(当然网络太大就过拟合了- -)

0x02 卷积神经网络历史

假设我们要对100×100像素的图片进行分类,如果用上面的多层感知机来做(现在叫全连接层),那么输入数据就是10000个,如果再来几十层网络,每层几千个节点,那么估计也只有朝鲜的计算机才能算出来了吧>_<

1. 图像的卷积

之前接触过图像算法的同鞋们对卷积一定很熟悉,什么Laplaciansoble算子之类的讲的就是卷积核。图像卷积的计算方法其实就是滑动窗口和加权平均(如下图所示)。对于原始图片,用一个固定的卷积核在图片上滑动,每滑动一个像素就计算对应位置的加权和并记录下来。

图像经过不同的卷积核后产生的新图像是不同的,比如下图的原始图片分别用了低通和高通卷积核后的结果。

再比如下图(原始图片分别用之前说的Laplacian,soble卷积核卷一下):

经过观察以后,不难明白卷积对于图像的意义是提取图像不同频段的特征

2. LeNet

上一章讲了1986年BP算法开始流行,证明了多层网络可以训练以后,Yann LeCun大牛像我一样意识到不能用全连接层进行图片分类后就开始了卷及神经网络的研究,并解决了应用在书信邮编中的手写数字的分类问题。其实只用模板匹配(只有10个神经元的单层感知机)的方法也能进行识别,但是效果只能达到92%(多层感知机为98%)。模板匹配的方法跟卷积一模一样,只是卷积核的大小等于输入图片的大小,我训练的模板如下图,代码见之前的博文:

LeNet的基本原理就是对输入图像一层一层的卷积,最后接一个softmax把结果分为10类。论文实在是太长了,有兴趣的同鞋可以看看。

3. AlexNet

上个世纪的计算机硬件实在太差了,卷积网络又是个耗资源的方法,所以没被广泛应用。(同等资源下传统特征+SVM也可以取得相当的效果,看过上个世纪Andrew Ng机器学习课的应该都知道,神经网络的讲解几乎是一带而过,重点都是SVM、AdaBoost、随机森林、GBDT、LR、FTRL这些概念)

到了2012年,Alex借助GPGPU技术,使用了两个NVIDIA GPU进行并行训练(话说作者确实牛逼,用GPU就算了,还来了个多GPU并行),使得top5错误率一下子降低到了17.0%

除了多GPU+更深的网络层数,AlexNet还体现了LRN Dropout ReLU等现在流行的方法(再次膜拜)。

4. VGG

没有什么问题是多层卷积网络解决不了的,如果有,那就再加10层。于是Karen Simonyan就把AlexNet的网络由8层加深到19层,取名叫VGG,夺得了当年比赛的第二名。(其实也有新技术啦,比如把卷积核变小- -)

5. GoogLeNet

当年VGG运气不好,碰到了GoogLeNet,否则就是比赛第一名了。

为什么GoogLeNet排名第一呢,是的,因为比VGG还要深十几层。但是,巨量参数容易产生过拟合也会增加计算量,说白了就是网络无法训练。因此GoogLeNet提出了一个叫做Inception的子结构,如下图:

Inception将一个图像分别用不同大小的卷积核卷一下,然后连接起来,据说让参数量降低了好几倍。其中Inception其实有好多好多版本,有兴趣的同鞋可以自定Google。完整的GoogLeNet如下图。

6. ResNet

GoogLeNet在某种程度上可以看作把网络加宽了,而ResNet不一样,依然坚信着没有最深只有更深。何凯明一口气把网络加深到了一百多层,然后在当年的ImageNet比赛中拿了第一。

然而其实并没有这么简单(据说朝鲜早就在研究1000层的神经网络了,也没见他们得奖)。大神设计了一个叫做残差的模块(如下图),一层网络不仅仅连接着下一层,还通过飞线跨过几层走到了后边。

7. DenseNet

ResNet 虽然效果了不得,但速度确实有点慢。ResNet的思想是把一层的输出跨几层传递到后面,DenseNet的思路更简单粗暴,把所有的层都连接起来了(在连接处的区别为ResNet是求和,DenseNet是concat),实验效果超好。

8. 总结

做目标检测(YOLO)的官网有个统计,我贴出来供参考:

  • AlexNet: The model that started a revolution! The original model was crazy with the split GPU thing so this is the model from some follow-up work.

  • Darknet Reference Model: This model is designed to be small but powerful. It attains the same top-1 and top-5 performance as AlexNet but with 1/10th the parameters. It uses mostly convolutional layers without the large fully connected layers at the end. It is about twice as fast as AlexNet on CPU making it more suitable for some vision applications.

  • VGG-16: The Visual Geometry Group at Oxford developed the VGG-16 model for the ILSVRC-2014 competition. It is highly accurate and widely used for classification and detection. I adapted this version from the Caffe pre-trained model. It was trained for an additional 6 epochs to adjust to Darknet-specific image preprocessing (instead of mean subtraction Darknet adjusts images to fall between -1 and 1).

  • Extraction: I developed this model as an offshoot of the GoogleNet model. It doesn’t use the “inception” modules, only 1x1 and 3x3 convolutional layers.

  • Darknet19: I modified the Extraction network to be faster and more accurate. This network was sort of a merging of ideas from the Darknet Reference network and Extraction as well as numerous publications like Network In Network, Inception, and Batch Normalization.

  • Darknet19 448x448: I trained Darknet19 for 10 more epochs with a larger input image size, 448x448. This model performs significantly better but is slower since the whole image is larger.

  • Resnet 50: For some reason people love these networks even though they are so sloooooow. Whatever.

  • Resnet 152: For some reason people love these networks even though they are so sloooooow. Whatever.

  • Densenet 201: I love DenseNets! They are just so deep and so crazy and work so well. Like Resnet, still slow since they are sooooo many layers but at least they work really well!

0xFF 附录 瞎扯淡 - 什么是卷积

接着第0章的卷积继续说

1. 给卷积一个通俗的解释——关于卷积的一个血腥的讲解

比如说你的老板命令你干活,你却到楼下打台球去了,后来被老板发现,他非常气愤,扇了你一巴掌(注意,这就是输入信号,脉冲),于是你的脸上会渐渐地(贱贱地)鼓起来一个包,你的脸就是一个系统,而鼓起来的包就是你的脸对巴掌的响应,好,这样就和信号系统建立起来意义对应的联系。下面还需要一些假设来保证论证的严谨:假定你的脸是线性时不变系统,也就是说,无论什么时候老板打你一巴掌,打在你脸的同一位置(这似乎要求你的脸足够光滑,如果你说你长了很多青春痘,甚至整个脸皮处处连续处处不可导,那难度太大了,我就无话可说了哈哈),你的脸上总是会在相同的时间间隔内鼓起来一个相同高度的包来,并且假定以鼓起来的包的大小作为系统输出。好了,那么,下面可以进入核心内容——卷积了!

如果你每天都到地下去打台球,那么老板每天都要扇你一巴掌,不过当老板打你一巴掌后,你5分钟就消肿了,所以时间长了,你甚至就适应这种生活了……如果有一天,老板忍无可忍,以0.5秒的间隔开始不间断的扇你的过程,这样问题就来了,第一次扇你鼓起来的包还没消肿,第二个巴掌就来了,你脸上的包就可能鼓起来两倍高,老板不断扇你,脉冲不断作用在你脸上,效果不断叠加了,这样这些效果就可以求和了,结果就是你脸上的包的高度随时间变化的一个函数了(注意理解);如果老板再狠一点,频率越来越高,以至于你都辨别不清时间间隔了,那么,求和就变成积分了。可以这样理解,在这个过程中的某一固定的时刻,你的脸上的包的鼓起程度和什么有关呢?和之前每次打你都有关!但是各次的贡献是不一样的,越早打的巴掌,贡献越小,所以这就是说,某一时刻的输出是之前很多次输入乘以各自的衰减系数之后的叠加而形成某一点的输出,然后再把不同时刻的输出点放在一起,形成一个函数,这就是卷积,卷积之后的函数就是你脸上的包的大小随时间变化的函数。本来你的包几分钟就可以消肿,可是如果连续打,几个小时也消不了肿了,这难道不是一种平滑过程么?反映到剑桥大学的公式上,f(a)就是第a个巴掌,g(x-a)就是第a个巴掌在x时刻的作用程度,乘起来再叠加就ok了,大家说是不是这个道理呢?我想这个例子已经非常形象了,你对卷积有了更加具体深刻的了解了吗?

看到这里,我们简直不能更明白,什么是卷积了

  • 时不变系统:就是系统的参数不随时间而变化,即不管输入信号作用的时间先后,输出信号响应的形状均相同。就是说不管老板什么时候打你,肿胀发展的程度是一样的
  • 线性时不变系统:在时不变系统中满足叠加原理。即老板在t时刻打你N巴掌,那么肿胀的程度成N倍增加。

2. 物理意义

我们先画几个简单的函数图像,理解“卷积”的物理意义,暂时不管它为什么要对称,为什么要反转。

已知f(t)为老板在t时刻打了你f(t)巴掌。如下图,老板分别在第0秒时打了2巴掌,第1秒打了1巴掌,第2秒打了3巴掌;g(t)为打完巴掌后的t时刻肿胀的程度,下图刚打完时肿胀程度为2,等了1秒后变大为3,2秒后变成1,3秒后完全消肿。

下面三个图$h_0(t)$,$h_1(t)$,$h_2(t)$,分别是f(0),f(1),f(2)单独作用时的h(x)值,也就是分别为第0秒打了f(0)=2巴掌,第1秒打f(1)=1巴掌,第2秒打了f(2)=3巴掌的肿胀曲线。

计算方法为:$h_0(t) = f(0) * g(t) = 2 * [2, 3, 1] = [4, 6, 2]$

$h_1(t) = f(1) * g(t) = 1 * [2, 3, 1] $ 然后向右平移1个单位

$h_2(t) = f(2) * g(t) = = 3 * [2, 3, 1] = [6, 9, 3]$ 然后向右平移2个单位

很明显,要求t时间的作用程度h(t),就是把上面三个函数加起来$h(t)=h_0(t)+h_1(t)+h_2(t)$

  • 说白了,卷积就是平移、叠加。(从这里,可以看到卷积的重要的物理意义是:一个函数(如:单位响应)在另一个函数(如:输入信号)上的加权叠加。)

由上图可知,你在第三秒的时候肿胀程度为10. (记住这个结果,后面要放大招了)

3. 更有意思的来了

我们接下来做一个简单的初中数学题。求$(3x^2+x+2)*(x^2+3x+2)$ 中$x^3$的系数。

普通方法

常规做法是先把它合并同类项:

$(3x^2+x+2)*(x^2+3x+2)$
$=(3x^4+9x^3+6x^2)+(x^3+3x^2+2x)+(2x^2+6x+4)$
$=3x^4+10x^3+11x^2+8x+4$

进行完计算后,我们一眼就可以看出$x^3$的系数是10. (这种算法,我们一共进行了9次乘法运算和4次加法运算

文艺方法

还是刚才那个题目,进行如下计算:

  1. 我们把第一个多项式反过来,使其一个降幂排列,一个升幂排列。公式变成了$(2+x+3x^2)*(x^2+3x+2)$
  2. 平移:把第二个多项式每次向右平移一项
  3. 相乘:竖直对齐的项分别相乘
  4. 求和:相乘的结果相加

反褶,平移,相乘,求和,这就是卷积的计算过程。(我们在求$x^3$的系数时,只需要进行1次平移运算,2次乘法,1次加法运算

4. 结论

不知道有没有人注意到,我们刚才计算的方法1其实就是前面用那一大堆图描述的方法,注意看公式X的指数就是图像的横坐标,系数为纵坐标的值。(上题x^3的系数为10,第3秒时肿胀程度也恰好为10。)

运用在连续函数中,只需把最后一步的求和改成求积分即可。

参考: