目录
2.1 1968年——CNN思想起源——Hubel 和Wiesel:
2.2 1980年——Neocognitron——福岛邦彦(Kunihiko Fukushima)
2.7 2012年——AlexNet——Alex Krizhevsky
3.2 在之前猫图片分类的实验中,我们使用的是全连接神经网络,现在为何要引入CNN呢?
3.4 边缘的过渡——如何区分正边和负边(由亮到暗与由暗到亮的区别)。
3.7 卷积步长(Strided convolutions)
3.12 卷积神经网络示例(包含池化层,与手写数字体识别网络架构类似)
3.13 为什么使用卷积?(Why convolutions?)
3.19 “Network in Network” 和 1x1卷积简介。
3.21 如何通过使用1×1卷积来构建瓶颈层,从而大大降低计算成本
3.39 Siamese 网络(Siamese Network)
3.41 人脸验证与二分类(Face verification and binary classification)
4.1 最大池化(Max Pooling)比平均池化(Average Pooling)在卷积神经网络中更常用的原因。
4.3 LRN为啥被Batch Normalization取代了呢?
4.4 “VGG使用多个较小卷积核(3x3)的卷积层代替一个卷积核较大的卷积层”的原因。
4.6 机器学习中训练样本的标签是真实值还是观测值?(待解决)
4.7 深度学习中对图片数据集扩充,是先对整个数据集增强再划分训练、验证和测试集,还是先划分再仅对训练集扩充?
4.9 如何直观理解这两个代价函数的关注点?为啥内容代价函数是激活值相近?风格代价函数是通道之间相关性?
0 完整章节内容:
深度学习入门指南——2021吴恩达学习笔记deeplearning.ai《深度学习专项课程》篇
1 优质笔记:
2 卷积神经网络的前世今生。
科学的发展往往不是一往无前的,不是按照教科书上编排那样诞生的。举一个可能和大家直觉相悖的例子,打火机早于火柴被发明,而ReLU比Tanh更早被应用在神经网络中。
2.1 1968年——CNN思想起源——Hubel 和Wiesel:
我们知道,神经网络这一概念最早是生物界提出的,而人工智能界的神经网络很大程度上是在模拟人类的神经元。虽然业界对我们是否需要继续仿生这条路,还是开辟一条不同于生物神经网络的路还有不少的争议,但是读完很多论文我发现现代人工神经网络受生物研究的影响可能比我们想象中要更大。
影响到CNN起源的相关研究是有关视觉皮层的,其中较著名的是Hubel 和Wiesel1968年做出的工作。在这项工作前,人们已经对这个领域有一些了解。我将他们罗列出来。
前置知识:
首先我们人类的大脑有的神经元,每个神经元上有1000个轴突,也就是说有
个神经连接。
另外每只人类的眼睛有个视觉接收器(比如视锥,视杆等等),但是我们只有
的视觉神经。因此,我们可以知道每一个视觉神经都接收来自许多视觉接受细胞的输入。
另外一个已经被实验表明的点是,我们视觉神经不是简单的告诉大脑光线被检测到,而是说光线和黑暗之间的对比,也就是形状被感受到了。
最后人们发现我们的每个单个神经元并不会对整个图像做出回应,而是只对其负责的receptive filed响应,这里有人翻译为感受野,也有称作接受域的。
在这些知识的基础上, Hubel 和Wiesel做了什么呢?
在这些事实的基础上,Hubel和Wiesel干了一件事,他们将猫麻醉后,把电极插到其视觉神经上连接示波器,并给它们看不同的图像,观察脑电波的反应。如下图所示:
当然,这个实验也引起了许多爱猫人士的抗议。
由这个实验,他们得到了一些新的有趣的现象:
- 外侧膝状核LGN会响应一个微小的光点,但是对漫反射没什么回应。
- 视觉皮层从LGN接受信息时,它们不再响应光圈,但是对亮暗的线条有回应。
- 视觉皮层中有一类简单的皮质细胞,只会在以特定角度刺激特定区域时才会响应。 对于某个简单细胞的无效响应区域会是另一个细胞的有效响应
- 其他细胞(复杂皮质细胞)也只响应特定方向的光,但是不再对区域敏感,这些光可以在屏幕上移动而不会导致失活。这可以解释为一组简单的皮层细胞在复杂细胞上汇聚。
非专业人士大概率看不太懂上述现象表述的是什么,不过我们可以看到关键字是“特定”,也即各司其职,汇聚在一起组成一个视觉皮层。
由这些现象得到的结论有:
- 每个处理步骤中,许多中间神经元的输入集中到一个输出上
- 因此,每一步中,有一些信息被选择性销毁了 (例如对于一个简单的皮层细胞,当某些LGN细胞在上面汇聚时它才会激活)
- 通过这种方式,大脑每个级别都会充当过滤设备,这种机制能够区分某些非常复杂的特征
- 哺乳动物的大脑不响应特定电路的特定脉冲,而是响应许多脉冲时空上的汇聚电路
由于这项发现,Hubel和Wiesel共享了1981年的诺贝尔奖。这项发现不仅在生物学上留下浓墨重彩的一笔,而且对20年后人工智能的发展埋下了伏笔。
熟悉CNN的同学可能已经察觉到这项发现和人工神经网络中很多概念都有呼应。
最直接的就是如下图的多层级结构,这项研究发现几层不同的细胞,最早的视网膜和LGN用于接受视觉信息并做初步处理响应光点,然后简单细胞开始响应线条,再之后复杂细胞和超复杂细胞做进一步处理。

另一个就是过滤(filtering)的概念,我们不同细胞只对特定的输入感兴趣,而会过滤掉其他的信息。例如有的细胞只响应45°的线条,有的只响应某些颜色

此外还有本地连接,即每个神经元不会对整个图像做出响应,它只会对其本地附近的区域感兴趣。

最后但是同样重要的概念就是平移不变性(这里也有把不变性说做是等变性的,这两种说法从不同角度来看是可以等价的,这里不过过多讨论,统一称作不变性),之前的实验表明了,即使我们将屏幕中的光条平移,猫的复杂视觉神经元依然能够被激活。 之后的研究发现,这种不变性不仅体现在平移不变上,同时也可以处理图像的翻转裁剪放缩等等。再后来的发现表明,优先复杂细胞能够保持的不变性非常的广,一个针对人类病患的实验找出病人脑中对著名演员Halle Berry响应的那部分神经元(我也不知道他们怎么能找到的),接着实验发现无论是长发还是短发,乃至穿上了猫女服装遮掩,甚至含有halle berry名字的文本都能激活该神经元。 这种不变性被认为是启发了神经网络中池化单元的设计。
虽然我们在生物上得到了很多启发,但是我们对人类大脑的工作机理的了解仍然只是皮毛,由此也给仿生的CNN留下许多疑惑。例如:
- 我们不了解大脑是如何训练这个网络的;
- 之前所说的简单细胞和复杂细胞以目前生物技术来看没有生理上的不同,那么它又是通过何种方式用怎样的参数使得同样的结构能够发挥不同作用呢;
- 我们观测到的视觉系统往往是不独立的,人类的视觉系统会集成许多其他感觉,例如听觉,心情等等。 而目前的CNN往往是负责纯粹一种感知;
- 现在简单细胞的线性处理已经比较明了了,但是复杂细胞如何达到非线性的呢,这一点还不得而知,这也为人工神经网络中激活函数的研究留下空间。
总之,这么来看,CNN中大部分重要的思想都在生物中有所体现,下面如何用在计算机中实现这种网络呢,就到了计算机科学大放异彩的时候了。
2.2 1980年——Neocognitron——福岛邦彦(Kunihiko Fukushima)
在Hubel和Wiesel因他们的卓越贡献获得诺贝尔奖的前一年,日本科学家福岛邦彦提出了neocognitron,其目标是构建一个能够像人脑一样实现模式识别的网络结构从而帮助我们理解大脑的运作。在这篇工作中,他创造性的从人类视觉系统引入了许多新的思想到人工神经网络,被许多人认为是CNN的雏形。Neocognitron是他之前工作Congnitron的改进,这里新的网络结构能够满足平移不变性。
我们先来看他的结构,这里,仿照生物神经网络,他设计了两种不同的cell,一种是simple cell,一种是Complex cell。对于输入多个区域,若干个Cell汇聚在一起各自处理一部分形成一个plane(平面),而一层网络又由多个plane组成。

注意到这里示意图中有两点:
- 对于C-cell来说它只接受自己这个plane中上一层对应plane的结果作为输入,而对于S-cell来说,它会接受上层网络中多个plane的输出。
- 随着网络层数的加深,每个cell的感受野越来越大,也由此每个plane包含的cell个数也越来愈少。
该结构与生物结构一一对应起来就是:先是简单细胞,然后复杂细胞,低阶超复杂细胞,高阶超复杂细胞,最后到祖母细胞。
注意一下这里简单细胞的突触是不可修改的(也就是设定初始值后就不再变化了)
为了简洁起见,另外图中画出的cell都是激活的cell,但是每个layer中也有被抑制的S/Ccell。
下面我们来看一下细节部分:
这里update S-cell的部分,l是层数,而k是plane编号。这里r是表示这一层的激活的效率,而𝜑起到的作用类似于线性整流器。仔细来看激活函数内的部分:分子上是可以看作是对前一层C-cell输出的加权求和,这个操作可以被看作是一个averaging pooling的池化。a表示兴奋突触的效率,外层循环是针对plane的,内层循环则是针对cell的感受野的,这里n可以视为position,v则可以看作是偏移。每个plane中cell的感受野形状相同,如图这层感受野就是一个T形的区域,那么所有cell的是使用的一个相同的感受野。分母上是上一层被抑制突触的部分,b表示抑制效率,v是被抑制的C-cell,其计算公式可以看作是RMS type的映射。
我们可以看到,这里每个S-cell的特征提取在形式上都是并行的,只是其处理的感受野的位置不同,因此,如果能够激活某个S-cell的模式位置进行了变动,那么被激活的S-Cell的位置也会做相应的变动。
C-Cell的处理类似S-Cell,但是形式上更简单些,每个C-cell只接受上一层其对应的plane的信息。这里就不再多说了。
总结起来Neocoginitro有哪些贡献呢?
- 将脑神经科学的结构在做了计算机模拟;
- 提出了现在CNN常用的step-by-step的filter;
- 使用ReLU来给网络提供非线性;
- 采用平均池化来做downsampling;
- 保证了网络的平移不变性;
- 实现了稀疏交互。
这么一看的话,基本上大部分现代CNN的结构在这个模型上都已经得到了体现。卷积运算的三个重要思想:稀疏交互,参数共享和等变表示也只有参数共享没有考虑到了。
但是这个模型虽然做的非常漂亮,但是其最大的局限在于它是使用基于WTA(Winner Take All)的无监督学习,因此这个很fancy的模型一直很欠缺实用性。
2.3 1989年——LeNet-1——LeCun
在开始介绍这块之前,我们有必要了解一下BP算法的发展历程:
提到“反向传播之父”,大家首先想到的可能就是Geoffrey Hinton,但其实事实并非如此。
- 1960年,反向传播由Henry J. Kelley提出的控制理论(control theory)和 1961年Arthur E. Bryson 提出的理论衍生而来,他们使用的思想是动态规划。
- 1962年, Stuart Dreyfus 发表了仅基于链式规则(chain rule)的更简单推导。
- 1969年,作为人工神经网络创始人的明斯基(Marrin M insky)和佩珀特(Seymour Papert)合作出版了《感知器》一书,论证了简单的线性感知器功能有限,不能解决如“异或”(XOR )这样的基本问题,而且对多层网络也持悲观态度。这些论点给神经网络研究以沉重的打击,很多科学家纷纷离开这一领域,神经网络的研究走向长达10年的低潮时期。同年,Bryson and Ho 将反向传播描述为一种多阶段(multi-stage)动态系统优化方法。
- 1970年, Linnainmaa 出版了一个为了解决discrete connected networks的自动分化问题更加通用的方法,这实际上是开发反向传播算法的第一步。这就是所对应的反向传播。(backpropagation),在稀疏网络也非常有效率。反向传播算法由 Seppo Linnainmaa 最早于1970年实现在计算机上运行。
- 1974年,哈佛大学的Paul Werbos发明BP算法时,正值神经外网络低潮期,并未受到应有的重视。Werbos提到了将此应用于人工神经网络(Artificial Neural Network,ANN)的可能性。
- 1982年,Werbos首次将Linnainmaa的AD方法应用于非线性函数(神经网络)。
- 1983年,加州理工学院的物理学家John Hopfield利用神经网络,在旅行商这个NP完全问题的求解上获得当时最好成绩,引起了轰动。然而,Hopfield的研究成果仍未能指出明斯基等人论点的错误所在,要推动神经网络研究的全面开展必须直接解除对感知器——多层网络算法的疑虑。
- 1985年,Werbos方法被Parker重新发现并描述。
- 1986年,反向传播算法由RumelhartRumelhart,Hinton和WilliamsWilliams重新描述,展示了这个方法可以根据输入数据适用隐含层来表示内在的联系。
- 1987年,卷积神经网络体系结构的发明者Yann LeCunYann LeCun 在博士学位论文中提出了神经网络的反向传播学习算法的现代形式。
- 1993年,Wan第一次适用反向传播赢得了国际模式识别竞赛。
- 2000年,神经网络仍不是很受欢迎,但在2010年代又回来了,得益于廉价,强大的基于GPU的计算系统。在语音识别语音识别,计算机视觉,自然语言处理和语言结构学习研究中尤其突出。
继1986年Hinton、Rumelhart 等人的计算实验证明了反向传播可以在神经网络的隐藏层中产生有用的内部表征后。LeCun在1987年自己的博士论文中提出了神经网络的反向传播学习算法的现代形式。并于1989年将反向传播正式应用到了类似Neocoginitro的网络上来做有监督学习,提出了LeNet-1。这下子就像是解开了五指山上的封条,CNN开始逐渐走向各个应用领域。
LeCun在这篇论文中延续了他在巴黎六大博士论文的工作,将BP延展开来。我们先来看这个网络里面定义的卷积操作,他吸取了Neocognitro的稀疏交互的优点,但他和福岛邦彦的网络最大不同在于,我们在生成每个feature map时,在所有的感受野都只用单个神经元。那么整个卷积操作就等价于用一个小尺寸的卷积核去扫描这个输入然后接一个squashing function。这个特性也就是权值共享,这个操作减少了自由变量的数量,也就减少了过拟合的风险,提高了泛化能力。参数的减少同时也加速了训练过程。
接下来来看下这个网络的结构,其实熟悉现代CNN架构的就已经很明白了。这里共有四层隐层和一层输出,其中H1和H3都是卷积层,而H2和H4都是downsampling层。其实网络架构并不是这篇论文的两点,虽然这篇文章提出了权值共享这一重要的思想,但是最重要的是它简化了卷积操作,便于将反向传播应用到CNN上,并且利用它解决了一个实际世界中的问题。
2.4 1992年——Cresceptron——翁巨杨
接着,在1992年,美籍华裔科学家翁巨杨发表了他的Cresceptron,虽然从结构上来看他的模型没有非常出彩之处,而且由于当时想模拟人脑的这种朴素思想,没有延续使用BP的监督学习而是用了一种非监督学习(也许在今天模拟人脑这种想法和强化学习的路子更近一些,人类在辨识物体时既不能看作是监督式学习,但也不能看作是完全的无监督)。但是这篇论文中的两个trick却被广泛应用至今。
其中第一个是数据增强(Data Augmentation),我们将训练的输入进行平移,旋转,缩放等变换操作然后加入到训练集中,一方面这可以扩充训练集,另一方面也提高了算法的鲁棒性,减少了过拟合的风险。

