深度学习CNN提升性能的方法总结

深度学习CNN提升性能的方法总结

最近阅读了几篇经典的CNN论文,发现作者在训练一些模型的过程中使用了一些共通的方法来增加网络的性能,并且在ImageNet等相关数据集上得到了明显的性能提升,下面按照CNN模型成长的轨迹来总结一些可以用在平常我们自己训练深度网络模型中的技术。这里只是做一个各种方法的总结和简述,并不会很详细的说明怎么去实现和一些数学推导,如果有需要的可以看我后面的博客或者是其他CSDN大神们的讲解

一、在训练模型时先训练一个比较浅层的网络,之后用这个网络的参数来初始化后面训练的更深层的网络。

在VGG的论文中,作者在论文中没有着重强调他们用先训练的浅层网络训练深层网络的事情,只是在文中提了一下(we initialised the first four convolutional layers and the last three fullyconnected layers with the layers of net A (the intermediate layers were initialised randomly).)其实如果在实验中,如果没有按照作者的方法做,直接从头用那个十九层的网络结构去训练的话很难训练出和作者一样好的模型,因为这里隐藏了一个degradation problem问题(这个问题的解决办法后面详细表述)。下面将VGG中提到的一些技术详细说明

  1. go deeper and deeper if you have data
    大部分做深度学习的学者或者是工程师都在试图在增加自己的网络的深度,在数据集足够大的前提下,让自己的网络变得更深,往往效果变得更好,但如果你没有足够的数据来训练你的网络,那就会有很严重的overfeeting问题。导致网络性能变差。
  2. dropdout
    解决overfeeting的常用方法,基本原理是在训练的时候随机的锁定一定比例的神经元,让每一次反向传播智能调整网络的一部分参数,同样的,这种方式也间接的等于针对一个问题,训练了很多个不同的网络(因为每次只训练的参数的一部分,所以相当于训练了总神经元个数的排列组合个共享参数的神经网路)在测试时激活所有的神经元,相当于用多个网络共同来进行预测并取平均结果,这样可以有效的减少过拟合问题。
  3. 通过一些图像处理的办法来增加数据集(数据增强)
    这种方法从信息的角度上来讲这种方法不回给网络提供新的信息,但可以减少过拟合现象。笔者认为应该理解为可以让网络更好的接受数据集的信息。具体的方法有:
    翻转图片、旋转图片、缩放图片、裁剪图片、平移图片、给图像加入高斯白噪声、对图像做一定的裁剪
    同时还有一些高级的方法,比如一些用GAN来增强数据的方法这里不做详细探讨。
  4. per-pixel mean subtracted 输入图像减去均值
    对每个输入的图片减去像素的平均值。这个方法很多文章都有使用,在一些传统的图像处理方法中也使用,笔者的理解应当是零频分量中不含什么有用信息。
  5. L2 penalty multiplier
  6. learnrate 和validation的结果是关联的,当validation不再提升的时候下降
    这里就有关于learningrate的决策机制了,所有learningrate的机制都是最开始训练的时候大一些,到最后小一些,这个是符合人的经验的,在雕刻一个人像的时候,一块材料先粗犷的消减成一个人的样子,然后再精雕细琢,最后抛光什么的。在训练网络的时候也同样,最初网络距理想的局部最优解比较远。所以更大的learningrate有助于网络更快的接近局部最优点,在更近的时候比较小的learningrate可以有助于更好的接近,而不是在最优点之间震荡。
    相似的learningrate决策机制还有很多,比如一个比较常用的是让学习率以指数函数的方式下降等等。
  7. 随机从训练集中提取数据
    对输入顺序进行随机化处理是为了保证能够有监督学习,同时使算法按照梯度下降法则进行学习。假如训练数据是有序的,那么会导致训练结果很难收敛到偏置值。只有保证数据的随机性才能使得BP算法训练结果尽可能地收敛。
  8. 随机输入图片尺寸(在Smax与Smin之间)
    在VGG的论文中实验证明了在一定范围内随机控制输入图片尺寸(即每次输入神经网路训练图片的大小都是随机的)可以有效提升网络的识别率,这里和上面通过旋转等方式增加数据集的思想应该是一样的,通过随机控制图像尺寸,让神经网络对图片的大小、旋转等特征不敏感,从而学习到鲁棒性更强的特征。
  9. 在定输入尺寸的训练中,可以先用小尺寸,训练完了用小尺寸的网络参数初始化大尺寸的,但在论文当中,还是随机图像尺寸表现好
  10. 两种测试方法
    方法1: multi-crop,即对图像进行多样本的随机裁剪,然后通过网络预测每一个样本的结构,最终对所有结果平均
    方法2: densely, 利用FCN的思想,将原图直接送到网络进行预测,将最后的全连接层改为1x1的卷积,这样最后可以得出一个预测的score map,再对结果求平均
  11. 在卷积层的最后一层加入11的卷积核,可以提高系统的非线性性能
    这个方法在许多CNN的论文中都提到了,1
    1的卷积核可以有效的提升网络的非线性性能,同时在ResNet中还利用了这种卷积核来作为数据的一种通路,在下面会详细说明。

