这是吴恩达老师的第二部分视频的学习笔记
1 概述问题
1.1带着这样的问题来看笔记
- 传统的卷积神经网络的构成
- 残差网络和普通网络的区别
- 1 x 1卷积的作用
1. 2上面问题的答案
- 传统的CNN网络由卷积层、池化层、全连接层和判别层softmax层组成。
- 残差网络中有残差块的概念,残差块就是shorcut connection包含的那些层。
- 1 x 1卷积相当于是将同一位置的多个信道元素加权相加之和通过一个非线性函数,增加其非线性能力。1 x 1信道可以实现压缩或者增加信道且不改变长宽值。在Inception网络中,1 x 1网络还可以通过构建瓶颈层来减小计算量。
2.1 概述
大致讲解了在神经网络的发展历史上,出现过lenet,alexnet,VGG,ResNet,Inception这些网络。我们在实现自己的网络架构的时候,尽量不要瞎想,而是要参考前人的网络架构。
2.2 历史回顾
首先介绍了LeNet的网络架构。当时使用了averge_pooling,现在更常使用的是max_pooling。当时使用的非线性函数主要是sigmoid和tanh以及relu,现在使用softmax也比较多(这里不是很确定)。当时的计算机计算速度并没有很快,因此在Lenet的论文中提到了很多精妙的优化速度的手段,但是现在基本不用了。因此再读那篇论文的时候,应该精读第二部分,泛泛的读第三部分即可。
AlexNet的网络结构如下图所示,和lenet类似,但是这里的参数数量有6000万之多。AlexNet的性能要比LeNet好,原因是这里使用了更多的参数更加复杂的网络,同时使用了ReLu作为激活函数。在Alexnet的论文中,还提到了Local Response Normalization,这个操作的含义是将贯穿不同信道同一位置的节点们归一化处理,据原论文说这样可以减少高激活神经元,但是后来的研究发现这样做并没有什么特别大的好处。
VGG网络优秀的在于真正简化了神经网络的结构,虽然VGG-16有16层,还是比较深的网络,参数也有13600万之多。但是这个网络优美的表现出了“长宽缩减的比例和信道增加的比列”相关的信念。在这个网络中,始终使用3*3的filter,每次使用same conv的模式;输入每经过一轮(一轮可能是2-3个卷积层)过滤器,channel数量增加一倍。池化层始终使用max pooling,且每经过一次池化层,长宽缩小一半。最后使用了两个全连接层和一个最终输出层。
吴恩达老师推荐我们看论文的顺序是先AlexNet,然后VGG,最后LeNet。LeNet的内容比较晦涩难懂。
1.3&1.4 残差网络
普通的神经网络,随着网络的深度增加会存在梯度爆炸和梯度消失等问题,变得越来越难以训练。残差网络的提出使得训练深度网络变得更加容易。他的原理是在某一层的线性模块之后,非线性模块之前增加前面某曾的输出,(这种操作又被称为skip connection),使得该层的非线性层a^(l+1) =g(z^l +a^(l-n)).这样的n个块被称为一个残差块。如下图所示的网络中一共有5个残差块。
网络只有在训练集上训练好才能在hold-out 交叉验证集上效果好。从经验来看,传统的网络存在随着深度的加深,学习的效率会逐步下降的缺点。但是对于残差网络来说,增加两层之后的恒等函数很容易学习。参考阅读这篇博客,暂时还没有看懂,希望下次巩固的时候可以看懂。
一般情况下,a^(l+2) 和 a^l 的维度是一致的,因为残差网络中一般使用same的卷积,偶尔会使用池化层。当a^(l+2) 和 a^l 的维度不一致时(池化层),可在a^l前面乘以一个W矩阵,保持维度的一致性。
1.5 1 * 1卷积(network in network)
1 * 1卷积对于单信道输入来说,只是将对应位置乘以对应的值而已。但是对于多信道输入而言,一个1 * 1卷积过滤器相当于将同一位置多个信道的元素加权相加,相当于一个全连接操作,之后会通过一个非线性函数操作,也就是相当于组合了同一位置的所有信道的元素,使其增加了非线性能力。
当输入的信道数量太多时,可以通过1 * 1卷积进行压缩信道(当然也可以增加信道,通过控制过滤器的数量),并且不改变height和weight(改变这两个参数的方式是池化层).这个1 * 1卷积的思想对于Inception网络很有用。
1.6 Inception网络——Inception的思想、1 * 1卷积在其中的作用、Inception网络框架
Inception网络可以让我们避免自己去人工构建卷积层或者池化层。而是自己去学习到底使用什么卷积层或者是池化层。
其实现的原理就是把1 * 1卷积、3 * 3卷积、5 * 5卷积以及池化层的结果都叠加在一起共同作为这一层的输出,然后让网络自行去学习参数。(注意思考为什么图中的最大池化层的输出channel数量是32?我还没有理解,按理来说池化层的输出channel数量应该保持不变才对)
可以想象,这样的网络计算成本非常大 。以其中一个 5 * 5卷积来说。为了构建一个 28 * 28 *32的输出层,需要进行的乘法操作如下:对于每个输出的元素都需要进行 5 * 5 *192的乘法操作。这样的乘法操作数量达到了120Million次。
因此Inception使用1 * 1卷积构建一个瓶颈层来减少计算量(可以将计算量减小为曾经的十分之一)。通过合理的构建一个中间层。
通过上面提到的两个思想,可以构建Inception模块。Inception模块中既使用了 1 * 1卷积构建瓶颈层来减小计算量,又使用了多种卷积方式让其自我学习。
注意到最后的池化层实际上是一个池化层加上一个1 * 1的卷积层来控制channel数量的。
一个Inception网络就是由众多Inception模块构成的。其中的红色模块是池化层,用于减少长宽。底部有一些分支,这些分支实际上是使用隐藏层来做全连接、最后实现softmax预测。这意味着即使是中间的隐藏层也可以做预测,这些模块起到了一个调整的作用,避免整个网络过拟合。
上面这张图也被称为Googlenet,为了致敬LeNet网络。
1.7迁移学习
自己训练网络是一件耗时耗CPU的痛苦的经历。github上有很多公共的神经网络代码以及设计好的网络架构和权重,我们可以利用这些网络来初始化我们的专用需求。
当我们自己只有少量的数据时,我们可以固定他人网络的所有隐藏层,只修改softmax层来适应自己的需求。为了减少计算量,来可以将自己的数据运行到softmax层之前的都保存起来当做input,只经过softmax,这样训练的速度就很快。
当我们的数据量不那么少的时候,可以固定前面的隐藏层,留下一两个隐藏层以及softmax层做训练。
当我们的数据量比较多的时候,可以将他人网络的权重作为初始值,然后训练整个网络。
一般的网络框架都会有可以固定前面隐藏层的参数的。
1.8 数据增强
计算机视觉神经网络面对的一个大问题是数据不充足。常见的数据增强的方式有
- 镜像变化、随机剪裁(效果不错),旋转,扭动
-
颜色偏移,一般对RGB三信道的数值按照某种分布做微小的调整得到不同的图片。这种变化是基于有时候光线的变化不应该对最终的标签有影响。这种变换可以增加对光线的鲁棒性。
当我们的数据量比较多的时候,通常会这样实现数据增强。使用一个或者多个线程来持续读取并转换数据(将数据通过不同的方式转换),构成一个batch的图片集合,然后输入另一个训练线程。图片增强和训练的过程可以并行执行。
数据增强的过程同样有很多的超参数,比如颜色变化的分布参数等。因此我们也可以使用别人的开源实现。
1.9 计算机视觉的发展现状
当我们在计算机视觉使用神经网络的时候,我们的目的有两个1. 参加比赛获得好的名次; 2.实际应用部署赚钱。
对于第一个目标,建议有两个:
- 使用emsembling的方式训练多个神经网络,最后平均得到输出。
- 使用n-crops的方式训练一个网络,但是数据集会有很多。
对于第二个目标的建议就是使用别人以后的网络作为初始化。因为别人可能把比较困难的痛苦细节都帮你完善好了。