第二个技巧是最大池化的提出,改变了千篇一律的用平均池化做downsampling的状况。
有趣的是,今天看来,这篇论文中这两个较大的贡献在原文中却并没有作为亮点来讲,论文中着力强调的点反而时至今日无人问津。
2.5 1998年——LeNet-5——LeCun
时间来到世纪之交的1998年,LeCun同志在这一年用一篇长达46页的巨作提出了LeNet-5,虽然这篇工作中用了较多的篇幅去介绍整个自动识别系统,而不是针对单个被切割好的字母图片。但是我们这边还是只关注它的网络方面。
简单看一下LeNet-5的结构,和我们现在经常看到的CNN已经别无二致了。相比之前的工作,这里网络层数加深到了7层。其中两层卷积两层池化。
我们注意到这里从S2到C3的feature map数从6个增长到16个,显然两层之间并非一一映射,那么这里的映射关系是怎样的呢? 我们看左下这张图,反应了C3中不同的feature map的输入。这里也没有使用全连接,而是不同的feature map会有3~6个不同个数的不同范围的S2的输出作为其输入。
这里有两个好处:
- 其一就是不用全连接减少了连接的个数。
- 第二,更重要的是这种安排打破了不同feature map间的对称性,回想集成学习里我们需要尽可能多样的基学习器,这里也是同样的思想,保持各个feature map和而不同有利于其表征的鲁棒性。
LeNet-5还有一些有趣的细节,一个是使用了tanh作为激活函数,这里作者表示对称的激活函数能够更快收敛,我理解这里不用ReLU的原因在于98年的时候,网络的深度还不太深,因此梯度消失不是一个太大的问题,而相比之下加速收敛的性质更加重要。
此外论文在附录对比了随机梯度下降和批梯度下降 ,指出随机梯度下降以及mini-bathSGD能够极大加快拟合速度,并且最终效果很好。但是他也指出SGD在理论上还没有可靠的理解。
另一个改变是,在输出层,LeCun用RBF layer(径向基)取代了原来惯用的全连接层:
这里的w是参数,从形式上看,这里的输出像是输入和参数差值的一个惩罚项。从概率论的角度来看,RBF的输出可以被视作一个未被正则化的负的log似然的高斯分布。 这里使用RBF的好处在于,我们可以手工设定RBF的参数,比如这边F6层的输出是84位,我们将其组成一个7x12的位图,并提供这个如下图的打印体位图作为参照来设定RBF的参数。这个操作在判断0~9的数字时没有很大的效果提升,但是当候选项从数字变成全部的ASCII字母时,这种操作相较之前的方法在容易引起歧义的图像上(例如数字0和字母O)表现有了很大的提升。
这篇论文中,其baseline涵盖了几乎所有主流的机器学习方法,LeNet也技压群雄。本来以为这是神经网络崛起的号角,但是由于计算能力限制和SVM的大放异彩,神经网络在21世纪初迷失了近10年。
2.6 2006年——GPU-for-CNN——None
进入到新世纪,第一个突破并不是在算法上的,而是工程上。2006年,研究人员成功利用GPU加速了CNN,相比CPU实现快了4倍。虽然这里没有算法的提升,但是其意义可能比一般的算法提升更大。
2.7 2012年——AlexNet——Alex Krizhevsky
直到2012年,这一年AlexNet的出现可以说是标志着神经网络的复苏和深度学习的崛起。在imageNet2012的图片分类任务上,AlexNet以15.3%的错误率登顶,而且以高出第二名十几个百分点的差距吊打所有其他参与者。
而且从此,ILSVRC这个竞赛称为深度学习的风向标,每年的优秀队伍的解法都会得到极大关注。从2015年开始,以商汤科技,旷视科技,海康威视,公安部等四所机构为代表,中国队伍也在该项竞赛中争金夺银。由于到了2016年,state-of-the-art已经达到了2.99%,远远超过人类5.1%的水平,因此,2017年被定做是最后一届ImageNet的图像分类竞赛。
回到AlexNet,这里又用了什么新的CNN技术呢。其实总的来看,卷积/池化操作没有太大变化,不过层数有所加深。
整个网络主要的点有:
- 使用了ReLU作为激活函数,其实我们之前提到这在1980年的时候就已经被应用过了,不过十几年前LeNet又因为种种原因改为tanh。
- 使用了数据增强,这点在92年的Cresceptron被引入。
- 使用了mini-batch SGD,这是98年LeNet的做法。
- 在GPU上训练,这得益于06年CNN在GPU上的实现。
- 实现了Dropout层来避免过拟合。
大家可以发现除了最后一点Dropout之外,其他的亮点都是之前其他人工作的拼接。这点倒是启发了我,其实老论文有的时候比新出炉的论文更值得读,一来随着热度提升,各个会议的注水量稳步攀升,新出论文的质量相比经时间考验的老论文而言更低,研究research,拆开来就是re-search,不断搜索之前的想法,也许能得到新的思路。
总之,AlexNet成功的打响了第一枪,这之后新的 CNN层出不穷,甚至你出去吃个午饭的功夫世界上就有一个新的CNN被提出。因此下面我们就挑选一个具有代表性的来说一下。
2.8 2015年——ResNet——Kaiming He
这篇论文就是15年底何凯明大神提出的ResNet,要说它的最大特点的话,就是很深。他也是第一个在ImageNet图片分类上表现超过人类水准的算法。

其实我们之前提到了,ImageNet竞赛上面,使用的模型的层数逐年加深,但是人们发现,越深的网络越难以训练,往往会会遇到梯度爆炸,梯度消失,梯度弥散等问题而导致网络退化。那么ResNet是如何解决这个问题的呢?
下面我们来看这个网络中最重要的组成部分,也就是残差块。纵向来看,这个模块有三层,是两层卷积(也可以是全连接)包含了一层激活,另外,还有一条线将输入直接短接到下面的加法上去。也就是微观上来看,我们这个小模块学习到的是原始输入和期望输出的差值。通常来说我们的不同层的feature map往往是在不同的空间中的,这里,加上去的这个x给输出提供一个reference,使得输入输出落在一个空间中。这样能够保证随着深度的提高,其feature map不会有太难以掌控的变化,从而解决了网络退化的问题。其实在此之前,已经有相关文章研究了短路的问题,但是通常都是用一个依赖于其他参数的gate去控制这种短接,这里将大门常年打开,最终避免了网络退化。
2.9 回顾和展望
那么回顾一下这些年的CNN的发展,它能够取得这么耀眼的成绩主要得益于以下几点:
- 首先是卷积和池化带来的 转换不变性
- 第二个就是尺度分离,这里是由这种多层的结构带来的,这个思想可追溯到1968年的Simple Cell和Complex Cell
- 然后就是利用了空间的本地性
- 接下来就是由稀疏连接,权值共享带来的参数个数的下降而提升了计算效率。

回顾一下CNN发展史,可以发现,大部分问题其实都是在2000年前搞定的。

我们不妨来对比一下2012年的AlexNet和14年前的LeNet-5. 我们的输入的数据量提高了,计算速度提高了20倍左右,而算法似乎只是在原来的基础上加深了一些,另外加了一些精细化的正则化或是改了下激活函数。所以其实新世纪中深度学习的成就在更多程度上是由我们数据量增加,计算能力增加带来的,而非算法的改进。很多人也对现在这种军备竞赛式的拼谁家GPU多的发展模式产生了质疑。
The pooling operation used in convolutional neural networks is a big mistake and the fact that it works so well is a disaster.
I am deeply suspicious of back-propagation, my view is throw it all away and start again.
—Geoff. Hinton
Hinton在14年的时候就说过,CNN的池化操作是一个大错,而由此带来的效果则是一场灾难。他对自己搞出来的反向传播深表怀疑,觉得我们应该抛下这些重起炉灶。
当然Hinton这种大牛也没啥科研压力了自然有底气说这些,不过马云不也说“我对钱没有兴趣”,“我这辈子最后悔的就是创建阿里巴巴”嘛。在2014年Hinton给出了一个名为“What is wrong with CNN”的演讲,提出了四点质疑。其中有的点现在已经部分解决,有的观点时至今日仍发人深省。有兴趣的同学可以去youtube看一下这个演讲。
这些质疑都预示着,CNN的进一步发展不能再仅仅依靠简单的改改模型了。在前沿的研究中,其中很有前景的是这三个方向。
分别是:
- 基于球体做CNN;
- 在流形上做CNN;
- 在图上做CNN。
这三者都可以看作是将传统CNN从欧几里得空间向外延展到非欧空间,分别到黎曼空间,流形空间和图上。
大家看近几年ICLR,ICML以及NIPS上比较有影响力的文章,有许多都是在这三个方向做文章。
3 重点:
3.1 计算机视觉的典型应用场景。
计算机视觉是一个快速发展的领域,深度学习极大地推动了这一领域的进步。典型的应用场景包括:
- 自动驾驶:识别周围的行人和车辆,帮助汽车做出避障决策。
- 人脸识别:用于解锁手机和门锁,提高安全性和便利性。
- 图片分类和目标检测:如在社交媒体应用中分析和推荐图片,识别出图像中的物体并定位它们的位置。
- 图像风格迁移:通过神经网络将一张图片的风格迁移到另一张图片上,创造出新的艺术作品。
3.2 在之前猫图片分类的实验中,我们使用的是全连接神经网络,现在为何要引入CNN呢?
在处理图像数据时,卷积神经网络是一种高效的架构。传统的全连接神经网络在处理高维度图像(如1000×1000的RGB图像)时,参数量巨大(可达30亿),易导致过拟合且计算成本高。CNN通过卷积运算有效减少参数量,同时保留图像的空间信息。
如果你要操作更大的图片,比如一张1000×1000的图片,它足有1兆那么大,但是特征向量的维度达到了1000×1000×3,因为有3个RGB通道,所以数字将会是300万。如果你在尺寸很小的屏幕上观察,可能察觉不出上面的图片只有64×64那么大,而下面一张是1000×1000的大图。
如果你要输入300万的数据量,这就意味着,特征向量的维度高达300万。所以在第一隐藏层中,你也许会有1000个隐藏单元,而所有的权值组成了矩阵W 。如果你使用了标准的全连接网络,就像我们在第一门和第二门的课程里说的,这个矩阵的大小将会是1000×300万。因为现在x的维度为3m,3m通常用来表示300万。这意味着矩阵W会有30亿个参数,这是个非常巨大的数字。在参数如此大量的情况下,难以获得足够的数据来防止神经网络发生过拟合和竞争需求,要处理包含30亿参数的神经网络,巨大的内存需求让人不太能接受。
3.3 边缘检测示例
在之前的章节中,我们提到过神经网络的前几层是如何检测边缘的,然后,后面的层有可能检测到物体的部分区域,更靠后的一些层可能检测到完整的物体。接下来,你会看到如何在一张图片中进行边缘检测。
让我们举个例子,给了这样一张图片,让电脑去搞清楚这张照片里有什么物体,你可能做的第一件事是检测图片中的垂直边缘。比如说,在这张图片中的栏杆就对应垂直线,与此同时,这些行人的轮廓线某种程度上也是垂线,这些线是垂直边缘检测器的输出。同样,你可能也想检测水平边缘,比如说这些栏杆就是很明显的水平线,它们也能被检测到,结果在这。
所以如何在图像中检测这些边缘?

为什么这个可以做垂直边缘检测呢?让我们来看另外一个例子。为了讲清楚,我会用一个简单的例子。这是一个简单的6×6图像,左边的一半是10,右边一般是0。如果你把它当成一个图片,左边那部分看起来是白色的,像素值10是比较亮的像素值,右边像素值比较暗,我使用灰色来表示0,尽管它也可以被画成黑的。图片里,有一个特别明显的垂直边缘在图像中间,这条垂直线是从黑到白的过渡线,或者从白色到深色。

如上图最左侧所示,我们可以看到在第3列->第4列(下标从1开始)有一个明显的垂直边缘,因此我们使用该垂直边缘卷积核就能很好的检测出该垂直边缘(上图最右侧的第2列以及第3列)。
3.4 边缘的过渡——如何区分正边和负边(由亮到暗与由暗到亮的区别)。
首先让我们定义一下什么是正边?什么是负边?
实际上,正边和负边的定义实际上是相对卷积核(filter/kernel)的取值模式而言的。卷积核的设计会影响到边缘检测的结果,即检测到的边缘类型(正边或负边)取决于卷积核的具体结构。
1)亮到暗的卷积核
例如,经典的Sobel卷积核之一(检测水平方向,从亮到暗的变化):
这个卷积核的取值模式是:左侧为正,右侧为负。因此,它检测的是从左侧亮(高像素值)到右侧暗(低像素值)的变化。对于这个卷积核:
- 从亮到暗时,卷积结果为正值,即为正边。
- 从暗到亮时,卷积结果为负值,即为负边。
2)暗到亮的卷积核
如果我们反转卷积核的取值,即从暗到亮的变化:
这个卷积核的取值模式是:左侧为负,右侧为正。它检测的是从左侧暗(低像素值)到右侧亮(高像素值)的变化。对于这个卷积核:
- 从暗到亮时,卷积结果为正值,即为正边。
- 从亮到暗时,卷积结果为负值,即为负边。

参见例子1和例子2,使用的卷积核皆为从亮到暗的卷积核,我们可以观测到:
- 在例子1最右侧图中,得到的乘积和皆为30,这就表示正边(例子1中最左侧图从左到右是由亮到暗的);
- 在例子2最右侧图中,得到的乘积和皆为-30,这就表示负边(例子2中最左侧图从左到右是由暗到亮的)。
当然,有时我们只关心是否存在边缘,而不关心边缘的方向。这时,可以对卷积结果取绝对值。