二、ResNet极深神经网络

一些上面提到过了的方法这里就不再重复了,这篇文章的核心是提出并解决了 degradation problem(在增大网络规模的时候,有的时候增大了网络但效果变差了,这种情况有的时候是overfitting但有的时候不是)同时提出一种可以高效(不用占用太多资源)的更深层的网络构建方法。
思路是对比VGG先训练一个浅层的网络,之后用这个参数去初始化更深层的网络。也就暗示着更深的layer的网络的性能至少不能比浅层网络的性能差,才能更好的构成网络。
另一个设计思路是在训练过程当中,我们并不知道一个面对一个问题应该用多大多深的网络来进行训练。如果前面的N层已经足够好了,那再这之后的这些层就没必要了,只是直接把前面的结果送到后面就可以,不需要做太多的工作。但传统的layer H(x)都是非线性的,把一个或多个非线性的层训练成一个线性的"单位化"的层是非常困难的,但如果加一个旁路把 H(x)改成F(x)+x【x是上一层的输入,F是本层的W和b对x的处理。实际上就是多加一条从输入到输出的旁路】。这样当不需要这么多层的时候只要把F的参数都训练成0就成了。
深度学习CNN提升性能的方法总结_第1张图片

这种旁路的形成有两种方式,一种直接用加法加上,如果前后矩阵大小不一样,就补零。另一种是WX(即乘个矩阵),然后再加到本层的输出上。这种可以应对大小问题(直接用11卷积核)。全部用11卷积核做通路可以有效的增加网络效果. 。
同时通过多个旁路,可以把input送到每一层,这样的效果和用浅层网络初始化深层网络一样。同时如果是带参数的旁路,随着参数再训练中的改变,前面可能旁路参数会很大,方便初始化,随着训练参数变小,等于再训练中一点点的变深。从一个并联网络编程了串联深层网络。

三、deep不仅仅是增加网络深度,同样可以增加网络的宽度

GoogleLeNet是一个非常成功的模型,再很多tansferlearning的问题种都用到了已经训练好了的GoogleLeNet来作为迁移的源域。下面叙述一些GoogleLeNet的思路,再最开始不知道怎么构建更有效的网络的时候。不妨可以尝试一下直接用GoogleLeNet 来做finetuning,可能会有不错的收获
going deeper 不仅仅是深度方向,同时还有宽度。感觉应该是going huger。宽度通过并联多个不同尺寸的卷积核和pooling来实现。
提出了构建更有效的网络的思想,有一个方法可以通过已经训练好了的网络,逐层重新设计稀疏的网络的方式(实际应用成本太高),通过类似思想,设计尽可能逼近稀疏的网络。(网络中的神经元在接近0的时候会出现死掉的情况,再怎么训练也很难增大(反向传播算法是要inputw再乘以反过来算的那个系数的)所以会有神经元没有作用,却占用了内存和计算资源的情况。所以要构建组有稀疏的网络。 )但又说了因为现在的计算性能的提升,尽可能的构建稀疏的网络是不值当的,模型有点浪费也可以接受。

深度学习CNN提升性能的方法总结_第2张图片

你可能感兴趣的:(deeplearning)