转载《Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)》学习笔记

参考旷世科技魏秀参的博客:http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html
仅供个人学习,如有侵权,请私聊)

沉下心来学习

1、数据增强

  1. 有许多数据扩充的方法,例如水平翻转,随机裁剪和颜色抖动。另外还可以将多种不同的方式组合,例如,同时进行旋转和随机缩放。还可以对图像的色调(H),饱和度(S)和明度(V)进行变换,比如加减一个值,乘以某个系数。
  2. Fancy PCA改变了训练图像中RGB通道的强度。通过求得每个像素点的协方差矩阵(3*3),从而求得特征值和特征向量,然后在对特征值进行一部分的波动,求出一个新的协方差矩阵,在加到原本的像素上,从而实现一种滤镜的效果。这种方法同样也可以产生大量的新样本

2、预处理

  1. 第一种简单的预处理方法是将数据归零,然后进行归一化。可以采用如下python语句实现。
X -= np.mean(X, axis = 0) # zero-center
X /= np.std(X, axis = 0) # normalize

   
   
  • 1
  • 2

  这样每个输入X被限制为-1到1之间。对于图像来说,像素的相对比例已经大致相等(范围从0到255),因此没有必要执行这个额外的预处理步骤。

  1. PCA Whitening(白化),前者通过抛弃携带信息较少的维度对数据进行降维,后者由于图像中相邻像素之间具有很强的相关性,训练输入是冗余的,白化的目的就是降低输入的冗余信息,换句话说通过白化使得输入具有:1)特征之间相关性较低;2)所以特征具有相同的方差。
      首先中心化,再求协方差,然后通过将原始(但以零为中心的)数据投影到特征基中,可以对数据进行重新关联。最后一步是白化,它取特征基中的数据,将每个维数除以特征值,对尺度进行归一化。
X -= np.mean(X, axis = 0) # zero-center
cov = np.dot(X.T, X) / X.shape[0] # compute the covariance matrix

U,S,V = np.linalg.svd(cov) # compute the SVD factorization of the data covariance matrix
Xrot = np.dot(X, U) # decorrelate the data

Xwhite = Xrot / np.sqrt(S + 1e-5) # divide by the eigenvalues (which are square roots of the singular values)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

  这些方法在CNN中不使用,但是zero-center数据还是十分重要,而且对每个像素点归一化还是很常见的。

3、初始化

  1. 所有零初始化
      让一半为正一半为负
  2. 小的随机数初始化
      比如权重w~0.001 x N(0,1),N(0,1)是零均值,标准差高斯函数。也可以是来自均匀分布的一个很小的数字,但是这在实践中对最终性能影响较小。
  3. 校准方差
      随着输入数量的增长,来自于随机初始化神经元的输出有方差,可以通过除以平方根来缩放使每个神经元归一化到1。
    w = np.random.randn(n) / sqrt(n) # calibrating the variances with 1/sqrt(n)
  4. 当前建议
      上述初始化不适用于relu,可以使用如下2.0/n的方法:
    w = np.random.randn(n) * sqrt(2.0/n) # current recommendation

4、训练中

  1. 滤波器和池化尺寸:训练中,输入图像尺寸最好为2的指数,比如32,64,224,384或512。另外,使用没有填充的小滤波器(3x3)和小步长(1),不仅减少参数量,而且提高整个网络的精度,池化层使用2x2的尺寸。
  2. 学习率:如果改变batch-size,不要总是改变学习率。使用验证集特别有用,通常出初始学习率为0.1,验证集中,如果没有进展,将学习率除以2或5,会有惊喜。
  3. 预训练模型:如有有很少的数据,可以从预训练模型的顶层提取特征来训练一个线性分类器。然而,如果您自己的数据集是完全不同于预训练模型中使用的数据但有足够的训练图片,大量的层应该调整窃用小的学习速率,以提升性能。如果你的数量很少且不同于预训练模型使用的数据,会遇到问题。在早期的网络训练SVM分类器会效果更好。
    在这里插入图片描述

5、激活函数

  神经网络中一个关键因素就是激活函数,它将非线性带入到网络中。例如Sigmoid、tanh(x)、Rectified Linear Unit、Leaky ReLU、Parametric ReLU、Randomized ReLU等。relu可以减少梯度爆炸和消失的情况,对于Leaky ReLU,小的 α α α αα \alpha w2<c来强制约束。c的典型值是3或4的顺序。即使学习率设置的太高,网络也不会爆炸,因为更新总是有限制的。

  • dropout:是一种十分有限简单的正则化方法,弥补了其他方法(上述三种),dropout可以解释为在整个神经网络中对一个神经网络进行采样,并且只能根据输入数据更新采样网络的参数。然而,可能被采样网络的指数不是独立的,因为他们参数共享。在测试阶段不使用dropout,解释了评估所有子网络指数级集合的平均预测。实践中,dropout设置为0.5,但是可以根据验证集调整。
  • 7、从数字从观察

    可以画一些数据表明网络的训练效果
    在这里插入图片描述在这里插入图片描述
    如果损失曲线的趋势看起来太线性,表明你的学习速率较低;如果没有减少太多,说明学习率可能太高。另外,“狂赌”和batch size有关。如果“宽度”看起来太宽,也就是说每批处理之间的差异太大,指出应该增加批量大小。
    在这里插入图片描述
    红线表示训练精度,绿线表示验证集的。当验证准确性收敛,红线和绿线之间的差距将会显示你的深层网络的有效性,如果差距变大,表明网络在训练数据获得很好的精度,而在验证集精度低,很明显说明模型过拟合。因此,应该增加网络正则化的强度。但是,没有差距且低精度,这显示了深度模型的学习能力低。在这种情况下,为了获得更好的结果最好是增加模型的能力。

    8、集成

    下面介绍一个深度学习场景中的集成技巧

    1. 相同模型,不同初始化:使用交叉验证确定最佳超参数,然后使用最佳超参数集训练多个模型,但使用不同的随机初始化。这种方法的危险之处在于初始化的多变性。
    2. 交叉验证期间发现的顶级模型:使用交叉验证确定最好的超参数,然后集成top k的模型。这提高了集成的多样性,但包括次模型的危险。在实践中,这可能更容易执行,因为交叉验证后不需要对模型进行额外的再训练。通常可以在 Caffe Model Zoo中选择性能最好的网络来集成。
    3. 单模型的不同检测点:如果训练成本很高,有些人在一个网络的不同检查点随着时间的推移而取得的成功是有限的,他们用这些检查点来集成。显然,这由于缺乏多样性,但是在实践中很有用。这种方法的好处在于成本低。
    4. 一些实际的例子:如果是做高层语义的视觉任务,一种更好的集成方法是使用多个在不同数据源上训练的深层模型来提取不同、互补的深层表征。

    Miscellaneous(混合的)

    当数据类别不平衡时,最简单的方法通过直接对不平衡的数据进行上采样和降采样来平衡训练数据,具体参考这里。另一种方法是一种在特别的裁剪流程这里,从训练集数量较少的类别中进行裁剪,一方面可以提供多种不同的数据源,一方面可以解决类别不平衡的问题。此外,还可以调整微调策略来客服类别失衡。例如,您可以将自己的数据集分为两部分:一部分包含具有大量训练样本(图像/裁剪)的类;另一部分包含有限数量样本的类。对于每个部分,类别失衡问题不会那么严重。在对数据集进行微调开始时,首先对具有大量训练样本(图像/作物)的类进行微调,然后继续微调,但对样本数量有限的类进行微调。

            </div>
    

    猜你喜欢

    转载自blog.csdn.net/m0_37192554/article/details/88167696
    今日推荐