- 这里的30(右边矩阵中绿色方框标记元素)代表了左边这块3×3的区域(左边矩阵绿色方框标记部分),这块区域确实是上边比较亮,而下边比较暗的,所以它在这里发现了一条正边缘;
- 而这里的-30(右边矩阵中紫色方框标记元素)又代表了左边另一块区域(左边矩阵紫色方框标记部分),这块区域确实是底部比较亮,而上边则比较暗,所以在这里它是一条负边。
- 这些中间的数值,比如说这个10(右边矩阵中黄色方框标记元素)代表的是左边这块区域(左边6×6矩阵中黄色方框标记的部分)。这块区域左边两列是正边,右边一列是负边,正边和负边的值加在一起得到了一个中间值。
3.5 可学习的过滤器
1. 可学习的过滤器
在卷积神经网络(CNN)中,我们通过卷积操作将一个小的过滤器(如3×3的矩阵)与输入图像进行卷积。关键的改进在于,过滤器的9个权重参数不再是固定的,而是由网络自动学习得到。也就是说:
- 过滤器的参数成为可学习的变量。
- 这些参数通过反向传播(Backpropagation)算法,根据损失函数对其进行优化。
2. 过滤器的多样性与泛化能力
由于过滤器的参数是通过学习而非手动设计的,神经网络可以自动找到最能帮助其识别特定特征的过滤器:
- 它们可以检测任意角度的边缘(如45°、70°、甚至是73°的边缘),而不是局限于水平或垂直方向。
- 神经网络不仅能学习到边缘特征,还可以捕捉到更加复杂的低级特征(如纹理、角点),甚至在深层卷积层中可以学习到高级特征(如物体形状、脸部轮廓)。
3.6 Padding(填充)
Padding 是深度神经网络中卷积操作的一个重要技巧,用于在输入图像边缘填充像素,以避免卷积过程中图像尺寸的缩小,并保留图像边缘的信息。
1. Padding 的作用
两个主要问题:
-
图像尺寸缩小:
- 使用卷积操作时,图像尺寸会不断缩小。比如,使用一个 3×3 的过滤器对 6×66 \times 6 的图像进行卷积,输出是 4×4 的矩阵。
- 随着卷积层的增多,图像会变得越来越小,影响深度网络的表现和特征提取。
-
图像边缘信息丢失:
- 边缘的像素点在卷积时被使用的次数较少,导致边缘特征可能没有被很好地学习和利用。
解决方法:在图像边缘填充像素,使图像在卷积时不变小,并保留更多边缘信息。
2. Padding 的两种常见模式
-
Valid 卷积:
- 不使用填充,图像在卷积过程中会缩小。
- 例如:输入为 n×n ,过滤器为 f×f ,输出大小为 (n−f+1)×(n−f+1) 。
-
Same 卷积:
- 使用填充,使得输出图像的尺寸和输入图像相同。
- 为了达到这个效果,填充 p 的值为 (f−1)/2,其中 f 是过滤器的尺寸。
- 例如:使用 3×3 过滤器时,p=(3−1)/2=1,即在图像四周各填充 1 个像素。
3. 为何过滤器大小通常为奇数?
- 中心点对称:
- 奇数大小的过滤器(如 3×3, 5×5)具有一个中心点,这使得卷积操作在图像上有一个明确的中心位置。
- 对称填充:
- 使用奇数大小的过滤器时,可以在图像四周进行对称填充,如填充 p=(f−1)/2,避免不对称填充(左边和右边、上边和下边填充不同数量的像素)。
3.7 卷积步长(Strided convolutions)
步幅(Stride) 是卷积操作中的一个重要参数,决定了过滤器在输入图像上移动的步长。调整步幅可以改变输出特征图的尺寸,并且对计算效率和特征提取有重要影响。
1. 步幅的定义
- 步幅 s:过滤器在输入图像上移动的距离。
- 例如,步幅为 1 时,过滤器在图像上每次移动 1 个像素。
- 步幅为 2 时,过滤器每次移动 2 个像素,跳过 1 个位置。
2. 步幅的影响
使用 3×3 的过滤器对 7×7 的图像进行卷积:
-
步幅为 1:
- 滤波器在图像上移动时,每次移动 1 个像素。
- 输出大小为 5×5。
-
步幅为 2:
- 滤波器每次移动 2 个像素,跳过 1 个位置。
- 输出大小为 3×3。
3. 举例
这里,n=7,p=0(注意是单侧的填充值),f=3,s=2,输出大小为3×3.
4. 输出维度计算公式
如果商不是一个整数怎么办?在这种情况下,我们向下取整,这意味着向下取整到最近的整数。
这个原则实现的方式是,你只在蓝框完全包括在图像或填充完的图像内部时,才对它进行运算。如果有任意一个蓝框移动到了外面,那你就不要进行相乘操作,这是一个惯例。
5. 卷积与互相关的区别
-
互相关 (Cross-correlation):
- 深度学习中,常用的“卷积”操作实际上是互相关,即不对过滤器进行翻转操作。
- 直接将过滤器应用于图像,进行逐元素相乘并求和。
-
卷积 (Convolution):
- 在数学和信号处理中,卷积操作包含翻转步骤,即将过滤器沿水平和垂直方向翻转后再与图像进行计算。
深度学习惯例:
- 在大多数深度学习框架中,卷积操作不包含翻转步骤,直接使用互相关。
- 这种简化可以加快计算速度,不影响特征提取效果。
3.8 3D卷积操作与多通道输入的理解
当我们处理 RGB 彩色图像 或者 多通道输入(例如深度图像、医学影像等)时,传统的 2D 卷积已经不再适用。此时我们需要使用 3D 卷积 来处理立体输入。这也是卷积神经网络(CNN)中处理多通道输入的重要步骤。
1. RGB 彩色图像与 3D 卷积
-
输入图像:假设一个彩色图像的尺寸为 6×6×3。
- 6×6 表示图像的高度和宽度。
- 3 表示图像有 3 个颜色通道(红、绿、蓝)。
-
3D 过滤器:一个 3×3×3 的卷积过滤器。
- 3×3 表示过滤器的空间尺寸(高度和宽度)。
- 3 表示过滤器的通道数,必须与输入图像的通道数匹配。
2. 卷积操作的步骤
-
过滤器匹配输入通道:输入图像的通道数为 3(RGB),过滤器的通道数也为 3。因此,过滤器可以看作是一个 3×3 的矩阵在 3 个通道上堆叠成 3×3×3 的立方体。
-
卷积计算:
- 将 3×3×3 的过滤器放在输入图像的最左上角位置。
- 对应位置的 27 个像素值与过滤器的 27 个权重进行逐元素相乘,并求和。
- 结果为一个单一的数值,作为输出特征图的第一个像素值。
-
移动过滤器:
- 过滤器按照步幅 s 移动一个位置,重复上述计算,直到遍历整个输入图像。
- 以步幅 s=1 为例,输出的尺寸为 4×4×1。
3. 多个过滤器的应用
为了检测不同的特征(例如边缘、纹理等),可以使用多个不同的过滤器。假设我们有 2 个 3×3×3 的过滤器:
- 过滤器 1:检测垂直边缘,得到一个 4×4×1 的特征图。
- 过滤器 2:检测水平边缘,得到另一个 4×4×1 的特征图。
- 堆叠输出:将这两个 4×4 的特征图堆叠起来,形成一个 4×4×2 的输出。
4. 输出维度计算公式
5. 通道(Channel)与深度(Depth)概念的区分
- 在文献中,输入图像的最后一个维度通常称为 通道(Channel)。
- 在卷积过程中,每个过滤器对应一个 输出通道(即下一层的深度)。
为了避免混淆,尤其是在讨论神经网络的“深度”时,输入数据的最后一个维度更常被称为 通道数,而非深度。
3.9 单层卷积网络
卷积神经网络(CNN)可以看作是全连接网络的一种特殊形式,通过局部连接和权重共享实现特征提取,避免了大量冗余的参数。
- 卷积层通过使用多个滤波器在输入图像上滑动,提取不同特征(如边缘、纹理等)。
- 通过添加偏差和激活函数(如 ReLU),可以实现非线性变换,使模型能够学习更复杂的特征。
- 通过选择不同数量和大小的滤波器,可以控制输出特征图的深度和大小。
- 卷积层的参数量通常较少,能够有效减少计算开销和避免过拟合。
- 对于每个 3×3×3 的滤波器,有 3×3×3=27 个权重。
- 加上一个偏差 b,每个滤波器有 28 个参数。
- 若使用 10 个滤波器,总参数量为: 28×10=280。
3.10 一个具体的卷积神经网络(CNN)示例
这节课我们通过一个具体的卷积神经网络(CNN)示例,来深入理解如何为图片分类任务构建卷积层。以下是我们总结的关键步骤和概念:
1. 卷积层的设计与示例
我们从一张39×39×3的图像开始,该图像表示为一个3通道的彩色图像。任务是判断图像中是否有猫,属于分类问题。
第一层:3×3的卷积滤波器
- 使用 valid卷积(无填充),步幅为1。
- 通过10个3×3的卷积滤波器提取特征。
- 输出图像的大小变为 37×37×10(高度和宽度减小,通道数为10)。
第二层:5×5的卷积滤波器
- 使用 valid卷积,步幅为2。
- 采用20个5×5的卷积滤波器。
- 输出图像的大小为 17×17×20(高度和宽度减小约一半,通道数为20)。
第三层:再次使用5×5的卷积滤波器
- 步幅为2,采用40个5×5的卷积滤波器。
- 输出图像的大小为 7×7×40(继续减小,通道数为40)。
到此,输入图像的尺寸从 39×39×3 变成了 7×7×40。每个特征图(channel)表示了图像的一种不同的特征,最终得到的输出图像包含了 1960 个特征。
2. 展开成向量与分类
- 接下来,这些特征将被 展开(flatten)成一个长向量,得到一个具有 1960个单元 的向量。
- 然后,将这个向量送入一个 全连接层,最终通过 softmax回归 函数(如果是多类分类问题)或 logistic回归(如果是二分类问题)来进行最终的分类预测。
3. 网络深度与尺寸变化
随着网络深度的加深,图像的 高度和宽度 会逐渐减小,从 39×39 到 7×7,而 通道数(特征图的数量)则会增加,从 3 到 40。这种趋势在许多经典的卷积神经网络中是普遍存在的。
4. 卷积神经网络的层类型
卷积神经网络的层主要有三种类型:
- 卷积层(Conv):用于特征提取,通过卷积滤波器进行特征映射。
- 池化层(Pooling):用于减少计算量和防止过拟合,通常是最大池化或平均池化。
- 全连接层(FC):用于将提取到的特征进行分类。
5. 超参数的选择
设计卷积神经网络时,选择合适的超参数(如滤波器的大小、步幅、填充方式、滤波器数量等)是非常重要的。不同的任务和数据集可能需要不同的参数设置。后续课程将更详细地讲解如何选择这些超参数,以构建高效的卷积神经网络。
3.11 池化层(Pooling layers)
池化层是卷积神经网络(CNN)中的一个重要组成部分,常用于缩减模型的大小、提高计算速度并增强特征的鲁棒性。池化层通过降低空间维度来减少计算量,保留图像中的重要信息。以下是对池化层的总结:
1. 池化层的功能
池化层主要用于减少特征图的空间尺寸,同时提高计算效率。池化操作通过对局部区域应用一个固定的规则来提取最重要的特征,最常用的池化方法有两种:
- 最大池化(Max Pooling):在每个池化窗口中,选择最大值作为输出。
- 平均池化(Average Pooling):在每个池化窗口中,选择平均值作为输出。
2. 最大池化示例
以 4×4 矩阵为例,采用 2×2 的池化过滤器,步幅为2。池化过程如下:
- 将输入图像划分为多个2×2区域,每个区域提取最大值。
- 第一个2×2区域的最大值是9,第二个是2,以此类推,最终输出为 2×2 的矩阵。
- 这种操作会显著减少图像的尺寸,同时保留图像中的关键特征。
对于 5×5 的输入矩阵,使用 3×3 的池化过滤器,步幅为1,输出是 3×3 的矩阵。池化过程类似于上面的步骤,不同的是池化区域和步幅不同。
3. 池化操作的超参数
池化的超参数包括:
- 过滤器大小(如2×2、3×3等)
- 步幅(如步幅为1或2)
- Padding:通常池化层不使用padding,除非需要特定的处理。大部分情况下,最大池化很少用padding。目前最常用的值是0.
在最大池化中,不需要学习参数,因此反向传播时没有需要更新的参数。池化层只是一个固定的操作,超参数(如过滤器大小、步幅)可能需要通过实验或交叉验证来选择。
4. 平均池化
平均池化与最大池化类似,但不同之处在于它计算的是每个池化窗口的平均值,而不是最大值。平均池化通常在深层神经网络中使用较少,因为最大池化通常能够保留更多的显著特征。平均池化有时被用于网络的最后一层,尤其是在全局平均池化(Global Average Pooling)中,用于将高维特征映射压缩成较小的向量。
5. 池化的作用
- 尺寸缩减:池化层通过减少空间维度来有效缩减计算量,从而提高网络的计算效率。
- 特征鲁棒性:池化操作使得模型对小的平移、旋转等变换具有更强的鲁棒性。即使某个特征的具体位置发生变化,池化层依然能有效保留特征信息。
- 避免过拟合:池化层有助于减少过拟合,因为它减少了网络中需要学习的参数数量。
3.12 卷积神经网络示例(包含池化层,与手写数字体识别网络架构类似)
在本节课中,我们详细讲解了如何构建一个卷积神经网络(CNN)来实现手写数字识别。以下是课程的总结:
1. 输入和网络架构
- 输入:我们使用32×32×3的RGB图片,目标是识别图片中的数字(0-9)。
- 灵感来源:网络架构受LeNet-5启发,但在参数选择上做了一些修改。
2. 网络层结构
-
第一层(CONV1):使用5×5大小的卷积过滤器,步幅为1,输出大小为28×28×6。接着应用ReLU激活函数。
-
池化层(POOL1):应用最大池化,过滤器大小为2×2,步幅为2,输出大小为14×14×6。
-
第二层(CONV2):使用5×5大小的卷积过滤器,步幅为1,过滤器个数为16,输出大小为10×10×16。
-
池化层(POOL2):再次应用最大池化,输出大小为5×5×16。
3. 全连接层
- 将池化层输出的5×5×16矩阵展平为一个一维向量,长度为400,作为全连接层的输入。
- 全连接层FC3:该层有120个神经元,权重矩阵维度为120×400。
- 全连接层FC4:该层有84个神经元,作为第二个全连接层。
- Softmax层:输出为10个神经元,用于分类手写数字。
4. 超参数
- 卷积层的主要超参数包括:过滤器大小、步幅、过滤器数量。
- 池化层的超参数包括:过滤器大小、步幅。
- 全连接层的参数包括:神经元数量和权重矩阵。
5. 网络特性
- 随着网络深度的增加,激活值的空间尺寸逐渐减小,而通道数(深度)通常会增加。
- 池化层没有需要学习的参数,因此它们不会增加网络的计算负担。
- 卷积层的参数较少,主要集中在卷积核(过滤器)中。全连接层的参数最多,因为它们与前一层的每个神经元都有连接。
6. 总结
- 在设计卷积神经网络时,常见的结构模式包括卷积层+池化层的交替堆叠,最终通过全连接层输出分类结果。
- 随着深度学习研究的不断发展,许多成功的卷积神经网络架构(如LeNet-5、AlexNet等)都采用了这种模式。
- 通过整合这些基本模块,我们可以构建高效的神经网络。学习和借鉴已有的网络架构和经验是非常重要的。
3.13 为什么使用卷积?(Why convolutions?)
卷积操作为什么如此有效呢?
1. 卷积的优势:
-
参数共享: 卷积层中的过滤器(如5×5的过滤器)在输入图像的不同区域共享相同的参数。这意味着,特征检测器(如边缘检测器)可以在整个图像中应用,而无需为每个区域都定义不同的特征检测器。例如,垂直边缘检测器可以用于图像的任何位置,而不需要针对每个区域使用不同的参数,这大大减少了需要训练的参数数量。
-
稀疏连接: 卷积层的输出仅依赖于输入中一个小区域(如3×3区域)。因此,每个输出单元只与输入的一部分特征连接,而不是与整个输入图像的每个像素都连接。这种稀疏连接减少了计算量,并且更高效。
2. 减少参数量:
- 在没有卷积的全连接层中,每一层的神经元会与上一层的所有神经元连接,导致需要训练的参数数量非常庞大。举例来说,如果图像是32×32×3的RGB图片,输入层到下一层的参数量可能达到千万级别。相比之下,卷积层通过共享过滤器和稀疏连接,使得参数量显著减少。例如,6个5×5的过滤器总共只有156个参数,而不是数百万个。
3. 平移不变性:
卷积神经网络能够自动学习到图像中的平移不变性。即使图像中的对象发生平移(例如,猫的位置从左移到右),卷积层也能够识别该对象,因为特征提取器在整个图像中共享,能够识别图像中各个位置的相似特征。
4. 卷积神经网络的训练:
- 通过使用标注过的训练集(如猫咪检测器的训练集),我们可以训练卷积神经网络。训练时,输入图像通过卷积层和池化层提取特征,并最终通过全连接层进行分类,输出结果通过softmax层得到。
- 训练时使用的代价函数表示网络在整个训练集上的预测误差,并通过梯度下降法(如Momentum、RMSProp等)来优化网络中的所有参数,从而减少代价函数的值。
3.14 计算机视觉领域几种经典的网络架构。
- LeNet-5:早期的经典网络之一,帮助奠定了现代卷积神经网络的基础。
- AlexNet:一个经常被引用的网络,曾在计算机视觉领域产生重大影响。
- VGG网络:具有深度结构的经典网络。
- ResNet(残差网络):通过引入残差学习解决了深层网络训练的问题,并且设计了152层深的网络。
- Inception网络:介绍了如何有效利用不同大小卷积核的组合,提高了网络的性能。
3.15 经典网络架构——LeNet-5
LeNet-5是一个经典的卷积神经网络结构,特别适用于手写数字体识别任务
1)网络架构:
输入层:输入是一张32×32×1的灰度图像。
卷积层 1:使用6个5×5的卷积核,步幅为1,padding为0,输出大小为28×28×6。图像尺寸从32×32缩小到28×28。
池化层 1:使用2×2的平均池化(步幅为2),输出大小为14×14×6,图像尺寸再缩小一半。
卷积层 2:使用16个5×5的卷积核,输出大小为10×10×16。由于没有padding,图像尺寸从14×14缩小到10×10。
池化层 2:使用2×2的平均池化(步幅为2),输出大小为5×5×16,图像尺寸再缩小一半。
全连接层:输入为5×5×16=400个节点,经过处理后,第一层全连接层有120个神经元。之后有第二层全连接层,其中包含84个神经元。
输出层:最后使用10个神经元来输出手写数字0-9的类别。这个部分通常使用Softmax激活函数来进行多分类。
2)特点(局限性):
- LeNet-5是针对灰度图片训练的,所以图片的大小只有32×32×1;
- 在这篇论文写成的那个年代(1998年),人们更喜欢使用平均池化,而现在我们可能用最大池化更多一些;
- 此外,当时人们并不使用padding,总是使用valid卷积,导致图像尺寸越来越小;
- LeNet-5使用Sigmoid和Tanh激活函数,而不是现代常用的ReLU;
- 该模型只有约6万个参数,而现在,我们经常看到含有一千万到一亿个参数的神经网络;
- LeNet-5网络在输出层使用的是高斯分布(Gaussian distribution)进行分类,而不是现在常用的Softmax分类器。
- 为了减少计算量和参数,经典的LeNet-5网络使用了非常复杂的计算方式,大多数过滤器都未采用和输入模块一样的通道数量。
3)启发意义:
卷积层与池化层步步交叠:LeNet-5首次明确提出了将卷积层(用于特征提取)和池化层(用于降维和减少计算量)交替使用的结构。这种结构成为了现代卷积神经网络的基础,至今仍然是大多数CNN架构中的核心组成部分。
随着网络加深,图像尺寸不断变小,通道数逐渐增大:随着网络越来越深,图像的高度和宽度在缩小,从最初的32×32缩小到28×28,再到14×14、10×10,最后只有5×5。与此同时,随着网络层次的加深,通道数量一直在增加,从1增加到6个,再到16个。该思想至今仍在使用。
3.16 经典网络架构——AlexNet
AlexNet,是以论文的第一作者Alex Krizhevsky的名字命名的,另外两位合著者是ilya Sutskever和Geoffery Hinton。
1. 输入和卷积层设计:
- 输入:AlexNet的输入是224×224×3的RGB图像(虽然文章中使用的是224×224,但227×227更为常见),这比LeNet输入图像尺寸更大。
- 第一层卷积:使用96个11×11的卷积核,步幅为4,因此输入图像的尺寸从227×227减少到55×55×96。这里较大的卷积核尺寸和较大的步幅在计算效率和特征提取上起到了作用。
- 最大池化:接着进行3×3的最大池化,步幅为2,将特征图尺寸从55×55缩小为27×27×96。
- 第二层卷积:使用5×5的卷积核,输出为27×27×256。
- 再次最大池化:池化将特征图的尺寸从27×27×256缩小到13×13×256。
- 同样的结构:之后是多个卷积层和池化层,通过适当的padding确保卷积后尺寸稳定,并逐步增大特征图的通道数(384、384、256等)。
- 最终输出:最后一个池化层输出6×6×256的特征图,展开成9216个单位,进入全连接层。

2. 激活函数与网络参数:
- 激活函数:与LeNet不同,AlexNet引入了ReLU(Rectified Linear Unit)激活函数,而不是传统的sigmoid或tanh。ReLU函数能够提高训练速度,避免梯度消失问题,使得网络能够更好地训练深层结构。
- 参数数量:相比LeNet的6万个参数,AlexNet有大约6000万个参数,这使得AlexNet能够处理更复杂的任务和数据集。
3. 使用两个GPU训练:
- 由于GPU计算速度当时还较慢,AlexNet的训练采取了两个GPU并行处理的方式。网络的层被分布在两个不同的GPU上,通过特殊的方法进行通信和数据交换。这种设计有助于加速训练过程并处理更大的数据集。
4. 局部响应归一化层(LRN):
- LRN(Local Response Normalization)用于对神经元的激活值进行归一化,目的是增强局部区域的竞争性,从而提高神经网络对强激活的响应。然而,后来的研究表明,LRN对提高模型性能并没有显著效果,因此在后续的深度学习研究中逐渐被淘汰。
- 假设你在13×13的图像上某个位置有一个神经元,其激活值为A。这时,LRN会看这个位置周围的一些神经元(比如,可能是它周围3×3的区域),然后对这些周围神经元的激活值进行归一化处理,像是计算它们的平均激活值。通过这种方式,LRN会调整A的值,使得它与周围其他神经元的激活值保持一定的比例关系。如果A相对较大,LRN就会减少它的影响,反之,则可能增加它的响应。
让我们举个例子理解一下这点:
- 虫子 = 神经元:每个神经元都有一个激活值,代表它的“状态”或“强度”。
- 争斗 = 激活值的竞争:神经元之间会根据它们在局部区域内的激活值来“竞争”,有些神经元会因为激活值太高而占据主导地位。
- 食物 = 激活值的调整:LRN就是根据每个神经元的激活值和它周围神经元的激活值进行比较,然后决定是否对这个神经元进行调整。如果某个神经元的激活值过高,就像是一个虫子太强大,LRN会“削弱”它的激活值,就像不给它食物一样;而如果神经元的激活值相对较低,就像虫子快奄奄一息了,LRN会“奖励”它,增强它的激活值,让它有更多机会生存下去。
5. 深度学习的历史背景与影响:
- 在AlexNet之前,深度学习已经在语音识别等领域有所应用,但由于计算机视觉领域的数据和计算资源限制,深度学习的潜力没有得到充分的发挥。AlexNet的成功让深度学习技术在计算机视觉领域获得了广泛关注,并催生了后续大量深度学习网络的出现,推动了计算机视觉技术的发展。
6. 网络结构总结:
- 卷积层和池化层: 相较于LeNet,AlexNet使用了更多的卷积层和池化层,且网络深度和复杂度显著增加。
- 全连接层: 通过将卷积层的输出展平成一维,进入全连接层进行最终的分类输出。最后通过softmax函数输出属于1000个类别之一的分类结果。
- ReLU激活函数和GPU训练: ReLU提高了训练速度,GPU并行计算加速了训练过程,尤其是在大规模数据集上。
- Dropout的首次应用:在AlexNet的实现中,Dropout被应用于全连接层中,尤其是在两个最重要的全连接层(即第6层和第7层),它们的输出尺寸分别是4096和4096。在这些全连接层中,每次训练时,Dropout随机“丢弃”部分神经元的连接,通常丢弃的比例为 50%。这意味着,在训练过程中,网络的每一轮都会随机选择一部分神经元不参与计算,从而避免了模型对某些神经元的过度依赖。
3.17 经典网络架构——VGG-16
VGG-16 是一种相对简单且高效的卷积神经网络,它的核心特点是使用相同的卷积操作:每个卷积层使用的是 3×3 大小、步幅为1的过滤器,并且每次卷积都采用了 same padding。同时,池化操作使用 2×2 的过滤器,步幅为2来减小特征图的尺寸。VGG-16 网络之所以被称为“16”,是因为它包含了16层主要的卷积和全连接层。尽管其结构相对简单,但其规则化的设计让它成为计算机视觉领域非常重要的网络架构之一。
VGG-16 结构总结:

-
输入:输入图像尺寸:224×224×3(RGB图像)
-
卷积层和池化层结构:
- 第一个阶段:2层卷积层,每个卷积层使用64个 3×3 过滤器,步幅为1,padding为same,之后进行池化层(2×2,步幅2),输出尺寸为112×112×64。
- 第二个阶段:2层卷积层,每个卷积层使用128个 3×3 过滤器,步幅为1,padding为same,之后进行池化层,输出尺寸为56×56×128。
- 第三个阶段:3层卷积层,每个卷积层使用256个 3×3 过滤器,步幅为1,padding为same,之后进行池化层,输出尺寸为28×28×256。
- 第四个阶段:3层卷积层,每个卷积层使用512个 3×3 过滤器,步幅为1,padding为same,之后进行池化层,输出尺寸为7×7×512。
- 注:这里的2层卷积层指的是顺序关系,而非堆叠关系。
-
全连接层:
- 将最后的7×7×512特征图展平,得到25088个神经元。
- 然后使用两个全连接层,每个包含4096个神经元。
-
输出层:最后通过一个包含1000个输出神经元的softmax层输出分类结果,适用于ImageNet等大型数据集的图像分类。


VGG-16的优点:
- 结构简洁且规整: 所有卷积层的过滤器大小都是 3×3,这使得网络设计更简单,更容易理解和实现。
- 卷积层后池化的规律性: 每次池化操作都将图像尺寸缩小一半,而通道数则是每组卷积层后翻倍,提供了一个相对一致的网络结构。
- 提高了网络的深度: VGG-16是一个很深的网络(包含16个卷积层),它的深度使得它可以捕捉到更加复杂的特征,并且在图像分类任务上表现出色。
VGG-16的缺点:
- 参数量巨大: VGG-16总共有约1.38亿个参数,即使以今天的标准来看,它仍然是一个非常庞大的网络。这要求大量的计算资源,训练过程较为缓慢。
- 需要较长的训练时间: 由于其庞大的参数量,VGG-16训练需要大量的计算资源和时间,尤其是在没有GPU加速的情况下。
VGG-19:
- VGG-19比VGG-16更大,包含19个卷积层和全连接层,但在很多应用中,VGG-16和VGG-19的表现差距并不大,因此VGG-16通常更受青睐。
影响与启发:
- VGG网络的设计揭示了一个非常重要的现象:随着网络深度的增加,图像的尺寸在池化操作后不断缩小,而特征图的通道数逐渐增多,这种规律性提供了一种简洁而高效的网络设计思路。
- VGG-16的结构简洁和层次清晰,使得它成为许多后续深度学习研究的基准模型,也为许多实际应用(如图像分类、物体检测等)提供了有效的解决方案。
3.18 经典网络架构——ResNets
提出的背景:
非常非常深的神经网络是很难训练的,因为存在梯度消失和梯度爆炸问题。如果我们使用标准优化算法训练一个普通网络,比如说梯度下降法,或者其它热门的优化算法。如果没有残差,没有这些捷径或者跳跃连接,凭经验你会发现随着网络深度的加深,训练错误会先减少,然后增多。而理论上,随着网络深度的加深,应该训练得越来越好才对。也就是说,理论上网络深度越深越好。但实际上,如果没有残差网络,对于一个普通网络来说,深度越深意味着用优化算法越难训练。实际上,随着网络深度的加深,训练错误会越来越多。
但有了ResNets就不一样了,即使网络再深,训练的表现却不错,比如说训练误差减少,就算是训练深达100层的网络也不例外。有人甚至在1000多层的神经网络中做过实验,尽管目前我还没有看到太多实际应用。但是对的激活,或者这些中间的激活能够到达网络的更深层。这种方式确实有助于解决梯度消失和梯度爆炸问题,让我们在训练更深网络的同时,又能保证良好的性能。也许从另外一个角度来看,随着网络越来深,网络连接会变得臃肿,但是ResNet确实在训练深度网络方面非常有效。
ResNet概述:
ResNet(Residual Network) 是由 何凯明、张翔宇、任少卿 和 孙剑 提出的深度神经网络架构,解决了深度神经网络训练中的梯度消失和梯度爆炸问题。ResNet的关键思想是通过使用跳跃连接(Skip Connection)来构建残差块(Residual Block),使得信息可以直接通过捷径传递到更深的网络层,从而帮助训练更深层次的神经网络,甚至可以达到100层或更深。
残差块:
解释如下:
注:捷径也可以称其为跳跃连接
接下来让我们看一下普通网络和残差网络的区别:

把它变成ResNet的方法是加上所有跳跃连接,正如前一张幻灯片中看到的,每两层增加一个捷径,构成一个残差块。如图所示,5个残差块连接在一起构成一个残差网络。

那么残差网络为何这么有用呢?
我们的目标不仅仅是保持网络的效率,还要提升它的效率。想象一下,如果这些隐藏层单元学到一些有用信息,那么它可能比学习恒等函数表现得更好。而这些不含有残差块或跳跃连接的深度普通网络情况就不一样了,当网络不断加深时,就算是选用学习恒等函数的参数都很困难,所以很多层最后的表现不但没有更好,反而更糟。
我认为残差网络起作用的主要原因就是这些残差块学习恒等函数非常容易,你能确定网络性能不会受到影响,很多时候甚至可以提高效率,或者说至少不会降低网络的效率,因此创建类似残差网络可以提升网络性能。
通俗来讲,总结一下:ResNet就是单纯的让深层网络初始就很容易做到identity mapping;原始网络是因为深层梯度消失,导致学习能力大幅降低,所以identity mapping都很难做到,反而降低模型表现。 所以skip connection的本质就是一个兜底,在此基础上深层能学多少就是赚到。
另一个细节:
Same卷积和维度保持
ResNet使用了许多“same”卷积(即保持输入和输出的维度不变的卷积)来构建网络中的残差块。具体来说,same卷积意味着在卷积过程中,输入和输出的特征图的尺寸保持一致(通过适当的填充来确保这一点)。这种做法非常关键,因为它允许跳跃连接(skip connection)将输入直接添加到输出,从而不引入维度变化。
举个例子,假设一个输入特征图的尺寸是 128×128×64,经过一个3x3的same卷积后,输出特征图的尺寸仍然是 128×128×64,维度不变。因此,输入可以与输出直接相加,形成残差块。这种“shortcut”连接确保了即使经过多层卷积,残差网络也不会因为加深网络而丢失信息。
当输入和输出维度不同时如何处理
在ResNet中,如果输入和输出的维度不同(例如输入的维度是128,而输出的维度是256),那么需要对跳跃连接进行调整。因为直接将维度不同的两个张量相加是不可行的,所以需要通过一个额外的变换来匹配维度。
一种常见的做法是使用1x1卷积来对输入进行变换,使其维度与输出一致。例如,假设输入的维度是128,输出的维度是256,我们可以通过一个1x1卷积层(大小为1x1,输出通道数为256)将输入特征图从128维转换为256维,从而使输入与输出的维度一致,然后再进行相加。
此外,ResNet在这种情况下会采用 零填充 (zero padding),通过增加适当的“补充”项,使得维度变换后的输入和输出可以相加。这样,跳跃连接可以直接传递信息,而不需要修改其维度。
3.19 “Network in Network” 和 1x1卷积简介。
1. 1×1卷积的基本作用
1×1卷积通常用于处理输入通道数(特征图的深度)的变化,而不是处理空间维度(高度和宽度)。它的关键作用是通过线性组合输入通道的特征,来减少或增加通道数,同时还引入了非线性激活函数(如ReLU),增强了网络的表现能力。
- 计算方法: 如果输入特征图的维度是 H×W×Cin(其中 H 和 W 分别是高度和宽度,Cin 是通道数),通过1×1卷积后,可以对每个位置的 Cin 个通道进行加权求和,并通过非线性激活函数得到输出。这种方法就相当于在每个像素点上做了一个全连接层,通过1×1卷积将输入的多通道信息合并成输出的多通道信息。
2. 1×1卷积的作用:
-
增加非线性: 通过引入非线性激活函数(如ReLU),1×1卷积使得神经网络能够学习更复杂的特征和函数,从而提升模型的表达能力。
-
通道数调整: 1×1卷积可以有效地调整输入的通道数。例如,在处理高维数据时,1×1卷积能够将较高维度的输入特征图(如 28×28×192 )压缩成较低维度(如 28×28×32 ),从而减少计算量和内存消耗。它可以视作一种“压缩”操作,但与池化不同的是,它不会减少空间维度(即宽度和高度),而是操作特征维度(即通道数)。
-
减少计算量: 如果想减少模型的计算量和参数量,可以通过1×1卷积来进行通道数的降维,从而避免在后续的卷积层中处理过多的特征通道,减少计算负担。
-
“Network in Network”思想: 1×1卷积在某些网络架构中被作为“微型网络”使用,即对每个通道进行局部的“网络处理”。这也是 Network in Network 这一概念的核心,意味着每个小区域(或者每个通道)都可以通过一个小网络(1×1卷积)进行信息提取。
3. 1×1卷积的应用
1) 压缩通道数
假设输入为 28×28×192,想要将其压缩到 28×28×32,可以使用32个1×1的过滤器,每个过滤器的大小为 1×1×192,输出将是 28×28×32 的特征图。这一过程并不会改变空间尺寸(高度和宽度),只会减少通道数。
2) 保持或增加通道数
如果需要增加输出的通道数,也可以使用1×1卷积来增加特征图的深度。例如,如果要将输入从 28×28×192 转换为 28×28×256,可以使用256个1×1过滤器。这种做法不仅保留了空间尺寸,还能提高模型的复杂性。
3) 用于Inception网络
1×1卷积在Inception网络中得到了非常重要的应用,尤其是在GoogleNet等网络中。Inception模块通过组合不同大小的卷积核(包括1×1卷积),可以在保持较低计算量的同时,提取多尺度的特征。在这个模块中,1×1卷积不仅用于减少通道数,还帮助网络从不同角度提取更加丰富的特征。
3.20 谷歌Inception网络架构。
Inception网络是一种非常创新的网络架构,它的核心思想是通过组合不同大小的卷积核(例如1×1、3×3、5×5卷积)和池化层(例如最大池化),来替代手动设计和选择卷积层的结构。通过这种方式,Inception模块能够让网络自行决定哪些卷积层、池化层以及哪些过滤器大小对任务最有用,从而提高模型的表现力,同时避免人为选择不同卷积核和池化层带来的困扰。
注意,在Inception网络中,自动决定的意思并不是由模型自己“自觉”地选择,而是通过设计网络结构来并行计算多种不同大小的卷积核和池化操作,最后将它们的结果合并起来,让网络学习哪些组合在特定任务中最有效。也就是说,网络通过训练数据学习如何权衡这些不同操作的效果。
也即我们需要列出几个菜,然后让顾客(训练数据)选择一个最适合他口味的菜。
你可能会好奇上图中MAX-POOL后维度不应该还是28×28×192么,为啥是 28×28×32?
这其实是为了防止拼接后池化层占据绝大多数通道所导致的不公平问题,那具体是如何实现的呢?关于这个问题,我们下文再说。
那么如何选择卷积核和数量?(总得先列出几道菜吧)
-
选择卷积核尺寸:这由网络的设计者决定。一般来说,较小的卷积核(如1×1)用于降低计算量,而较大的卷积核(如3×3、5×5)用于提取更多细节特征。通过将它们组合起来,网络可以学习从不同尺度提取信息。
-
选择卷积核数量:通常,每种卷积核都会选择不同数量的过滤器(卷积核数量),这些数量一般是通过试验确定的。比如,1×1卷积可能用64个过滤器,3×3卷积用128个,5×5卷积用32个。
在Inception网络中,这些不同卷积操作的输出会拼接(沿通道维度拼接),从而得到丰富的特征表示。这种设计让网络能够在同一层级上并行处理多种不同类型的特征。
那么Inception如何自动决定呢?(顾客如何选择一个一个最适合他口味的菜)
在训练过程中,网络会通过反向传播学习如何调整每个操作的权重。即便是不同尺寸的卷积核,网络会根据任务的需求来调整各个卷积核的参数,以便从不同类型的特征中提取有用的信息。
-
卷积核的参数(权重)会随着训练调整:比如,1×1卷积可能用于减少通道数,3×3卷积会捕捉较小范围的局部特征,5×5卷积会捕捉较大范围的局部特征。网络在训练时会逐渐调整这些卷积核的权重,从而决定在特定任务中每个卷积核的贡献。
-
池化操作的学习:池化操作(例如最大池化或平均池化)通常用于减少空间维度,保留重要特征。通过训练,网络会学会如何通过池化来减少冗余信息,从而保留更重要的特征。
也即通过数据集的训练让模型找到最适合该数据集的卷积核或者池化操作进行的力度(通过调整卷积核的权重)。
3.21 如何通过使用1×1卷积来构建瓶颈层,从而大大降低计算成本
不难发现,上文所描述的Inception层有一个问题,就是计算成本
如上图所示,这是一个28×28×192的输入块,执行一个5×5卷积,它有32个过滤器,输出为28×28×32。我们来计算这个28×28×32输出的计算成本,它有32个过滤器,因为输出有32个通道,每个过滤器大小为5×5×192,输出大小为28×28×32,所以你要计算28×28×32个数字。对于输出中的每个数字来说,你都需要执行5×5×192次乘法运算,所以乘法运算的总次数为每个输出值所需要执行的乘法运算次数(5×5×192)乘以输出值个数(28×28×32),把这些数相乘结果等于1.2亿(120422400)。即使在现在,用计算机执行1.2亿次乘法运算,成本也是相当高的。
那么如何降低成本呢?使用1×1卷积来构建瓶颈层
对于输入层,使用1×1卷积把输入值从192个通道减少到16个通道。然后对这个较小层运行5×5卷积,得到最终输出。请注意,输入和输出的维度依然相同,输入是28×28×192,输出是28×28×32,和上一页的相同。但我们要做的就是把左边这个大的输入层压缩成这个较小的的中间层,它只有16个通道,而不是192个。
我们看看这个计算成本,应用1×1卷积,过滤器个数为16,每个过滤器大小为1×1×192,这两个维度相匹配(输入通道数与过滤器通道数),28×28×16这个层的计算成本是,输出28×28×192中每个元素都做192次乘法,用1×1×192来表示,相乘结果约等于240万。
那第二个卷积层呢?240万只是第一个卷积层的计算成本,第二个卷积层的计算成本又是多少呢?这是它的输出,28×28×32,对每个输出值应用一个5×5×16维度的过滤器,计算结果为1000万。
所以所需要乘法运算的总次数是这两层的计算成本之和,也就是1204万,与上一张幻灯片中的值做比较,计算成本从1.2亿下降到了原来的十分之一,即1204万。所需要的加法运算与乘法运算的次数近似相等,所以我只统计了乘法运算的次数。
为什么叫做瓶颈层呢?观察上图:我们发现核心思想是先缩小再放大(对通道数而言)。

3.22 一个完整的Inception 网络示例
我们上文提到,为了解决计算量巨大的问题,引入了1×1卷积构建瓶颈层,因此如下:
注意:
池化操作前不需要加入1×1卷积,因为池化不会改变通道数;
池化操作后需要加入1×1卷积,也是因为池化不会改变通道数,需要通过1×1卷积缩减通道数
包含许多重复模块:
如上图所示,这是一张取自Szegety et al的论文中关于Inception网络的图片,你会发现图中有许多重复的模块,可能整张图看上去很复杂,但如果你只截取其中一个环节(编号1),就会发现这是在前一页ppt中所见的Inception模块。
我们深入看看里边的一些细节,这是另一个Inception模块(编号2),这也是一个Inception模块(编号3)。这里有一些额外的最大池化层(编号6)来修改高和宽的维度。这是另外一个Inception模块(编号4),这是另外一个最大池化层(编号7),它改变了高和宽。而这里又是另一个Inception模块(编号5)。
所以Inception网络只是很多这些你学过的模块在不同的位置重复组成的网络.
事实上,如果你读过论文的原文,你就会发现,这里其实还有一些分支,我现在把它们加上去。所以这些分支有什么用呢?在网络的最后几层,通常称为全连接层,在它之后是一个softmax层(编号1)来做出预测,这些分支(编号2)所做的就是通过隐藏层(编号3)来做出预测,所以这其实是一个softmax输出(编号2),这(编号1)也是。这是另一条分支(编号4),它也包含了一个隐藏层,通过一些全连接层,然后有一个softmax来预测,输出结果的标签。
你应该把它看做Inception网络的一个细节,它确保了即便是隐藏单元和中间层(编号5)也参与了特征计算,它们也能预测图片的分类。它在Inception网络中,起到一种调整的效果,并且能防止网络发生过拟合。具体如何起效果呢?
Inception网络框架中会有额外的两个softmax预测层,这两个预测层分别是从网络框架中间部分引出的分支,用于反向传播更新梯度,这样就避免了因梯度消失导致浅层的网络参数无法更新。注意这两个分支只在训练的时候防止梯度消失会用到,真正做预测的时候需要删除。

