P2.1为什么要进行实例探究
就是列了一下提纲,告诉我们我会讲这些内容,可能尽管你不是搞图像方向的,但是你可以借鉴里面的一些重要思想啊!
P2.2经典网络
第一个是1980年的LeNet-5,其中有几个注意点:
- 当时是没有用ReLU的,用的是sigmod跟tanh作为非线性激活函数;
- 网络的模式沿用至今:也就是(卷积+池化)+····+(卷积+池化)+全连接1+···+全连接n+输出;
- 可以发现随着深度增加图像的长宽变小,但是通道数确实增加的;
- 当时这个网咯的参数仅仅60K的样子,现如今可是百万级了啊!
- 看论文的时候先看下第二节讲的是系统架构,然后第三章有实验结果,have fun!
第二个是AlexNet,由于是Alex最先发现的所以以之命名,其特点如下:
- 卷积核很大,stride也大;
- 参数很多60 millions(远大于LeNet-5的60K);
- 使用了ReLU非线性函数;
- 当时计算能力问题,曾设计把网络给2个GPU进行计算,论文中有对如何分配、GPU之间如何通信都有一定的论述(这个部分就很工程了);
-
论文里提到的local response normalizations实际中验证效果并不好,未有沿用。
图片.png
第三个是VGG-16,一句话总结的话就是它使得网络的结构变简洁了。
- 使用的卷积核总是3*3的,stride总是为1,图像保持为same(加padding);
- 最大池化总为2*2,stride=2不变,
- VGG-16的16是指有16层,同理VGG-19就是19层,同样有对应论文的,但性能跟16层差不多,所以使用VGG-16的人偏多;
- 138millions的参数;
- 通过pooling来减少图片尺寸;
-
作者认为通过double卷积核数量可以更好的描述图片,同时到达512个卷积核已是最多了。
P2.3 残差网络
讲到了深度神经网络会有各种问题,比如梯度消失啊梯度爆炸啊什么的!
之前有说到了,由于sigmod激活函数的非线性会导致梯度消失或者爆炸;而是会消失还是会爆炸,这由激活函数跟权值一起决定,因此这里就算将激活函数改为ReLU但是也还是存在梯度消失或者爆炸的问题的,因此残差网络的出现对网络深度地拓展具有重要意义。
残差网络的架构如下图所示,本来的深度模型就是输入然后经过:[线性操作(linear) + 激活函数(ReLU)]的叠加来构成深度,这样子很容易发生梯度的问题,原因上面也讲了。
然后我们的残差网络结构基本原理就是:把前面层的输出直接短接到后面层那里去,需要注意的就是:插入的位置是在线性激活之后跟ReLU激活之前,如图所示。
看到作者何凯明把这种接法叫short cut,还有种叫法是skip connection,其实这也好理解,你既然把信息传递到后面层,那么我很自然地想“我萌能不能把信息传到后面的不同层呢?因为我们也不知道具体传到哪层合适嘛!!!”
一般的残差网络如下图所示:这里有5块,每块叫做残差块,这五块叠加起来构成了残差网咯。
那你这个效果如何呢?
下图表示的是:常规的深度网络,也就是plain,理论上是那条绿色的theory曲线,然而实际上却是蓝色那条reality曲线,这说明深度网络中的机理我们了解的还并不是特别清楚,某种程度上来说还是个黑盒子;
而我们的ResNet网络表现出来的效果却是跟理论曲线是相近的,也就是说残缺信息(层间信息)是深度网络的一个重要特性啊!
P2.4 为什么残缺网络表现如此之好?
从图中可知,假设输入x经过一个big NN大型网络之后输出a[l],那么我们再在后面给他加上两层网络,而且这两层通过加上short cut线来构成残缺网络,因此(假设非线性激活函数数ReLU,也就是说激活输出的值全部都是大于等于0的)从这往上数第三张图写出了残差网络的激活函数,于是有:
a[l+2] = g(z[l+2] + a[l]) = g(w[l+2]*a[l+1] + b[l+2] + a[l]) **
往我们对W或者b进行L2正则化就可以使得其均取值为0,这样子的话,如图所示最后的结果就是a[l],也就是说这个网络直接就去掉了,这可是在深度增加的情况下,却不增加计算量的啊!,其实这里就是在学习一个恒等函数啊,也就是一个自编码器啊!
这也就是为什么常规的深度学习网络在一定程度上学习着学习着效果反而不好了!因为他们学恒等函数很难啊!?
保证网络功能(恒等函数)的前提下提高效率(恒等函数参数为0,即减少参数)!
残差网络的卷积操作是same操作,维度不同的话是需要变维度的!
有个细节就是,ResNet(下图中)中的3*3卷积都是same的,因此才有Z[l+2] + a[l]是同维度的。conv、pool、softmax这些都是有的。
P2.5 1*1卷积核的作用?(网络中的网络)
这玩意儿是啥?
-
1*1的卷积核作用在一个通道(深度)为1的输入,表现出来的就是单单把这个通道做一些线性放大缩小的作用,没啥意义;
-
但是放到通道为32的输入时,效果就不一样了,我们直观的理解就是不同通道的统一位置都会经历一个缩放效果,直观感受就是加强或者弱化某些通道的输出。
-
这个叫做network in network
这玩意的作用是啥?
- 如下图所示,这玩意能在通道上降维(我们知道图片大小的降维是通过pooling来实现的);
- 我们的图片是28*28*192的,我们的卷积核是1*1*192的,因此选择n个卷积核就输出多大的通道,这里选的是32通道,也就是最终实现通道降维的效果;
-
ps. 我们这里图片大小是木有降维的哈!因为1*1啊!!!
P2.6 inception network(谷歌) motivation
-
大概意思是我们选择卷积核大小的时候可以选择多种大小的共同使用,如1*3、3*3、3*5啊啥的!
-
网络的核心思想是:我们不去人工指定定卷积核的类型,也不去人工组合它们来使用,而是全部拿出来,甚至是直接max-pooling,让网络自动去学习最优的组合参数,哪些卷积核是重要的,然后训练出参数来。
-
注意的是:输入是192个通道,卷积核大于1*1的记得是same(记得加padding),然后将输出叠加起来构成输出的通道。
硬伤是啥?
-
计算量是硬伤啊!,这仅取其中一小部分,就5*5卷积核这个,28*28的图片大小,要对应32个卷积核;每个卷积核大小是5*5,然后对应的深度是192,因此全部乘起来就是120millions的计算量啊!这可是12亿了啊!注意,这还只是一小部分啊!
我们加入1*1卷积核之后的计算量看看好多少!
- 下图中有2个要点,其一则解释了为啥1*1卷积核叫做bottleneck layer,因为这玩意跟瓶子的脖子真的是长一模一样啊!
话说瓶颈的作用是啥?是限制流量吧!放置一次性倒出太多,而我们这里则是限制计算量的啊!计算量即流量,限制一下流出来少点!
- 这里算了一下计算量大概是12millions左右,是之前的整整十分之一啊!这效率杠杠的!
思考:为什么不直接用32个1*1的卷积核得到28*28*32的输出?我个人理解是,1*1主要的作用不是提取特征,而是进行计算量压缩的,因此必须要有个大一点的卷积核来提取特征啊!
小结:inception module:当你不想自己去选择那些个卷积核类型合适的时候,say: let's do them all. and let's concatenate the results.
P2.7 inception网络
inception模块构成如下图所示,将前面激活函数的输出,再组合出一些卷积核进行输出,将这些输出叠起来就是输出啦!是按通道这个维度叠起来哟~
这个才是论文中描述的整个网络结构,单单就其中某个block来说的话就是上面那个!
- 中间有些池化层,是为了调整维度的;
- 中间有两路支路,也是softmax直接输出的,这个是用来做预测的,放置过拟合,个人认为是硬件电路里面的测试点吧!
- 该网络是谷歌的输出,叫googleLeNet是对LeNet的致敬。
总结:
- Inception:注意是大写开头,这个是官方引用的电影梗!“我们需要进入更深层次!”
- 版本更新成V2、V3、V4,还有个甚至是跳跃连接,效果不错!
P2.8 我们不要自己重复造轮子!
用好github网站!
P2.9 迁移学习
- 用别人训练好的模型,来作为我们模型的预训练部分,这相对于随机初始化来说能更快收敛!
- 数据集有ImageNet、MS COCO、pascal
问题:我们目标都不一样的话还能随便用别人的模型嘛?怎么使别人的模型适应我们的任务?具体细节是什么?
-
比如要识别猫,如下图所示,我们我识别这两个动物是不是猫,有三种可能,Tigger是,misty是或者两个都不是,因此softmax输出三个值;
-
第一步我们先从github上下载代码,最重要的是记得下载权值;
-
第二步就是去掉他们的softmax函数,然后加上自己的!这个时候把别人的网络给冻结起来不训练,而是只训练我们自己的softmax就好!这样子的话可以实现用少量的数据样本就可以获得很好的效果;
-
不同的框架有不同的冻结方式,比如有的就是设置freeze = 1还有的就是trainableParameter = 0等等此类!
-
由于别人这个网络就是一个固定的函数了嘛!一个预训练的操作就是把图片提前经过这个函数,得到的是这个网络输出的特征嘛!我们把这个特征给存起来到硬盘,那么我们是不是只需要训练我们自己的softmax函数就好了呀!这样子能大大提高训练效率的啊!
-
这里说道,假如你的数据集很小,你可以把整个网络冻结来训练;但是假如你的数据集中等,那么就不要浪费了,因为我们可以训练出更有针对性的特诊啊!因此,我们一般在中等数据集时只冻结前面的浅层特征部分,后面复杂特诊部分你都要去训练,用别人已有的结构也好,或者你自己构建的结构也好,总之,不要把中等数据集里面的信息量给浪费了!
-
大数据集的时候,别人网络的所有层都要去训练哟!用别人的框架来训练自己的目标!更有针对性!
P2.10 数据扩充(数据增强)
第一种:
- 镜像
- 随机截取部分图像
-
旋转、剪切、局部扭曲····(操作麻烦,实际中使用较少)
第二种:
- 色彩转换:就是把RGB的值分别添加一个失真值,实际中这个失真值是基于某种分布的(比如是对某些场景的覆盖)!
这个其实不就是写测试用例么?!用来测试我们模型的!
PCA颜色增强(Alexnet论文中有):就是分析发现R、G的颜色占得比重多一点,B少一点,那么我就把R、G调少多一点,B调少少一点,最终达到均衡,很容易理解的。
数据生成的软件流程如下所示:开一个线程专门做数据产生的,从硬盘读数据然后构造出我们要的数据(mini batch),然后送给其他线程或者GPU去执行训练操作。
总结:图像颜色失真大小、分布等这些是超参数,随机剪切大小、模式也是超参数,这些是需要我们人为根据实际场景来设计的,因此,具体场景具体分析吧!童鞋们!
P2.11计算机视觉现状
数据量和手工工程的关系:
数据量少的时候我们需要人工构建特征,数据量大(当然在机器视觉领域我们从来不认为数据量是足够的)的时候就构建复杂的网络架构来实现任务;
-
当我们有很多数据的时候,就不会花时间去建立手工特征,而是花时间去建立学习系统;
-
当我们拥有较少数据的时候,一般做法就是人工构建很多很复杂的特怔或者叫做“超参数”,但是其实还是有种学习系统是可以借用的,比如上面说到的迁移学习:即用别人的模型来训练你的模型,而本质上则是利用==相似数据==来加速及提高你的学习系统
发论文的算法都是在一个标准测试集上的表现,并不是在真实的生产环境中产生;
其中他们用到的一些小tips如下:
集成Ensembling:
- 构建好几个神经网络模型,然后把输出加权平均,这会使得你在基准上的提高1%~2%的精度;但是,由于计算量也加大了好几倍,因此这种只适合在竞赛中使用,生产中使用就是浪费了啊!
多剪切:
- 就是把一张图片进行镜像之后,然后区域性剪切成小图片,然后送入模型进行训练,也就是扩充数据集啊!
- 10-corp法:把图片镜像为两张图,然后第一张取中心区域,然后基于此中心区域再次进行取左上角、左下角、右上角、右下角四个区域,因此一张图最后得到5张剪切图;镜像的那张也类似,总共十张图,因此叫10-crop。将之送进模型进行训练,并将十个输出结果平均来作为最终的结果。
使用开源代码:
- 使用论文中的网络架构;
- 应当学习开源的模型框架,使用他们的代码,因为他们已经把如学习率这样的超参数调好了,繁琐的工作都帮你做好了!
- 使用别人已经训练好的模型,然后在你的数据集上进行精调,这可使得你的模型在应用程序中运行的更快。
总结
- 大量的计算机视觉架构的学习,并大致说了一下为啥有效;
- ···
网友评论