训练深度神经网络的技巧和窍门

训练深度神经网络的技巧和窍门

训练深度神经网络很困难。它需要知识和经验才能正确地训练和获得最佳模型。在这篇文章中,我想分享我在深度神经网络训练中学到的知识。以下提示和技巧可能对您的研究有益,可以帮助您加速网络架构或参数搜索。

1)在开始构建网络体系结构之前,首先需要做的是,如果输入(x)对应于标签(y),则将输入数据验证到网络中。在密集预测的情况下,确保将ground-truth标签(y)正确编码为标签索引(或one-hot编码)。如果没有,训练将无效。

2)决定是使用预先训练的模型还是从头开始训练您的网络?

  • 如果问题域中的数据集与ImageNet数据集类似,请在此数据集上使用预训练模型。最广泛使用的预训练模型是VGG网络,ResNet,DenseNet或Xception等。有许多层结构,例如,VGG(19层和16层),ResNet(152,101,50层或更少),DenseNet( 201,169和121层)。注意:不要尝试通过使用更多层网来搜索超参数(例如VGG-19,ResNet-152或DenseNet-201层网,因为它的计算成本很高),而是使用更少的层网(例如VGG-16,ResNet-50)或DenseNet-121层)。选择一个您认为可以为您的超参数提供最佳性能(比如ResNet-50图层)预训练模型。获得最佳超参数后,只需选择相同但更多的网络层(例如ResNet-101或ResNet-152图层)以提高精度。
  • 如果您有一个小数据集,则微调几层或仅训练分类器,您还可以尝试在卷积层之后插入Dropout图,因为它可以帮助对抗网络中的过度拟合。
  • 如果您的数据集与ImageNet数据集不相似,您可以考虑从头开始构建和训练您的网络。

3)始终在网络中使用归一化层。如果您使用大批量(例如10个或更多)训练网络,请使用BatchNormalization层。否则,如果您使用小批量(例如1)进行训练,请改用InstanceNormalization层。请注意,BatchNormalization如果增加批量大小会提高性能,而当批量小时会降低性能。但是,如果InstanceNormalization使用较小的批量大小,则会略微提高性能。或者您也可以尝试GroupNormalization。

4)如果有两个或更多卷积层(比如说Li)对相同的输入(比如说F)进行操作,则在连接特征后使用SpatialDropout。由于这些卷积层是在相同的输入上操作的,因此输出特征可能是相关的。因此,SpatialDropout会删除这些相关特征并防止网络过度拟合。注意:它主要用于较低层而不是较高层。

训练深度神经网络的技巧和窍门

SpatialDropout用例

5)要确定您的网络容量,请尝试使用一小部分训练示例来填充您的网络(来自andrej karpathy的说明)。如果它没有过度配合,请增加网络容量。在它过度拟合之后,使用正则化技术,如L1,L2,Dropout或其他技术来对抗过度拟合。

6)另一种正则化技术是约束或约束您的网络权重。这也可以帮助防止网络中的梯度爆炸问题,因为权重始终是有界的。与您在损失函数中惩罚高权重的L2正则化相反,此约束直接调整您的权重。您可以在Keras中轻松设置权重约束,Python示例:

from keras.constraints import max_norm

# add to Dense layers

model.add(Dense(64, kernel_constraint=max_norm(2.)))

# or add to Conv layers

model.add(Conv2D(64, kernel_constraint=max_norm(2.)))

7)对数据的平均减法有时会带来非常糟糕的性能,尤其是从灰度图像中减去(我个人在前景分割领域遇到了这个问题)。

8)在训练前和训练期间,都要调整你的训练数据,以防你没有从时间数据中受益。这可能有助于提高您的网络性能。

9)如果您的问题域与密集预测相关(例如语义分割),我建议您使用Dilated Residual Networks作为预训练模型,因为它是为密集预测而优化的。

10)要捕获对象周围的上下文信息,请使用multi-scale 特征池化模块。这可以进一步帮助提高准确性,并且该想法成功地用于语义分割或前景分割。

11)从你的损失或准确性计算中(如果有的话)Opt-out void标签(或模糊区域)。这可以帮助你的人际网络对预测更有信心。

12)如果你有高度不平衡的数据问题,在训练期间应用类权重。换句话说,给稀有类更多的权重,但给主要类更少的权重。使用sklearn可以很容易地计算类权重。或者尝试使用OverSampling和UnderSampling技术重新采样训练集。这也有助于提高预测的准确性。

13)选择一个正确的优化器。有许多流行的自适应优化器,如Adam, Adagrad, Adadelta,或RMSprop等。SGD+momentum被广泛应用于各种问题领域。有两件事需要考虑:首先,如果你关心快速的收敛,使用自适应优化器,比如Adam,但是它可能会陷入局部极小值,并且提供了很差的泛化(如下图所示)。其次,SGD+momentum可以找到全局极小值,但它依赖于健壮的初始化,可能需要比其他自适应优化器更长的时间才能收敛(如下图所示)。我建议你使用SGD+momentum,因为它趋向于达到更好的最优状态。

训练深度神经网络的技巧和窍门

14)有三个学习率起点(即1e-1,1e-3和1e-6)。如果您对预训练模型进行微调,请考虑低于1e-3(比如1e-4)的低学习率。如果您从头开始训练网络,请考虑学习率大于或等于1e-3。您可以尝试这些起点并调整它们以查看哪一个最佳,选择那个。

15)除了Learning Rate Schedule(https://keras.io/callbacks/#learningratescheduler)会降低学习率,还有一种方法可以通过一些因素(比如10)来降低学习速度,如果验证损失在某些epochs停止改善(比如10),我们就可以停止训练过程。这可以通过在Keras中使用ReduceLROnPlateau和EarlyStopping轻松完成。Python示例如下:

reduce = keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=5, mode='auto')

early = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=1e-4, patience=10, mode='auto')

model.fit(X, Y, callbacks=[reduce, early])

16)如果您在密集的预测领域工作,比如前景分割或语义分割,那么您应该使用skip connections,因为由于最大池化操作或跨越卷积而丢失了对象边界或有用信息。这也可以帮助您的网络轻松地学习特征从特征空间到图像空间的特征映射,并有助于缓解网络中的消失梯度问题。

17)始终使用数据增强功能,如水平翻转,旋转,缩放裁剪等。这有助于提高边距的准确性。

18)你必须有一个高速GPU用于培训,但它有点贵。如果您希望使用免费的云GPU,我建议您使用Google Colab。

19)在ReLU之前使用Max-pooling 来保存一些计算。由于ReLU将值限制为零:f(x)=max(0,x)并且Max-pooling pools仅限最大激活:f(x)=max(x1,x2,...,xi),使用Conv > MaxPool > ReLU而不是Conv > ReLU > MaxPool。

例如,假设我们有两次激活Conv(即0.5和-0.5):

所以 MaxPool > ReLU = max(0, max(0.5,-0.5)) = 0.5

ReLU > MaxPool = max(max(0,0.5), max(0,-0.5)) = 0.5

这两个操作的输出仍然是0.5。在这种情况下,使用MaxPool > ReLU可以节省我们一个max操作。

20)考虑使用深度可分离卷积运算,与正常卷积运算相比,该运算速度快,并且大大减少了参数数量。

21)最后但并非最不重要的是不要放弃。相信自己,你可以做到!如果您仍未获得所需的高精度,请调整超参数,网络架构或训练数据,直到获得所需的准确度。

相关推荐