3.23 使用开源的实现方案——Git使用指南
可以参见我之前写的一篇文章:
一文带你学会Git的基本使用⭐⭐⭐(超简洁,避免冗余)_git菜鸟教程-CSDN博客
3.24 在计算机视觉中应用迁移学习。
1. 迁移学习的基本概念
- 迁移学习指的是将一个任务上学到的知识迁移到另一个任务上,尤其在目标任务的数据较少时非常有用。你可以使用别人已经训练好的网络权重作为初始化,并在此基础上进行微调(fine-tuning),来适应你自己的任务。
- 比如,使用已经在大数据集(如ImageNet)上训练好的卷积神经网络(CNN)作为预训练模型,只需对最后的分类层(如Softmax层)进行调整,适应特定的分类任务。
2. 迁移学习的优势
- 节省训练时间:训练深度神经网络需要大量的计算资源和时间。迁移学习使你能够利用别人训练好的网络和权重,避免从头开始训练整个网络,从而节省了几周甚至几个月的训练时间。
- 适应小数据集:对于很多任务,尤其是个性化或特定类别的任务(如猫咪检测器),你可能只有很小的训练数据集。迁移学习可以帮助你在小数据集上快速获得良好的性能,因为预训练模型已经学到了非常有用的特征。
3. 迁移学习的步骤
- 使用预训练的网络:你可以下载已经在大数据集上训练好的模型(如ImageNet上的ResNet、VGG等),并将其作为初始化网络。
- 修改输出层:如果你的任务是一个不同的分类问题(比如3类而非1000类),你需要替换掉网络的输出层(如Softmax层),用新的输出单元来适应你需要的类别(例如,Tigger、Misty、Neither三类)。
- 冻结层与微调:
- 冻结层:你可以冻结预训练网络中大部分层的权重,只训练新的输出层,特别是在数据集较小的情况下。冻结的层会保持固定,网络的前几层会保留从大数据集学习到的特征。
- 微调:如果你有更多的数据,可以选择解冻一些前面的层,进行微调训练。这样做能够使网络的特征适应你自己任务的数据分布。
- 加速训练的技巧:对于较小的数据集,你可以计算并存储预训练模型的中间层特征,然后基于这些特征训练你的Softmax分类器,这样就避免了每次训练时都需要重新计算这些特征,节省了计算资源。
4. 如何处理不同大小的数据集
- 小数据集:对于非常小的数据集(比如只有Tigger和Misty的图片),你可以冻结大部分网络的权重,只训练新的Softmax层。这种方法能够在极其有限的数据上依然获得不错的结果。

- 中等大小的数据集:如果你有一定数量的数据(例如更多的猫咪照片),你可以考虑冻结较少的层,解冻一些靠近输出的层进行训练(或者直接删除自己定义一些隐藏层)。这样,网络能够更加适应你的任务特定的数据。

- 大数据集:如果你有大量的数据,你可以将预训练网络的权重作为初始化,并对整个网络进行微调,甚至完全训练整个网络。
5. 一个小技巧
由于前面的层都冻结了,相当于一个固定的函数,不需要改变。因为你不需要改变它,也不训练它,取输入图像X,然后把它映射到这层(softmax的前一层)的激活函数。所以这个能加速训练的技巧就是,如果我们先计算这一层(紫色箭头标记),计算特征或者激活值,然后把它们存到硬盘里。你所做的就是用这个固定的函数,在这个神经网络的前半部分(softmax层之前的所有层视为一个固定映射),取任意输入图像Z,然后计算它的某个特征向量,这样你训练的就是一个很浅的softmax模型,用这个特征向量来做预测。对你的计算有用的一步就是对你的训练集中所有样本的这一层的激活值进行预计算,然后存储到硬盘里,然后在此之上训练softmax分类器。所以,存储到硬盘或者说预计算方法的优点就是,你不需要每次遍历训练集再重新计算这个激活值了。
3.25 计算机视觉中常用的数据增强操作
大部分的计算机视觉任务使用很多的数据,所以数据扩充是经常使用的一种技巧来提高计算机视觉系统的表现。
1. 数据扩充的目标
- 增加数据多样性:数据扩充通过对原始数据进行多样化变换,生成更多的训练样本,从而提高模型的鲁棒性。
- 避免过拟合:通过生成不同版本的训练数据,避免模型对少量数据的过拟合,使其在未见过的图像上具有更好的泛化能力。
2. 常见的数据扩充方法
1) 镜像对称
- 最常见且最简单的扩充方法是水平翻转(镜像对称),将图像沿垂直轴进行翻转。例如,如果训练集中有一张猫的图片,翻转后得到的图像依然是猫。该方法对大多数计算机视觉任务有效,尤其是物体识别任务。
2) 随机裁剪
- 随机裁剪指的是从原图的不同区域随机选择一个子区域进行裁剪。这样生成的图像内容会有所不同,但如果裁剪区域仍包含目标物体,模型依然能够学习到有效特征。
- 问题:如果裁剪的区域不包含物体,可能会影响模型学习,但在实际应用中,裁剪仍然是常用的数据扩充方法。
3) 旋转与变形
- 对图像进行旋转、剪切(shearing)、缩放、翻转等变形操作。这些变换有助于提高模型对各种角度和形变的鲁棒性。
- 尽管这些操作能够生成多样的数据,但在实际应用中,由于变形过于复杂,通常不会过多使用。
4) 彩色转换与颜色增强
- 颜色变化:通过调整图像的RGB通道,比如改变红色、绿色和蓝色的强度,来模拟不同的光照条件或环境变化。这样的变化使得模型在不同光照下的表现更加鲁棒。
- 例如,给红色和蓝色通道加值,使图片偏紫;或者减少绿色通道的值,使图片偏黄。
- PCA颜色增强:PCA(主成分分析)可以通过调整颜色通道之间的关系,进行更精细的颜色增强,这种方法可以在训练中加入更复杂的颜色变换。
5) 复杂变形与失真
- 对图像进行局部弯曲或更复杂的几何变形,增加训练数据的多样性。
- 这些方法虽然有效,但通常会增加计算量,因此在实践中较少使用。
3. 如何实现数据扩充
1) 数据流与并行化
- 在有大量训练数据时,可以使用CPU线程从硬盘中加载图片数据流,并对其进行随机裁剪、颜色变化等变换。这样能够动态地为训练提供不断变化的图像样本。
- 通过多线程或多进程并行化这些操作,可以加速数据扩充过程,避免数据读取成为瓶颈。
2) 存储与读取
- 数据扩充时,图片的变形操作可能会消耗大量计算资源,因此可以通过预计算并存储这些变换后的图像,减少训练过程中的计算压力。
- 如果数据量特别大,常用的方法是将数据变换结果存储在硬盘中,并通过多线程读取和加载,保证训练的连续性。
4. 如何调整数据扩充时的超参数
与训练深度神经网络的其他部分类似,在数据扩充过程中也有一些超参数,比如说颜色变化了多少,以及随机裁剪的时候使用的参数。与计算机视觉其他部分类似,一个好的开始可能是使用别人的开源实现,了解他们如何实现数据扩充。
3.26 计算机视觉现状总结
1. 深度学习在计算机视觉中的应用
深度学习已经在计算机视觉、自然语言处理、语音识别、在线广告、物流等多个领域取得了成功。在计算机视觉领域,深度学习的应用具有一些独特之处,尤其是在数据集的规模、任务复杂性和模型构建方面。尽管现在有很多公共的大规模数据集(如图像分类),在计算机视觉任务中,尤其是物体检测等任务,数据仍然不足。因此,数据集的大小是影响计算机视觉性能的一个关键因素。
2. 数据规模对学习方法的影响
计算机视觉问题通常可以分为两个极端:少量数据和大量数据。对于拥有大量数据的任务(如图像分类),使用简单的深度学习模型即可获得较好的表现。相反,在数据较少的情况下,依赖于手工工程、特征设计和更复杂的网络架构是提高表现的有效方式。计算机视觉特别依赖手工工程,尤其是在数据较少时,设计合理的网络架构和特征提取方法能够显著改善模型表现。
一般而言,目标检测比图像分类所能获得的数据集更少(因为人工标注框的价格比打个分类标签的活儿更贵)
3. 手工工程与深度学习的平衡
尽管深度学习在数据丰富的情况下能够取得良好表现,但计算机视觉的复杂性仍然要求在数据较少时使用更多的手工工程。这包括特征工程、网络架构设计和其他组件的精心调优。深度学习的优势在于,当数据足够多时,模型可以自动学习特征,无需人工设计,但在数据有限时,手工工程依然是非常有效的提升模型表现的手段。
4. 迁移学习
当数据不足时,迁移学习成为一种有效的技术。迁移学习通过利用在其他领域获得的知识,帮助模型在数据较少的情况下提高表现。通过使用在大数据集上训练的预训练模型,结合迁移学习,可以大大提高计算机视觉模型在小数据集上的表现。这使得迁移学习成为计算机视觉领域解决数据不足问题的重要工具。
5. 基准测试与竞赛
计算机视觉的研究和开发中,基准测试(Benchmark)和竞赛扮演了重要角色。在基准测试中,研究者通过标准数据集和任务测试算法表现,许多开源项目和研究论文都侧重于优化这些基准测试中的表现,尤其是在竞赛中获胜。然而,虽然这些技术在基准测试中非常有效,但它们往往不适用于实际生产系统中(原因是你会采用一些时间、空间换模型效果的trick方式,但可能并不应用于实际)。因此,在设计实际应用时,研究者需要将这些基准优化技术与生产环境的需求进行平衡。
6. 一些基准测试技巧
- 集成(Ensemble):集成方法通过训练多个神经网络模型并平均它们的输出,来提高基准测试中的表现。这种方法通常能在竞赛中获得1-2%的提升,但由于需要同时运行多个模型,它在实际生产环境中成本较高,因此不适用于生产部署。
- Multi-crop:这种方法通过对测试图像进行多次裁剪(如中心裁剪和四个角裁剪),然后将不同裁剪的图像输入分类器并取其输出的平均值。这种技术能够提高基准测试表现,但在生产环境中,由于计算开销较大,通常不采用。

7. 网络架构的选择
在计算机视觉中,很多成功的神经网络架构(如ResNet)已经被开发并优化。这些网络架构经过大量的调试和训练,已经在许多计算机视觉任务中证明了其有效性。因此,建议使用已有的开源网络架构作为基础进行微调,而不是从头开始设计。通过迁移学习,可以将这些预训练模型应用到新的任务上,从而节省大量的计算资源和训练时间。
8. 实际部署的挑战
尽管在研究和竞赛中有很多方法能取得显著的提高,但在实际生产中,许多优化技巧(如集成和Multi-crop)并不适用。这是因为它们往往需要大量的计算资源,可能导致生产系统的运行时间过长。因此,在设计生产系统时,更需要考虑到计算资源的限制和实时性需求。
3.27 目标定位
1. 图片分类 vs 定位分类
- 图片分类:算法判断图片中是否存在某种特定的对象(如汽车)。例如,使用卷积神经网络(CNN)对图像进行分类,输出一个类别。
- 定位分类:在判断对象类别的同时,还需要定位该对象在图片中的位置。即除了判断图片中是否有汽车外,还需要画出一个边界框,标记汽车的具体位置。
2. 边界框的参数化
- 对象定位不仅输出分类结果,还要输出一个边界框的四个参数(
x_center, y_center, height, width
)。这些参数表示边界框的中心点坐标、高度和宽度,用来框定检测到的对象的位置。
- 假设图片的左上角坐标为
(0,0)
,右下角为(1,1)
,这四个参数可以帮助确定边界框的位置。
3. 目标标签的定义
- 目标标签是一个向量,包含对象是否存在的信息及其边界框的参数。具体来说:
- 第一个元素表示图像中是否有对象(如汽车、行人、摩托车)。
- 后续四个元素是边界框的四个参数。
- 剩下3个元素表示该对象属于1-3类中的哪一类,这3者中最多只有一个等于1。
- 如果图像中没有检测到任何对象,其他边界框参数将被置为无意义(通常表示为问号)。
4. 分类与定位任务的损失函数
- 神经网络的损失函数用于计算网络输出与目标标签之间的差异,通常采用平方误差策略。
- 如果图片中存在对象,则计算边界框的预测值与实际值之间的平方误差。
- 如果图片中没有对象,只需要关注分类准确度,其他参数的损失不再考虑。
5. 总结
- 对象定位任务不仅仅是分类问题,还涉及到物体的定位问题。神经网络的输出包括是否存在物体、边界框的坐标参数以及分类标签。
- 训练集不仅包含分类标签,还需要包含边界框的参数,以便网络可以学习如何识别和定位目标对象。
- 损失函数通常考虑分类准确性和定位准确性,可以通过平方误差来衡量。
下一步,课程将讨论如何处理多对象检测问题以及更复杂的检测任务。
3.28 特征点检测问题
1. 特征点检测简介
- 神经网络不仅可以用于输出对象的边界框,还可以输出图片中特定特征点的坐标。通过这种方式,神经网络可以识别并定位图像中的特定目标特征。
2. 人脸识别中的特征点检测
- 以人脸识别为例,假设你想要识别并标定脸部的特征点(如眼角、嘴角、鼻尖等)。你可以让神经网络输出多个坐标点来表示这些特征点的位置。例如,输出两个数字代表一个眼角的坐标,四个眼角的坐标可以通过四个特征点表示。
- 如果需要更多特征点,可以通过设置一个定值(如64个特征点)来表示更详细的脸部轮廓和表情特征。输出的最终结果将是这些特征点的坐标集。
3. 如何构建训练集
- 为了训练神经网络,你需要准备一个包含标注过特征点的训练集。每张图片将有对应的标签,标签中包含每个特征点的准确坐标。神经网络将通过学习这些数据来自动标定图片中的特征点。
4. 增强现实应用
- 特征点检测在增强现实(AR)中有广泛应用。例如,Snapchat等应用使用面部特征点来添加虚拟物品(如皇冠)或实现面部扭曲效果。通过准确地检测和定位面部特征点,可以将虚拟元素与真实世界合成。
5. 人体姿态检测
- 除了面部特征,神经网络还可以用于人体姿态检测。通过定义一些关键点(如肩膀、肘部、膝盖等),网络可以标定人物的姿态。例如,输出胸部中点、左肩、左肘、腰部等特征点的坐标,以此表示人物的动作和姿势。
6. 一致性要求
- 在进行特征点检测时,每个特征点在所有图片中的标注必须一致。例如,右眼外眼角始终是特征点1,左眼内眼角始终是特征点3,等等。这种一致性是保证神经网络能够正确学习特征点标注的关键。
3.29 传统的滑动窗口目标检测算法

假如你想构建一个汽车检测算法,步骤是,首先创建一个标签训练集,也就是和表示适当剪切的汽车图片样本(x,y),这张图片(编号1)x是一个正样本,因为它是一辆汽车图片,这几张图片(编号2、3)也有汽车,但这两张(编号4、5)没有汽车。出于我们对这个训练集的期望,你一开始可以使用适当剪切的图片,就是整张图片x几乎都被汽车占据,你可以照张照片,然后剪切,剪掉汽车以外的部分,使汽车居于中间位置,并基本占据整张图片。有了这个标签训练集,你就可以开始训练卷积网络了,输入这些适当剪切过的图片(编号6),卷积网络输出y,0或1表示图片中有汽车或没有汽车。训练完这个卷积网络,就可以用它来实现滑动窗口目标检测,具体步骤如下。
假设这是一张测试图片,首先选定一个特定大小的窗口,比如图片下方这个窗口,将这个红色小方块输入卷积神经网络,卷积网络开始进行预测,即判断红色方框内有没有汽车。

滑动窗口目标检测算法接下来会继续处理第二个图像,即红色方框稍向右滑动之后的区域,并输入给卷积网络,因此输入给卷积网络的只有红色方框内的区域,再次运行卷积网络,然后处理第三个图像,依次重复操作,直到这个窗口滑过图像的每一个角落。
重复上述操作,不过这次我们选择一个更大的窗口,截取更大的区域,并输入给卷积神经网络处理,你可以根据卷积网络对输入大小调整这个区域,然后输入给卷积网络,输出0或1。

再以某个固定步幅滑动窗口,重复以上操作,遍历整个图像,输出结果。

这样,不论汽车在图片的什么位置,总有一个窗口可以检测到它。
但是这种办法也有很大的缺点:就是计算成本,因为你在图片中剪切出太多小方块,卷积网络要一个个地处理。如果你选用的步幅很大,显然会减少输入卷积网络的窗口个数,但是粗糙间隔尺寸可能会影响性能,无法准确定位图片中的对象;反之,如果采用小粒度或小步幅,传递给卷积网络的小窗口会特别多,这意味着超高的计算成本。
总结一下,实质是:先对数据集中的图片进行剪切(切为只包含车的尺寸,纯背景的不需要),切完后统一尺寸得到新的数据集;接着用这个数据集单独训练一个卷积神经网络(因为这个图片尺寸足够小,所以你可以认为这个算法只能检测一个图片中是否有车,框的大小就是图片的尺寸),接这个在原始数据集的图片上,通过滑动窗口,每次截取一个小图像送到模型中输出该块包含车的概率,直到滑动结束(图片右下角),得分最高的区域便为车及其框所在位置。
3.30 改进后的滑动窗口目标检测算法
之前的“3.29 传统的滑动窗口目标检测算法”有什么缺点呢?
我们确实是将整张图像分割成多个小块,然后逐个输入到卷积神经网络中进行检测。假设我们有一张较大的图像,我们会把它切割成多个小区域(比如 14×14 ),并对每个小区域进行前向传播(卷积和分类)。这种方法的一个问题是,每个小块都需要独立地进行计算,这样就会导致计算重复,尤其是小块之间有大量重叠区域时。(也即无法解决重叠带来的重复计算问题)
所以,我们换一种思路,不再将图像切割成独立的小块,而是直接将整个图像输入到卷积神经网络中进行计算。也即卷积块的移动代替了之前人为规定的滑动窗口(因为卷积块本质采用的就是滑动窗口策略),好处如下:
- 卷积核会在图像的不同位置执行相同的操作,不需要为每个小块分别使用不同的卷积核,这种方式节省了很多计算资源。之前的策略每个图像都要输入进小模型跑一遍。
- 通过卷积操作,我们不再为每个小块重新计算重叠区域,而是将这些区域共享计算。例如,如果图像的左上角和右上角有重复的部分,那么卷积层会在这两个区域之间共享计算结果,而不是每次都重新计算这部分。比如14×14向右侧滑动一格,其实只需要减去左侧那一列的乘积同时加上右侧那一列的乘积。
但是这样做有个问题,如果我们仍然采用全连接层和softmax进行卷积后处理,得到的只能是每个类别的概率,因为我们是对整个图像进行的处理,这样子就没意义了呀,和分类有什么区别呢?我如何定位到概率最大的类别所在的位置(框框)呢?
答案是:让输出不再以1维的格式输出(softmax那种的一维向量),而是以3维输出,a×b×c这样子。这样我们就可以查看到a×b上每个小块的所有类别概率c,找到所有类别概率最大值对应的小块自然就知道哪个在哪儿了。
怎么实现呢?通过点卷积操作
在这一步操作中(编号1),卷积网络运行同样的参数,使得相同的5×5×16过滤器进行卷积操作,得到12×12×16的输出层。然后执行同样的最大池化(编号2),输出结果6×6×16。照旧应用400个5×5的过滤器(编号3),得到一个2×2×400的输出层,现在输出层为2×2×400,而不是1×1×400。应用1×1过滤器(编号4)得到另一个2×2×400的输出层。再做一次全连接的操作(编号5),最终得到2×2×4的输出层,而不是1×1×4。最终,在输出层这4个子方块中,蓝色的是图像左上部分14×14的输出(红色箭头标识),右上角方块是图像右上部分(绿色箭头标识)的对应输出,左下角方块是输入层左下角(橘色箭头标识),也就是这个14×14区域经过卷积网络处理后的结果,同样,右下角这个方块是卷积网络处理输入层右下角14×14区域(紫色箭头标识)的结果。
以绿色方块为例,假设你剪切出这块区域(编号1),传递给卷积网络,第一层的激活值就是这块区域(编号2),最大池化后的下一层的激活值是这块区域(编号3),这块区域对应着后面几层输出的右上角方块(编号4,5,6)。
所以该卷积操作的原理是我们不需要把输入图像分割成四个子集,分别执行前向传播,而是把它们作为一张图片输入给卷积网络进行计算,其中的公共区域可以共享很多计算,就像这里我们看到的这个4个14×14的方块一样。

不过这种算法仍然存在一个缺点,就是边界框的位置可能不够准确(和卷积核的尺寸以及步长有关)。
接下来我们看一下YOLO是如何解决这个问题的。
3.31 Bounding Box预测
之前我们提到了“改进后的滑动窗口目标检测算法”存在边界框的位置可能不够准确的问题,这是因为卷积核的尺寸以及步长都是我们手动设置的(而非精准值),我们要做的就是用连续值(真实标签)取代原来的离散值(手动设置框的大小,固定死的)。

在改进后的滑动窗口法中,你取这些离散的位置集合,然后在它们上运行分类器,在这种情况下,这些边界框没有一个能完美匹配汽车位置,也许这个框(编号1)是最匹配的了。还有看起来这个真实值,最完美的边界框甚至不是方形,稍微有点长方形(红色方框所示),长宽比有点向水平方向延伸,有没有办法让这个算法输出更精准的边界框呢?
其中一个能得到更精准边界框的算法是YOLO算法,YOLO(You only look once)意思是你只看一次,这是由Joseph Redmon,Santosh Divvala,Ross Girshick和Ali Farhadi提出的算法。
那么它是怎么实现的呢?
首先,对原始图片进行网格划分,例如划分为3×3网格,实际实现时会用更精细的网格,可能是19×19;
接着定义全新的标签,例如我用3×3网格进行划分,那么最后的输出就必然是3×3×D(这里的D指的是第三维的长度,不同情况下不一样,例如一个网格内存在1个或多个目标物体时),y的含义和我们之前提到的类似:
但是你会想到,如果一个格子里包含了这个物体的一部分该如何定义呢?讲的更具体一点,这张图有两个对象,YOLO算法做的就是,取两个对象的中点,然后将这个对象分配给包含对象中点的格子。所以左边的汽车就分配到这个格子上(编号4),然后这辆Condor(车型:神鹰)中点在这里,分配给这个格子(编号6)。所以即使中心格子(编号5)同时有两辆车的一部分,我们就假装中心格子没有任何我们感兴趣的对象,所以对于中心格子,分类标签y和这个向量类似,和这个没有对象的向量类。
所以对于这里9个格子中任何一个,你都会得到一个8维输出向量,因为这里是3×3的网格,所以有9个格子,总的输出尺寸是3×3×8,所以目标输出是3×3×8。因为这里有3×3格子,然后对于每个格子,你都有一个8维向量,所以目标输出尺寸是3×3×8。
好了,了解了上述步骤,我们来谈一下为什么叫做“You only look once”呢?
- 首先,YOLO通过一次前向传播就能完成物体检测任务,而不像传统方法那样需要进行多次处理。那么它相比改进后的滑动窗口算法有何突出之处呢?
- YOLO确保了不存在重叠区域,图像的划分是严格按照网格来进行的,而不存在重叠区域,也即卷积核移动的时候是严格按照格子来移动的,这就大大降低了计算量;
- 此外YOLO的标签和“改进后的滑动窗口算法”都是3维,但前者在第三维上包含了更多信息(包括置信度、框框的坐标、尺寸以及各类别概率),后者则仅仅包含各类别概率。标签的丰富使得框框从离散值变为连续值,因此可以定位得更精确一些。
注:在我们上述得讨论中,只要每个格子中对象数目没有超过1个,这个算法应该是没问题的。一个格子中存在多个对象的问题,我们稍后再讨论。但实践中,我们这里用的是比较小的3×3网格,实践中你可能会使用更精细的19×19网格,所以输出就是19×19×8。这样的网格精细得多,那么多个对象分配到同一个格子得概率就小得多。
如何指定边界框?
现在你们了解了YOLO算法的基础(并非完整得YOLO,而是基于Bounding Box预测得到的YOLO,后续我们将介绍完整得YOLO算法),接下来我们继续讨论别的让这个算法效果更好的研究。
3.32 IoU
对象检测任务中,你希望能够同时定位对象,所以如果实际边界框是这样的,你的算法给出这个紫色的边界框,那么这个结果是好还是坏?所以交并比(loU)函数做的是计算两个边界框交集和并集之比。两个边界框的并集是这个区域,就是属于包含两个边界框区域(绿色阴影表示区域),而交集就是这个比较小的区域(橙色阴影表示区域),那么交并比就是交集的大小,这个橙色阴影面积,然后除以绿色阴影的并集面积。
在对象检测中,判断算法的性能通常会用交并比(IoU,Intersection over Union)来衡量预测边界框与真实边界框之间的重合度。交并比是通过计算两个边界框的交集面积与它们的并集面积之比来评价检测效果。具体来说:
交并比(IoU)的定义:
- 交集(Intersection):预测的边界框与实际边界框重叠的区域。
- 并集(Union):包含预测和真实边界框的整个区域(即,两个边界框的总面积)。
- IoU计算公式:
- 其中,交集面积是重叠区域的面积,而并集面积是两个边界框合并后的面积。
IoU的评价标准:
- IoU = 1:当预测边界框完全和真实边界框重合时,IoU为1,表示检测完美。
- IoU = 0.5(或更高):一般情况下,如果IoU大于0.5,就认为检测是有效的,即认为预测边界框与实际边界框足够重合。
- IoU阈值:通常情况下,IoU的阈值被设定为0.5。你可以根据需求调整阈值,使用更严格的标准(比如0.6、0.7),以要求边界框更精确地匹配。
IoU的应用:
- 判断检测准确性:IoU主要用于评价边界框的定位精度。如果预测框与实际框重叠度高,那么表示检测结果较好;反之,如果IoU低,说明检测不准确。
- 性能评估:IoU是衡量模型性能的一个重要指标。在进行物体检测时,可以根据IoU来判断哪些检测结果是有效的。比如,一个检测结果如果IoU大于设定阈值(通常为0.5),就可以认为它是“正确检测”。
3.33 非极大值抑制(NMS)
问题背景: 在对象检测任务中,YOLO等算法可能会对同一个物体做出多次检测。例如,在图像中,同一个物体可能被多个不同的网格检测到,因此会产生多个边界框。这种重复检测不仅浪费计算资源,而且会导致冗余的检测结果。非极大值抑制(NMS)就是用来解决这一问题的。

非极大值抑制(NMS)算法步骤:
-
生成多个边界框: 每个网格对图像中的每个对象进行检测,生成多个预测边界框。每个预测框都有一个与之关联的置信度(概率值)和边界框参数(如位置、宽高等)。
-
选择最高置信度的边界框: 对于每个检测到的物体,首先选择置信度最高的边界框作为最可靠的预测结果。
-
抑制重叠度高的框: 对于其他所有边界框,计算它们与当前选择的边界框的交并比(IoU)。如果某个边界框与已经选中的边界框的IoU大于预设的阈值(通常为0.5),那么就抑制(去除)这个边界框,因为它与已经选中的框重叠过多。
-
继续选择下一个最高置信度的框: 在去除掉重叠度高的边界框后,继续选择下一个置信度最高的框,并重复以上过程,直到所有的边界框都被处理完。
-
输出最终检测结果: 最终,保留那些置信度较高且与其他框重叠较少的边界框,作为最终的检测结果。


NMS的关键点:
- IoU阈值:阈值通常设定为0.5。如果两个框的IoU大于0.5,则认为它们重叠过多,抑制较差的框。
- 多类别处理:在同时检测多种物体时,需要对每个类别独立进行非极大值抑制。比如,对于检测到的“汽车”类别和“行人”类别,分别进行NMS处理,而不是将所有类别一起处理。
NMS的作用:
- 消除冗余框:通过去除多个重叠的边界框,减少冗余的检测结果,确保每个物体仅被检测一次。
- 提高检测精度:通过选择最优的边界框,提升物体定位的精度。
3.34 Anchor Box(锚框)概念总结
背景问题:
假设你有这样一张图片,对于这个例子,我们继续使用3×3网格,注意行人的中点和汽车的中点几乎在同一个地方,两者都落入同一个格子中。如果仍然采用我们之前的y标签,则两者只能取其一
在YOLO等传统的对象检测算法中,每个网格只会对一个对象进行检测,且每个格子只能产生一个预测结果。然而,现实中一个格子中可能有多个物体存在,尤其是当物体的中心点相近时。为了处理这种情况,YOLO引入了Anchor Box(锚框)的概念,使得每个格子可以处理多个物体。
Anchor Box的工作原理
-
定义Anchor Box:
- Anchor Box是预先定义好的、不同形状和尺寸的边界框,用来对不同形态的物体进行匹配。
- 每个网格在检测物体时,会使用一个或多个Anchor Box来预测物体的边界框。
- 比如,如果物体的形状类似于某个Anchor Box的形状,那么该Anchor Box就会用于检测这个物体。
-
-
分配Anchor Box:
- 对于每个网格位置,首先根据物体的实际边界框和Anchor Box的形状进行匹配,选择与物体边界框交并比(IoU)最大的Anchor Box。
- 每个物体不仅会分配到一个网格,还会被分配到最合适的Anchor Box。这样即使多个物体落在同一个格子中,也可以通过不同的Anchor Box来进行区分和检测。
-
编码目标:
- 每个网格的输出不仅包含物体类别,还包含与对应Anchor Box相关的边界框参数。例如,对于每个Anchor Box,都会输出物体类别、边界框的坐标(中心点、宽高)以及置信度(即是否存在物体)。
- 如果一个格子内有多个物体(例如行人和汽车),则根据与物体形状最匹配的Anchor Box,将物体分配到相应的Anchor Box中。
-
维度扩展:引入Anchor Box后,输出的维度会增加。例如,如果每个格子使用2个Anchor Box,那么输出将会是原来的2倍(例如3×3网格的输出将是3×3×16,而不是3×3×8),每个Anchor Box有8个参数(包括位置和类别信息)。
-
无法处理的僵局:
- 如果你有两个anchor box,但在同一个格子中有三个对象;
- 两个对象都分配到一个格子中,而且它们的anchor box形状也一样。
- 希望你的数据集里不会出现这种情况,其实出现的情况不多,所以对性能的影响应该不会很大。
-
Anchor Box选择方法:
- 手动选择:一般通过观察数据集中的物体形状,手动选择几种典型的Anchor Box形状(例如针对宽而长的物体选择较宽的Anchor Box,针对高而窄的物体选择较高的Anchor Box)。
- 自动选择(进阶方法):通过聚类算法(如k-均值算法)自动选择最具代表性的Anchor Box。这样可以根据数据集中的物体形状自动优化Anchor Box的选择。
3.35 YOLO
YOLO(You Only Look Once)是一种高效的对象检测算法,通过将图像分成网格并使用多个Anchor Box来进行多目标检测。这个视频主要介绍了如何将YOLO的各个组件整合在一起进行训练和预测。以下是YOLO算法的完整工作流程:
1. 训练集构造
在训练YOLO模型时,首先需要准备一个包含多个对象类别的训练集。假设你要训练一个模型来检测三种对象:行人、汽车和摩托车,同时还需要显式指定背景类别。
-
网格和Anchor Box:
- 假设使用3×3的网格,每个网格会预测多个Anchor Box。对于每个Anchor Box,输出包含物体类别、边界框位置(中心点坐标、宽高)和置信度。
- 在使用2个Anchor Box时,输出的维度为3×3×2×8(其中3×3是网格的大小,2是Anchor Box的数量,8是每个Anchor Box的参数数量:包括5个边界框参数和3个类别标签)。
-
目标向量构造:
- 对于每个网格,根据物体的位置和形状分配Anchor Box。例如,如果某个网格位置有汽车,其边界框与Anchor Box 2的形状匹配,那么就将汽车的边界框和类别信息与Anchor Box 2对应的向量部分关联起来。
- 如果该网格没有物体,则该网格的目标向量中与物体相关的部分为0,其他部分为“don’t care”标记。
2. 神经网络训练
- 输入和输出:
- 输入:原始图像(例如100×100×3的RGB图像)。
- 输出:经过卷积神经网络处理后的预测结果,形状为3×3×16或3×3×2×8(取决于使用的Anchor Box数量)。
- 训练过程:
- 网络的输出是每个网格对应的预测向量。对于每个网格:
- 如果网格没有物体,输出的值应为0或噪声。
- 如果网格内有物体,网络会预测该物体的类别、边界框的坐标和置信度。
- 网络的输出是每个网格对应的预测向量。对于每个网格:
3. 预测过程
-
在预测时,YOLO会对每个网格和Anchor Box的组合进行预测,输出一个关于物体类别和边界框的向量。
-
左上格子(没有物体):
- 对于没有物体的格子,网络的输出应该是0,表示该格子没有有效预测。
-
含有物体的格子:
- 对于含有物体的格子,网络会预测该物体的边界框坐标、类别信息以及与Anchor Box的相关性。
- 比如,如果某个格子内有汽车且Anchor Box 2与汽车的边界框匹配,那么该网格的输出会包含关于汽车的信息。
4. 非极大值抑制(NMS)
-
YOLO通过非极大值抑制(NMS)来处理多重检测,并去除冗余的边界框。
- 步骤:
- 对于每个网格,网络输出两个预测的边界框(基于两个Anchor Box),其中一个可能概率较低。对于概率较低的预测,网络会抛弃。
- 然后,对所有的边界框进行NMS处理。NMS会根据交并比(IoU)阈值抑制掉重叠的边界框,只保留置信度较高的预测。
- 对于每个类别(行人、汽车、摩托车),独立地运行一次NMS。
- 步骤:
-
多类别检测:
- 如果检测图像中有多个物体类别,YOLO会分别对每个类别进行NMS,以确保每个类别的物体检测都是独立的,并最终输出最终的预测结果。
5. YOLO算法总结
- YOLO通过将图像划分为网格并使用Anchor Box的机制来高效地检测物体。每个网格可以检测多个物体,并且通过NMS确保不会输出重复的检测结果。
- YOLO的优点在于它不仅高效,而且可以处理不同形状的物体,适应多种物体尺寸。
- 在训练过程中,YOLO网络学习如何将输入图像映射到每个网格的预测向量,通过最小化预测与真实值之间的损失来优化模型。
6. 进一步优化:
- 在实践中,YOLO通常会使用较大的网格(如19×19)和更多的Anchor Box来提高检测精度。
- YOLO还可以通过更复杂的网络架构和损失函数优化来进一步提高性能。
3.36 候选区域与R-CNN系列算法概述
在计算机视觉中的对象检测任务里,“候选区域”是一个非常重要的概念,尤其是在区域卷积神经网络(R-CNN)系列算法中。这些算法的核心思想是先通过某种方法生成可能包含目标的区域(候选区域),然后在这些候选区域上运行分类器进行对象识别。
1. 滑动窗口法的局限性
传统的对象检测方法常使用滑动窗口法,即将训练好的分类器应用于图像的每个位置和尺度,以检查是否存在目标。然而,滑动窗口法存在以下缺点:
- 计算量巨大:每个位置的每个尺度都需要进行计算,因此在图像中显然没有物体的区域也会浪费时间进行计算。
- 低效:在没有物体的区域运行分类器是没有意义的,容易导致冗余计算。

2. R-CNN的提出与候选区域
为了解决滑动窗口法的局限性,R-CNN(Region-based Convolutional Neural Networks)算法应运而生。R-CNN的核心思想是通过生成一组候选区域,然后只在这些候选区域上运行卷积神经网络(CNN),而不是在整个图像上进行滑动窗口操作。这样做的好处是:
- 减少了计算量:只在潜在的物体区域(候选区域)上进行卷积神经网络的处理。
- 提高了检测精度:可以通过更精细的候选区域来捕捉到物体的边界和特征。
R-CNN的工作流程:
- 候选区域生成:使用图像分割算法(如Selective Search)生成一组候选区域,通常生成数千个候选区域,这些区域可能包含目标物体。
- 区域分类:对每个候选区域,R-CNN将其裁剪出来并调整为固定大小,输入到卷积神经网络中进行特征提取和分类。
- 边界框回归:R-CNN还会回归出物体的边界框,使得生成的边界框更精确。
尽管R-CNN显著提高了检测精度,但它也有一个显著的缺点——速度较慢。每个候选区域都要单独输入卷积神经网络进行计算,处理速度很慢。
3. 快速R-CNN(Fast R-CNN)
为了加速R-CNN,Fast R-CNN算法应运而生。其主要创新点在于:
- 共享卷积特征:不像R-CNN对每个候选区域都进行单独的卷积操作,Fast R-CNN通过对整张图像进行一次卷积操作,得到一个特征图,然后从中提取出每个候选区域的特征(RoI Pooling层)。
- 端到端训练:Fast R-CNN可以实现端到端的训练,这使得训练过程更加高效。
尽管Fast R-CNN提高了速度,但候选区域生成仍然是瓶颈,因为候选区域生成步骤仍然依赖于传统的图像分割算法,导致速度上仍然无法满足实时检测的需求。
4. 更快R-CNN(Faster R-CNN)
为了进一步提高速度,Faster R-CNN提出了一个全新的候选区域生成方法——区域提议网络(RPN)。RPN是一个基于卷积神经网络的网络结构,可以直接在图像特征图上生成候选区域,而不依赖于传统的分割算法。通过这种方式,Faster R-CNN实现了如下目标:
- 速度提升:通过RPN生成候选区域,省去了传统候选区域生成的计算步骤,显著提升了速度。
- 端到端训练:RPN与主网络共享卷积特征,可以一起训练,进一步提高了效率。
尽管Faster R-CNN比Fast R-CNN更快,但它的速度仍然较慢,尤其是与YOLO(You Only Look Once)等单步检测算法相比。
5. YOLO与R-CNN的对比
YOLO算法与R-CNN系列的最大区别在于:
- YOLO是单步检测:YOLO不需要候选区域生成,它直接将图像分割成网格并在每个网格中进行预测,整个过程只需一步完成。这种方法的优点是速度非常快,适合实时检测。
- R-CNN是两步检测:R-CNN和它的改进版本(Fast R-CNN、Faster R-CNN)需要两步处理:第一步是生成候选区域,第二步是对这些候选区域进行分类和回归,处理时间较长。
YOLO通过一次性预测所有边界框,避免了候选区域生成和后续分类的重复计算,而R-CNN则需要在多个步骤中处理,因此在速度上不如YOLO。
6. 候选区域的影响
尽管YOLO和类似的单步检测方法在速度上具有优势,候选区域的概念仍然在计算机视觉领域具有广泛的影响。尤其是在一些较为复杂的场景或需要更高精度的任务中,基于候选区域的检测方法(如R-CNN及其变体)仍然占有一席之地。候选区域生成通常能帮助模型聚焦于潜在的目标区域,提高检测精度。
3.37 人脸验证与人脸识别。
在人脸识别领域,我们通常涉及到两个概念:人脸验证(Face Verification)和人脸识别(Face Recognition)。
-
人脸验证(Face Verification):
- 这是一个一对一(1-to-1)的匹配问题。系统接收一张输入图片和一个对应的身份信息(如ID或名字),然后判断输入图片中的人是否与声称的身份相符。
- 应用场景:登录验证(如通过照片验证用户是否为账户持有者)。
-
人脸识别(Face Recognition):
- 这是一个一对多(1-to-N)的识别问题。系统从数据库中找出与输入图片匹配的身份,即从多个候选人中找到与输入图片最相似的人。
- 难点:如果数据库中有100个人,验证系统的错误率为1%,那么在识别任务中出错的概率会大大增加,要求验证系统的准确率必须非常高。
3.38 One-Shot学习
一次学习问题(One-Shot Learning)是指在仅有一张训练样本的情况下,系统就能够识别同一对象。
传统的深度学习算法在少量数据时表现较差,而人脸识别场景中常常只有每个人的一张照片,这使得一次学习问题尤为重要。
假设你的数据库里有4张你们公司的员工照片,实际上他们确实是我们deeplearning.ai的员工,分别是Kian,Danielle,Younes和Tian。现在假设有个人(编号1所示)来到办公室,并且她想通过带有人脸识别系统的栅门,现在系统需要做的就是,仅仅通过一张已有的Danielle照片,来识别前面这个人确实是她。相反,如果机器看到一个不在数据库里的人(编号2所示),机器应该能分辨出她不是数据库中四个人之一。
所以在一次学习问题中,只能通过一个样本进行学习,以能够认出同一个人。大多数人脸识别系统都需要解决这个问题,因为在你的数据库中每个雇员或者组员可能都只有一张照片。
有一种办法是,将人的照片放进卷积神经网络中,使用softmax单元来输出4种,或者说5种标签,分别对应这4个人,或者4个都不是,所以softmax里我们会有5种输出。但是这样有什么缺点呢?
- 实际上这样效果并不好,因为如此小的训练集不足以去训练一个稳健的神经网络。
- 假如有新人加入你的团队,你现在将会有5个组员需要识别,所以输出就变成了6种,这时你要重新训练你的神经网络吗?
解决方法:
- 通过学习一个相似性函数(Similarity Function),输入两张图片,输出一个差异值。
- 当两张图片是同一个人时,差异值应较小;当两张图片是不同的人时,差异值应较大。
- 所以在识别过程中,如果这两张图片的差异值小于某个阈值,它是一个超参数,那么这时就能预测这两张图片是同一个人,如果差异值大于阈值,就能预测这是不同的两个人,这就是解决人脸验证问题的一个可行办法。
- 也即当某人走到脸机前时,摄像头捕捉该图片然后进入数据库中和已有员工的图片一一比对,得到相似性最大的差值看是否大于阈值,若小于则证明非本公司员工。
- 要注意在这过程中你是如何解决一次学习问题的,只要你能学习这个函数,通过输入一对图片,它将会告诉你这两张图片是否是同一个人。如果之后有新人加入了你的团队(编号5),你只需将他的照片加入你的数据库,系统依然能照常工作。
3.39 Siamese 网络(Siamese Network)
Siamese网络是一种用于比较两个输入的神经网络架构,它共享相同的权重,即两个输入通过同一套卷积神经网络,得到各自的编码表示(向量)。
- 输入:两张人脸图片
- 输出:每张图片的编码表示(通常为128维向量)
- 计算距离:通过计算两个编码表示的欧式距离来衡量图片的相似度
优势:
- 不需要重新训练整个网络,只需要比较新的图片编码和已有数据库中的编码。
- 适合一次学习问题,因为即使只有一张参考图片,也能进行有效识别。
怎么训练这个Siamese神经网络呢?
不要忘了这两个网络有相同的参数,所以你实际要做的就是训练一个网络,它计算得到的编码可以用于函数,它可以告诉你两张图片是否是同一个人。更准确地说,神经网络的参数定义了一个编码函数,如果给定输入图像,这个网络会输出的128维的编码。你要做的就是学习参数,使得如果两个图片和是同一个人,那么你得到的两个编码的距离就小,否则就大。
你要做的就是用反向传播来训练更新这些所有的参数,直到满足上述的条件。
你已经了解了Siamese网络架构,并且知道你想要网络输出什么,即什么是好的编码。但是如何定义实际的目标函数,能够让你的神经网络学习并做到我们刚才讨论的内容呢?在下一个章节里,我们会看到如何用三元组损失函数达到这个目的。
3.40 三元组损失(Triplet Loss)
要想通过学习神经网络的参数来得到优质的人脸图片编码,方法之一就是定义三元组损失函数然后应用梯度下降。
-
定义:
- Anchor(A):基准图片
- Positive(P):与Anchor相同的人脸图片
- Negative(N):与Anchor不同的人脸图片
-
目标:使得 Anchor 和 Positive 之间的距离小于 Anchor 和 Negative 之间的距离,并且至少相差一个间隔(margin):
-
-
其中,α 是一个超参数,用于控制间隔大小,防止网络输出所有编码都一样的无效情况。
-
损失函数:
-
-
选择三元组:
- 选择难训练的三元组(Hard Triplets),即
-
之间的差距较小的样本,从而增加训练的效果。
这是一个三元组定义的损失,整个网络的代价函数应该是训练集中这些单个三元组损失的总和。假如你有一个10000个图片的训练集,里面是1000个不同的人的照片,你要做的就是取这10000个图片,然后生成这样的三元组,然后训练你的学习算法,对这种代价函数用梯度下降,这个代价函数就是定义在你数据集里的这样的三元组图片上。
注意,为了定义三元组的数据集你需要成对的A和P,即同一个人的成对的图片,为了训练你的系统你确实需要一个数据集,里面有同一个人的多个照片。这是为什么在这个例子中,我说假设你有1000个不同的人的10000张照片,也许是这1000个人平均每个人10张照片,组成了你整个数据集。如果你只有每个人一张照片,那么根本没法训练这个系统。当然,训练完这个系统之后,你可以应用到你的一次学习问题上,对于你的人脸识别系统,可能你只有想要识别的某个人的一张照片。但对于训练集,你需要确保有同一个人的多个图片,至少是你训练集里的一部分人,这样就有成对的Anchor和Positive图片了。
实质:利用多个三元组训练样本训练出一个可以得到优质的人脸图片编码的神经网络(优质的定义:相似人脸的编码差值小,不相似的差值大),然后再让公司人员的图片上传至数据库,顺序跑一遍该神经网络拿到对应的编码存储到数据库中。当人员来上班时,脸机捕获人脸照片再跑一遍该神经网络并获取到其编码,将其和数据库中存储的大量编码进行比对得到差值最小的即可。
如何构建三元组训练样本呢?
随机选择A,P,N,很容易达到如下条件,这样网络并不能从中学到什么。
所以为了构建一个数据集,你要做的就是尽可能选择难训练的三元组A、P、N。
如果你对此感兴趣的话,这篇论文中有更多细节,作者是Florian Schroff, Dmitry Kalenichenko, James Philbin,他们建立了这个叫做FaceNet的系统
• Florian Schroff, Dmitry Kalenichenko, James Philbin (2015)
FaceNet: A Unified Embedding for Face Recognition and Clusterin
在深度学习领域,算法是如何命名的:
顺便说一下,这有一个有趣的事实,关于在深度学习领域,算法是如何命名的。如果你研究一个特定的领域,假如说“某某”领域,通常会将系统命名为“某某”网络或者深度“某某”,我们一直讨论人脸识别,所以这篇论文叫做FaceNet(人脸网络),上个视频里你看到过DeepFace(深度人脸)。“某某”网络或者深度“某某”,是深度学习领域流行的命名算法的方式,你可以看一下这篇论文,如果你想要了解更多的关于通过选择最有用的三元组训练来加速算法的细节,这是一个很棒的论文。
优质的人脸图片编码的神经网络——预训练模型
现在的人脸识别系统,尤其是大规模的商业人脸识别系统都是在很大的数据集上训练,超过百万图片的数据集并不罕见,一些公司用千万级的图片,还有一些用上亿的图片来训练这些系统。这些是很大的数据集,即使按照现在的标准,这些数据集并不容易获得。幸运的是,一些公司已经训练了这些大型的网络并且上传了模型参数。所以相比于从头训练这些网络,在这一领域,由于这些数据集太大,这一领域的一个实用操作就是下载别人的预训练模型,而不是一切都要从头开始。但是即使你下载了别人的预训练模型,我认为了解怎么训练这些算法也是有用的,以防针对一些应用你需要从头实现这些想法。
3.41 人脸验证与二分类(Face verification and binary classification)
之前我们提到构建Siamese神经网络并构建三元组样本对其训练,那么可以只构建二元组样本实现上述功能么?
实际上,这是可以的
大致思路如下:
这些公式及其变形在这篇DeepFace论文中有讨论:
• Yaniv Taigman, Ming Yang, Marc'Aurelio Ranzato, Lior Wolf (2014)
DeepFace:Closing the gap to human-level performance in face verification
这种方法与 Triplet Loss 的不同之处在于,二分类模型仅需成对的图像训练,而 Triplet Loss 需要三元组 (anchor, positive, negative) 进行训练。这种二分类方法简单且效果好,适合小型数据集或对计算资源要求较高的场景。
3.42 什么是神经风格迁移?
在神经风格迁移中,我们的目标是根据一幅内容图片和一幅风格图片,生成一幅结合了内容和风格的新图片。也即由Content和Styte生成新的图片的过程。


为了实现神经风格迁移,你需要知道卷积网络提取的特征,在不同的神经网络,深层的、浅层的。在深入了解如何实现神经风格迁移之前。
3.43 CNN特征可视化
深度卷积网络到底在学什么?接下来我将展示一些可视化的例子,帮助大家理解CNN 的不同层次是如何工作的。我们选择不同层的隐藏单元,然后查看最大化了单元激活的9个图片块。
- 浅层特征(第一层到第二层):
- 第一层的卷积核通常学习到边缘检测、颜色阴影等简单的特征。通过寻找那些使特定神经元激活最大的图片块,可以发现这一层通常会响应于简单的形状和边缘。
- 中层特征(第三层到第四层):
- 随着网络层次加深,神经元所能看到的感受野(Receptive Field)变大,这意味着每个神经元会响应输入图像中更大区域的特征。
- 在这个阶段,网络开始学习更复杂的模式,如纹理、重复图案、几何形状等。
- 深层特征(第五层及之后):
- 在深层,网络已经学习到能够识别更抽象和具体的概念,比如动物、物体或文字等具体的类别。这些神经元可以捕捉到输入图片中高度复杂的模式。
这种特征可视化帮助我们理解为什么神经风格迁移(Neural Style Transfer)算法能够使用卷积网络来将一种图像的风格迁移到另一种图像上。浅层的特征主要用来捕捉风格(如笔触和纹理),而深层的特征用于识别图像的内容。
3.44 风格迁移的代价函数
这里有个例子,假设你从这张内容图片(编号1)和风格(编号2)图片开始,这是另一张公开的毕加索画作,当你随机初始化,你随机初始化的生成图像就是这张随机选取像素的白噪声图(编号3)。接下来运行梯度下降算法,最小化代价函数,逐步处理像素,这样慢慢得到一个生成图片(编号4、5、6),越来越像用风格图片的风格画出来的内容图片。
在这段视频中你看到了神经风格迁移算法的概要,定义一个生成图片的代价函数,并将其最小化。接下来我们需要了解怎么去定义内容代价函数和风格代价函数,让我们从下一个章节开始学习这部分内容吧。
3.45 内容代价函数
在神经风格迁移(Neural Style Transfer)中,内容代价函数用于衡量生成图像与内容图像在内容上的相似性。以下是内容代价函数的详细定义和总结。
1. 内容代价函数的目标
- 目的:评估生成图像 G 与内容图像 C 在指定的神经网络层上的特征表示(激活值)之间的差异。
- 原则:如果两张图片在某一层的激活值相似,则意味着它们在内容上相似。
2. 选择层的考虑
- 浅层 vs 深层:
- 浅层(例如隐含层1):包含低级特征,如边缘、纹理等。如果使用浅层,生成图像在像素级别上会非常接近内容图像。
- 深层:包含高级特征,如物体、复杂结构等。如果使用深层,则生成图像会保留高层次的内容(如图片是否包含某种物体)。
- 中间层:通常在实际应用中选择网络的中间层,这样既不会只关注低级特征,也不会完全忽略图片的结构和内容。常用的模型是VGG网络等预训练卷积神经网络。
3. 内容代价函数的定义
4. 归一化和调整参数
5. 梯度下降的应用
3.46 风格代价函数
在上一节中,我们学习了内容代价函数,用于评估生成图像和内容图像在内容上的相似性。本节将介绍风格代价函数,用于衡量生成图像与风格图像在风格上的相似性。
1. 风格的定义
- 风格:指的是图像的纹理、色彩模式,而不是具体的物体或结构。比如一幅画的笔触、色彩搭配和纹理都是其风格的一部分。
- 在深度学习中,风格通常用特征图(activation maps)的通道之间的相关性来表示。
- 原则:风格图像和生成图像在不同通道的激活项之间的相关性相似,即特征图中各个通道之间的“协同模式”是否相似。
2. 风格矩阵(Gram矩阵)的定义
3. 生成图像的风格矩阵
4. 风格代价函数的定义
5. 总风格代价函数
3.47 一维到三维卷积神经网络的推广
1. 2D卷积(图像数据)
- 输入数据:典型的2D图像,形如
14×14
,或带有颜色通道的14×14×3
。 - 卷积操作:使用2D过滤器,例如
5×5
或5×5×3
(与输入图像通道匹配)。过滤器会在图像的各个位置进行滑动,提取特征,得到特征图输出,例如10×10
。 - 输出结果:使用多个过滤器(如16个)会得到
10×10×16
的输出,这代表每个位置被16种不同的特征检测器提取。
2. 1D卷积(序列数据)
- 输入数据:一维序列数据,如心电图(EKG信号),形如
14
(时间序列长度)或14×1
(单通道)。 - 卷积操作:使用1D过滤器,例如
1×5
,类似于在一维序列上滑动,检测特定的特征模式。卷积后会得到10
长度的输出。 - 多通道和多过滤器:若使用多通道(如不同的电极测量心电图)和多个过滤器(如16个),输出形如
10×16
。 - 应用场景:1D卷积常用于处理时间序列数据,如语音信号、心电图等。在某些情况下,1D卷积网络可以替代递归神经网络(RNN)进行序列数据处理。
3. 3D卷积(体数据)
- 输入数据:3D数据,如CT扫描生成的立体图像,形如
14×14×14
,代表长、宽、高。 - 卷积操作:使用3D过滤器,例如
5×5×5
,在长、宽、高三个维度上滑动,检测3D特征。输出形如10×10×10
。 - 多通道和多过滤器:如输入带有多个通道(如不同的CT扫描片段)并使用16个过滤器,输出将是
10×10×10×16
。 - 应用场景:3D卷积主要用于处理体数据,如医疗影像中的CT、MRI扫描,以及视频分析(如动作识别),将时间作为第三个维度。
总结与推广
- 1D卷积主要用于序列数据的特征提取,适用于时间序列、语音信号等。
- 2D卷积是处理图像的核心方法,用于提取空间特征,如边缘、纹理和形状。
- 3D卷积适用于体数据和视频,能够在空间和时间维度上同时提取特征。
核心思想:
- 无论是一维、二维还是三维卷积,卷积操作的核心思想是不变的:利用过滤器在不同位置滑动,提取局部特征,再堆叠形成特征图。
- 这种操作可以推广到任意维度的数据,只需要将过滤器和输入数据在对应的维度上进行匹配即可。
4 补充知识点:
4.1 最大池化(Max Pooling)比平均池化(Average Pooling)在卷积神经网络中更常用的原因。
- 保留显著特征:最大池化能保留局部区域的最显著特征(如边缘、角落),而平均池化会平滑这些特征,导致信息丢失。
- 提高鲁棒性:最大池化对噪声和扰动更不敏感,能保持重要信息。
- 训练效果更好:最大池化通常帮助模型更快收敛,提升性能。
4.2 CNN中空间不变性和池化之间有何联系?
1. 什么是空间不变性?
空间不变性(spatial invariance),也称为平移不变性,指的是卷积神经网络具有的一个重要特性——网络能够识别输入图像的特征,不受图像位置变化的影响。换句话说,无论目标物体出现在图像的哪个位置,CNN都应该能够正确地识别该物体。这意味着,网络不仅仅要关注局部特征,而要学会从不同位置和不同尺度上提取特征。
在传统的全连接神经网络中,每个神经元都连接到输入图像的每一个像素,因此位置和空间结构信息很难被保留。而在CNN中,通过使用卷积层和池化层,网络能够捕捉到局部特征并具有空间不变性。
2. 池化(Pooling)操作的作用
池化操作(特别是最大池化和平均池化)是一种下采样操作,旨在减小特征图的尺寸,同时保留重要的特征信息。池化操作可以减少计算量和参数,同时增加网络对空间变换(如平移、旋转、缩放)的鲁棒性。
池化的常见形式:
- 最大池化(Max Pooling):在一个固定大小的窗口(例如2x2或3x3)内选择最大值。通过这种方式,池化层能够保留该区域的最显著特征,同时忽略细节。
- 平均池化(Average Pooling):在一个固定大小的窗口内计算平均值。相比最大池化,它保留了更平滑的特征,但也可能丢失一些局部的显著性特征。
3. 池化如何实现空间不变性?
池化操作帮助CNN实现空间不变性,具体机制如下:
-
位置不敏感性:池化操作减少了特征图的空间分辨率,因此即使输入图像中的某个特征发生了小的平移,池化层也能保证对该特征的识别不受影响。例如,如果一个物体在输入图像中发生了轻微平移,最大池化层仍然能保留这个物体的最显著特征(最大值),从而增强网络对平移变化的鲁棒性。
-
特征的概括化:池化通过对局部区域的汇聚(如取最大值或平均值),将局部特征转化为较为简洁的全局特征。这样,模型能够学习到不依赖于物体具体位置的通用特征,从而提升空间不变性。比如,在图像分类任务中,池化操作帮助网络不依赖于物体在图像中的具体位置,而能识别该物体在任意位置的出现。
-
减少过拟合:池化还通过减少参数量和特征图尺寸,起到类似正则化的作用,避免网络过度拟合于输入图像的细节。这使得网络不仅能对输入图像的具体位置变化不敏感,还能对局部噪声、细节和变形更具鲁棒性。
4. 空间不变性与卷积层的关系
除了池化,卷积层本身也在一定程度上帮助网络实现空间不变性。卷积操作通过在输入图像上应用共享的过滤器(卷积核),使得网络能够提取图像中的局部特征,而不依赖于这些特征的具体位置。
- 共享权重:卷积层中的卷积核在整个图像上滑动,使用相同的权重来提取不同位置的特征,这种共享权重的机制使得卷积层具有了空间不变性。
- 局部感受野:卷积核只关注图像的局部区域,而池化则对局部区域进行概括。因此,卷积和池化的结合使得CNN不仅能识别局部特征,还能有效地进行空间不变性学习。
4.3 LRN为啥被Batch Normalization取代了呢?
虽然局部响应归一化(LRN)在早期的神经网络(例如AlexNet)中尝试过,但后来很多研究表明,LRN并没有像预期那样显著提升性能,甚至在一些情况下,效果并不理想。具体原因包括以下几个方面:
1. LRN的计算复杂度和训练效率问题
LRN需要对每个神经元在局部区域内的激活值进行归一化,这会增加额外的计算量。对于大规模网络和深度网络来说,LRN的计算和内存开销可能成为一个瓶颈,尤其是在处理高分辨率图像和较大的数据集时。随着深度学习技术的发展,越来越多的研究者发现,使用更简单的归一化方法(如批量归一化)效果更好,且计算开销更小。
2. LRN对激活的影响过于局部化
LRN在归一化时只考虑一个小的局部范围(比如邻近几个神经元的激活值),这种方法对整体特征的捕捉比较有限。在某些情况下,LRN可能抑制了网络中某些有效特征的激活,导致模型难以捕捉到全局信息。相比之下,批量归一化(Batch Normalization)方法通过考虑整个批次的数据来进行归一化,能够更加全面地调节神经网络的激活,进而提高了网络的稳定性和训练效率。
3. LRN对于深度网络的影响减弱
随着神经网络架构变得越来越深,LRN的效果逐渐减弱。深度网络本身已经具备了足够的能力去捕捉复杂的特征,过多的局部归一化反而可能干扰模型的学习过程。在这种情况下,LRN的正则化效果不如预期,反而可能影响网络的学习能力。
4. 替代方法的出现
LRN的作用是通过局部归一化来增加神经元之间的竞争性,但后来批量归一化(Batch Normalization,BN*逐渐成为了更有效的替代方法。批量归一化通过对每个小批次的数据进行归一化,帮助加速训练,提高了网络的稳定性,避免了梯度消失问题,且计算效率也比LRN更高。BN不仅在全连接层中有效,在卷积层中也能取得良好的效果,因此迅速取代了LRN。
5. LRN的激活函数与ReLU不兼容
LRN的归一化是基于sigmoid或tanh激活函数的,但当ReLU(Rectified Linear Unit)激活函数开始成为主流时,LRN的效果并不理想。ReLU激活函数的输出是非负的,因此在与LRN结合时,LRN的归一化操作会干扰ReLU的输出,导致网络的训练变得不稳定。相比之下,BN不依赖于激活函数类型,能够更好地适应不同的激活函数。
总结
- LRN引入了额外的计算复杂度,并且在深度网络中逐渐显示出效果不佳的趋势。
- 它的局部归一化操作对全局特征的捕捉能力有限,尤其是在深度网络和大数据集的情况下,反而可能影响网络的学习效果。
- 批量归一化(BN)成为了更有效的替代方法,它不仅能加速训练,还能稳定网络,处理复杂任务时的表现更好。
4.4 “VGG使用多个较小卷积核(3x3)的卷积层代替一个卷积核较大的卷积层”的原因。
VGG 使用多个较小的卷积核(如 3x3)代替单个较大的卷积核(如 5x5 或 7x7),这一设计背后有几个关键的原因,主要包括:
1. 增加网络的非线性表达能力
- 使用多个较小的卷积核(例如 3x3)比单一大卷积核(如 5x5)能够增加更多的 非线性变换。每增加一层卷积,就会有一个非线性激活函数(如 ReLU)在该层之后。通过堆叠多个卷积层,网络可以有效地增加非线性表达能力,能够学习到更复杂、更抽象的特征。
- 比如,两个连续的 3x3 卷积层组合,相当于一个 5x5 卷积核的效果,但同时每一层都能引入更多的非线性变换。
2. 减少参数数量
- 一个 5x5 卷积核会有 25 个参数,而一个 3x3 卷积核则只有 9 个参数。假设你用两个 3x3 的卷积核堆叠代替一个 5x5 的卷积核,虽然输出特征图的大小相同,但参数数量要比直接使用一个 5x5 的卷积核少得多。对于同样数量的卷积核,堆叠多个 3x3 卷积层能够显著减少模型的总参数量。
- 举个例子:
- 一个 5x5 的卷积核和 1 个卷积层(输入通道数为 C,输出通道数为 K)会有 25 * C * K 个参数。
- 两个 3x3 卷积层,输入通道数为 C,输出通道数为 K,每层卷积核有 9 * C * K 个参数,两层一共是 18 * C * K 个参数。
- 因此,两个 3x3 卷积层的参数数量比一个 5x5 卷积层少一半,这样可以减少计算量,降低模型的复杂度。
3. 更细粒度的特征提取
- 使用较小的卷积核(如 3x3)可以让网络更细致地处理输入图像的局部区域。在一个图像中,每个 3x3 的卷积核只能捕捉一个较小的感受野(局部区域),但通过堆叠多个 3x3 卷积层,感受野可以逐渐增大,同时保持更多的细节信息。
- 例如,第一个 3x3 卷积层可以捕捉到图像中非常细微的局部特征(比如边缘、纹理等),而第二个 3x3 卷积层则可以基于第一个层的输出进行进一步的特征抽象和组合。
总结:
- 多个 3x3 卷积核代替一个大卷积核的做法,结合了减少计算量、增加非线性、提升特征表达能力的优势。虽然每个 3x3 的卷积核捕捉的感受野较小,但通过层层堆叠,能够逐步获得大感受野的效果,同时提升模型的表达能力和泛化能力。这种做法使得 VGG 网络能够在相对较少的计算资源下,获得较高的准确性和较强的特征提取能力。
4.5 统计学中的残差和ResNets中的残差含义一样么?
首先我们先了解一下统计学中的误差和残差是什么:
- 简单来讲,误差是观察值与真实值之间的差。经典测验理论(CTT)的基本假设是:X=T+E。也就是说,观察值等于真值加上误差。我们的任何一次测量都带有误差(每一次测量的这个误差具体是多少是不清楚的,只有把所有测量结果进行分析后才知道误差有多大),经典测验理论认为误差是随机分布,且误差均值为0。因此,经过多次测验后,将观测值求平均就可以看作为真值。也就是说,多次测量求得的平均数是真值的最佳估计。
- 残差是观察值与模型估计值之间的差。以回归分析为例,回归方程y=b0+b1x,当知道b0和b1时这就是一个真实的回归模型。比如y=2+3x。取一个数值(1,2),则模型估计值为y=2+3×1=5。残差为2-5=-3。因此,只要有一个确定的取值以及模型,则模型肯定有一个估计值,也就有一个残差了。对残差进行分析是回归分析的一个重要部分。
1. 统计学中的残差
在传统的统计学回归分析中,残差定义为:
残差=观测值−模型预测值
即残差是模型预测值与实际观测值之间的差距。我们试图通过调整模型的参数来最小化残差,这样可以提高模型的拟合效果。
2. 在 ResNet 中的“残差”概念
在 ResNet 中,残差的概念来源于传统统计学中的残差,但它的含义有所变化,具体地说,在ResNet中,残差是指“输入”与“输出”之间的差距。
- 输入 是残差块的输入(假设为 x ),
- 输出 是经过一系列变换后的结果,通常是经过一层或多层卷积后的结果(假设为 y )。
而 残差 就是通过引入 跳跃连接,让网络学习 输入与输出之间的差异,即:
残差=输出−输入
也就是说,ResNet的核心思想是通过学习“输入与输出之间的差异”或“残差”来实现网络的优化,而不直接学习 从输入到输出的完整映射。
虽然 ResNet 中的残差不同于统计学中“观测值与预测值”的差距,但这个名字之所以被沿用,主要是因为它遵循了类似的思路:ResNet的残差块 不直接学习从输入到输出的映射,而是学习输入与输出之间的“差值”,即残差。这与统计学中最小化残差的目标有相似之处:都是通过学习差值来提高模型的拟合能力。
4.6 机器学习中训练样本的标签是真实值还是观测值?(待解决)
以下皆为个人理解,如果有异议,欢迎在评论区交流。
真实值的含义:即理想的、理论上的真实值(通常是无法直接获得的),但一定存在,可能只有上帝知道。
那么样本中标签大都是人为去打的(例如一个图片即使上面显示的是一只猫(至少是大多数人都这样认为),但它也有极小极小的概率是一个“长的像猫的狗”,因此真实值我们是不得而知的,我们打的标签是基于我们经验所做出的一个预测值)。
我们在训练模型时,往往通过缩小模型预测值与标签的差值来优化模型,按照残差的概念,我认为这块的优化目标是不断缩小残差,而非误差,毕竟误差是无法测量的。
但我的想法似乎和主流想法(或者说正确想法)相悖,我无法理解正确想法,但我认可下面这句话:
如果模型正确,可以将残差看作误差的观测值。
4.7 深度学习中对图片数据集扩充,是先对整个数据集增强再划分训练、验证和测试集,还是先划分再仅对训练集扩充?
在深度学习中,正确的做法是先划分数据集,再对训练集进行数据扩充。具体流程如下:
-
划分数据集:首先将整个数据集划分为训练集、验证集和测试集。这个过程的目的是确保每个子集中的数据具有代表性,并且不同子集之间不会有重叠。
-
数据扩充:一般情况下数据扩充只应用于训练集。对训练集进行扩充时,实际上是通过各种变换(如旋转、翻转、裁剪、颜色变换等)生成新的训练样本,从而提高模型的泛化能力。
-
注:如果你想提高模型预测效果,可以采用10-crop方式(Multi-crop at test time)。
-
验证集和测试集:验证集和测试集不进行数据扩充,它们应保持原始数据集的分布和内容。扩充验证集或测试集会改变其数据分布,从而影响模型评估的真实性。
你可能会问为什么不能“先增强再划分”呢?
原因是这会导致测试集被污染: 如果你先对整个数据集进行增强,那么增强过程中产生的图像可能会被用作训练集、验证集或者测试集的一部分。这样,测试集中的一些样本会与训练数据集中的样本相似(因为它们经过了相同的增强操作)。这就导致模型“已经见过”测试集的某些样本,使得模型的评估结果不再真实可靠。
也就是1个样本A被增强后得到B,后续在划分时B被划入训练集,A被划入测试集,由于两者非常相似,因此会导致测试集无法独立于训练集,受到了污染,影响模型泛化效果。
4.8 ResNet中一般是每隔多远用一个跳跃连接?
在 ResNet 中,跳跃连接通常是应用在 每个残差块内部,每个残差块中通常包含两个或三个卷积层。具体来说:
- ResNet-18/34:每个残差块有2个卷积层,跳跃连接位于这两个卷积层之间。
- ResNet-50/101/152:每个瓶颈块有3个卷积层,跳跃连接跨越这三个卷积层。
4.9 如何直观理解这两个代价函数的关注点?为啥内容代价函数是激活值相近?风格代价函数是通道之间相关性?
- 内容代价函数像是在临摹画的“内容”,确保画面中的物体形状和原画一致。
- 激活值相近,意味着在特定层提取到的特征是相似的。比如在深层卷积层中,如果内容图像和生成图像的激活值接近,说明它们提取出的物体形状和结构相似,生成图像就像内容图像。
- 风格代价函数像是在模仿画的“风格”,确保画出来的东西有类似的笔触、纹理和颜色搭配。
- 如果在风格图像中,垂直纹理和蓝色区域经常一起出现(相关性高),那么在生成图像中也应该有类似的情况。
- Gram矩阵通过计算不同通道之间的内积,捕捉了这些通道的相关性。相关性高说明这些特征在图片中经常一起出现,而相关性低则说明这些特征在图片中较少同时出现。