CNN调优总结
数据派THU
共 2189字,需浏览 5分钟
·
2022-06-08 08:31
来源:Charlotte数据挖掘、深度学习爱好者 本文约11000字,建议阅读15+分钟
本文详细对比了各种超参数对CNN模型性能的影响。
针对CNN优化的总结
Systematic evaluation of CNN advances on the ImageNet
下面转自:
https://nmarkou.blogspot.com.cy/2017/02/the-black-magic-of-deep-learning-tips.html
有助于充分利用 DNN 的小技巧
记得要 shuffle。不要让你的网络通过完全相同的 minibatch,如果框架允许,在每个 epoch 都 shuffle 一次。 扩展数据集。DNN 需要大量的数据,而且模型在小的数据集上很容易过拟合。我强烈建议你要扩展原始的数据集。如果你的是一个视觉任务,可以增加噪点、增白,减少像素,旋转或色移,模糊,等等可以扩展的一切。有一点不好的是,假如你扩展得太大,可能训练的数据大多数是相同的。我创建了一个应用随机变换的层来解决这个问题,这样就不会有相同的样本。若果你用的是语音数据,可以进行移位和失真处理。 在整个数据集上训练之前,先在非常小的子数据集上训练进行过拟合,这样你会知道你的网络可以收敛。这个 tip 来自 Karpathy。 始终使用 dropout 将过拟合的几率最小化。在大小 > 256 (完全连接层或卷积层)之后就应该使用 dropout。关于这一点有一篇很好的论文:Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning [Gal Yarin & Zoubin Ghahramani,2015]. 避免 LRN 池化,MAX 池化会更快。 避免 Sigmoid/TanH 的门,它们代价昂贵,容易饱和,而且可能会停止反向传播。实际上,你的网络越深,就越应该避免使用 Sigmoid 和 TanH。可以使用更便宜而且更有效的 ReLU 和 PreLU 的门,正如在 Yoshua Bengio 等人的论文 Deep Sparse Rectifier Neural Networks 中所提到的,这两者能够促进稀疏性,而且它们的反向传播更加鲁棒。 在最大池化之前不要使用 ReLU 或 PreLU ,而是在保存计算之后使用它。 不要使用 ReLU ,它们太旧了。虽然他们是非常有用的非线性函数,可以解决很多问题。但是,你可以试试用它微调一个新模型,由于 ReLU 阻碍反向传播,初始化不好,你没法得到任何微调效果。但是你应该用 PreLU 以及一个非常小的乘数,通常是0.1。使用 PreLU 的话收敛更快,而且不会像 ReLU 那样在初始阶段被卡住。ELU 也很好,但成本高。 经常使用批标准化。参考论文:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift [Sergey Ioffe & Christian Szegedy,2015]。这会很有效。批标准化允许更快的收敛(非常快)以及更小的数据集。这样你能够节省时间和资源。 虽然大多数人喜欢删除平均值,不过我不喜欢。我喜欢压缩输入数据为[-1,+1]。这可以说是训练和部署方面的技巧,而不是针对提升性能的技巧。 要能适用更小的模型。假如你是像我这样部署深度学习模型,你很快就会体会到把千兆字节规模的模型推给用户或地球另一端的服务器的痛苦。哪怕要牺牲一些准确度,也应该小型化。 假如你使用比较小的模型,可以试试 ensemble。通常 ensemble 5个网络能够提升准确度约3%。 尽可能使用 xavier 初始化。你可以只在大的完全连接层上使用它,然后避免在 CNN 层上使用。有关这点的解释可以阅读这篇文章:An Explanation of Xavier Initialization(by Andy Jones) 如果你的输入数据有空间参数,可以试试端到端的 CNN。可以阅读这篇论文:SqueezeNet: AlexNet-level accuracy with 50x fewer parameters and <0.5MB model size [Forrest N. Iandola et. al. 2016],它介绍了一种新的方法,而且性能非常好,你可以尝试应用上面提到的tips。 修改你的模型,只要可能就使用 1x1 的 CNN 层,它的位置对提高性能很有帮助。 假如没有高端的 GPU,就不要尝试训练任何东西了。 假如你要利用模型或你自己的层来制作模板,记得把所有东西参数化,否则你得重建所有二进制文件。 最后,要明白你在做什么。深度学习就像是机器学习里的中子弹,它不是任何任务、任何时候都有效的。了解你正在使用的结构以及你试图达成的目的,才不至于盲目地复制模型。
提升算法性能思路
1. 通过数据提升性能
2. 通过算法提升性能
3. 通过算法调参提升性能
4. 通过嵌套模型提升性能
获取更多数据 创造更多数据 重放缩你的数据 转换你的数据 特征选取 重架构你的问题
1) 获取更多数据
Datasets Over Algorithms
如果你的数据是数值型向量,可以随机构造已有向量的修改版本。 如果你的数据是图片,可以随机构造已有图片的修改版本(平移、截取、旋转等)。 如果你的数据是文本,类似的操作……
Image Augmentation for Deep Learning With Keras http://machinelearningmastery.com/image-augmentation-deep-learning-keras/ What is jitter? (Training with noise) ftp://ftp.sas.com/pub/neural/FAQ3.html#A_jitter
3) 重缩放(rescale)你的数据
当应用神经网络时,一个传统的经验法则是:重缩放(rescale)你的数据至激活函数的边界。
归一化到0和1的区间。 重放缩到-1和1的区间 标准化(译者注:标准化数据使之成为零均值,单位标准差)
Should I standardize the input variables (column vectors)? ftp://ftp.sas.com/pub/neural/FAQ2.html#A_std How To Prepare Your Data For Machine Learning in Python with Scikit-Learn http://machinelearningmastery.com/prepare-data-machine-learning-python-scikit-learn/
4) 数据变换
列数据看起来像偏斜的高斯分布吗?考虑用Box-Cox变换调整偏态。 列数据看起来像指数分布吗?考虑用对数变换。 列数据看起来有一些特征,但是它们被一些明显的东西遮盖了,尝试取平方或者开平方根来转换数据 你能离散化一个特征或者以某种方式组合特征,来更好地突出一些特征吗?
你能利用类似PCA的投影方法来预处理数据吗? 你能综合多维特征至一个单一数值(特征)吗? 你能用一个新的布尔标签去发现问题中存在一些有趣的方面吗? 你能用其他方法探索出目前场景下的其他特殊结构吗?
How to Define Your Machine Learning Problem http://machinelearningmastery.com/how-to-define-your-machine-learning-problem/ Discover Feature Engineering, How to Engineer Features and How to Get Good at It http://machinelearningmastery.com/discover-feature-engineering-how-to-engineer-features-and-how-to-get-good-at-it/ How To Prepare Your Data For Machine Learning in Python with Scikit-Learn http://machinelearningmastery.com/prepare-data-machine-learning-python-scikit-learn/
5) 特征选择
同样的,如果你有时间,我建议在同一个网络中尝试选择不同的视角来看待你的问题,评估它们,来看看分别有怎样的性能。
或许你利用更少的特征就能达到同等甚至更好的性能。而且,这将使模型变得更快! 或许所有的特征选择方法都剔除了同样的特征子集。很好,这些方法在没用的特征上达成了一致。 或许筛选过后的特征子集,能带给特征工程的新思路。
An Introduction to Feature Selection http://machinelearningmastery.com/an-introduction-to-feature-selection/ Feature Selection For Machine Learning in Python http://machinelearningmastery.com/feature-selection-machine-learning-python/
6) 重新架构你的问题
看看能够在一个时间窗(时间周期)内对已有的特征/数据做一个合并。 或许你的分类问题可以成为一个回归问题(有时候是回归到分类)。 或许你的二元输出可以变成softmax输出? 或许你可以转而对子问题进行建模。
How to Define Your Machine Learning Problem http://machinelearningmastery.com/how-to-define-your-machine-learning-problem/
通过算法提升性能
对算法进行抽样调查 借鉴已有文献 重采样方法
1) 对算法进行抽样调查
首先尝试评估一些线性方法,例如逻辑回归(logistic regression)和线性判别分析(linear discriminate analysis)。 评估一些树类模型,例如CART, 随机森林(Random Forest)和Gradient Boosting。 评估一些实例方法,例如支持向量机(SVM)和K-近邻(kNN)。 评估一些其他的神经网络方法,例如LVQ, MLP, CNN, LSTM, hybrids等
A Data-Driven Approach to Machine Learning http://machinelearningmastery.com/a-data-driven-approach-to-machine-learning/ Why you should be Spot-Checking Algorithms on your Machine Learning Problems http://machinelearningmastery.com/why-you-should-be-spot-checking-algorithms-on-your-machine-learning-problems/ Spot-Check Classification Machine Learning Algorithms in Python with scikit-learn http://machinelearningmastery.com/spot-check-classification-machine-learning-algorithms-python-scikit-learn/
2) 借鉴已有文献
How to Research a Machine Learning Algorithm http://machinelearningmastery.com/how-to-research-a-machine-learning-algorithm/ Google Scholar http://scholar.google.com/
3) 重采样方法
或许你在使用一个简单的训练集/测试集分割,这是常规套路。如果是这样,你需要确保这种分割针对你的问题具有代表性。单变量统计和可视化是一个好的开始。 或许你能利用硬件来加速估计的过程。例如,如果你有集群或者AWS云端服务(Amazon Web Services)账号,你可以并行地训练n个模型,然后获取结果的均值和标准差来得到更鲁棒的估计。 或许你可以利用hold-out验证方法来了解模型在训练后的性能(这在早停法(early stopping)中很有用,后面会讲到)。 或许你可以先隐藏一个完全没用过的验证集,等到你已经完成模型选择之后再使用它。
有些情况下你会发现在训练集的一部分样本上训练得到的模型的性能,和在整个数据集上训练得到的模型的性能有很强的相关性。也许你可以先在小数据集上完成模型选择和参数调优,然后再将最终的方法扩展到全部数据集上。 或许你可以用某些方式限制数据集,只取一部分样本,然后用它进行全部的建模过程。
Evaluate the Performance Of Deep Learning Models in Keras http://machinelearningmastery.com/evaluate-performance-deep-learning-models-keras/ Evaluate the Performance of Machine Learning Algorithms in Python using Resampling http://machinelearningmastery.com/evaluate-performance-machine-learning-algorithms-python-using-resampling/
通过算法调参提升性能
诊断(Diagnostics) 权重初始化(Weight Initialization) 学习速率(Learning Rate) 激活函数 网络拓扑(Network Topology) 批次和周期(Batches and Epochs) 正则化 优化和损失 早停法
How to Grid Search Hyperparameters for Deep Learning Models in Python With Keras http://machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/
1) 诊断
如果训练集上的模型总是优于验证集上的模型,你可能遇到了过拟合,你可以使用诸如正则化的方法。 如果训练集和验证集上的模型都很差,你可能遇到了欠拟合,你可以提升网络的容量,以及训练更多或者更久。 如果有一个拐点存在,在那之后训练集上的模型开始优于验证集上的模型,你可能需要使用早停法。
对于难以训练的样本,或许你需要更多的数据。 或许你应该剔除训练集中易于建模的多余的样本。 也许可以尝试对训练集划分不同的区域,在特定区域中用更专长的模型。
Display Deep Learning Model Training History in Keras http://machinelearningmastery.com/display-deep-learning-model-training-history-in-keras/ Overfitting and Underfitting With Machine Learning Algorithms http://machinelearningmastery.com/overfitting-and-underfitting-with-machine-learning-algorithms/
2) 权重初始化
尝试所有不同的初始化方法,考察是否有一种方法在其他情况不变的情况下(效果)更优。 尝试用无监督的方法,例如自动编码(autoencoder),来进行预先学习。 尝试使用一个已经存在的模型,只是针对你的问题重新训练输入层和输出层(迁移学习(transfer learning))
Initialization of deep networks http://deepdish.io/2015/02/24/network-initialization/
3) 学习率
实验很大和很小的学习率 格点搜索文献里常见的学习速率值,考察你能学习多深的网络。 尝试随周期递减的学习率 尝试经过固定周期数后按比例减小的学习率。 尝试增加一个动量项(momentum term),然后对学习速率和动量同时进行格点搜索。
Using Learning Rate Schedules for Deep Learning Models in Python with Keras http://machinelearningmastery.com/using-learning-rate-schedules-deep-learning-models-python-keras/ What learning rate should be used for backprop? ftp://ftp.sas.com/pub/neural/FAQ2.html#A_learn_rate
4) 激活函数
Why use activation functions? ftp://ftp.sas.com/pub/neural/FAQ2.html#A_act
5) 网络拓扑
尝试一个隐藏层和许多神经元(广度模型)。 尝试一个深的网络,但是每层只有很少的神经元(深度模型)。 尝试上述两种方法的组合。 借鉴研究问题与你的类似的论文里面的结构。 尝试拓扑模式(扇出(fan out)然后扇入(fan in))和书籍论文里的经验法则(下有链接)
这些链接会给你很多启发该尝试哪些事情,至少对我来说是的。
How many hidden layers should I use? ftp://ftp.sas.com/pub/neural/FAQ3.html#A_hl How many hidden units should I use? ftp://ftp.sas.com/pub/neural/FAQ3.html#A_hu
6) Batches和周期
之前,我们已经讨论了学习率,网络大小和周期之间的关系。
尝试选取与训练数据同大小的batch size,但注意一下内存(批次学习(batch learning)) 尝试选取1作为batch size(在线学习(online learning)) 尝试用格点搜索不同的小的batch size(8,16,32,…) 分别尝试训练少量周期和大量周期。
What are batch, incremental, on-line … learning? ftp://ftp.sas.com/pub/neural/FAQ2.html#A_styles Intuitively, how does mini-batch size affect the performance of (stochastic) gradient descent? https://www.quora.com/Intuitively-how-does-mini-batch-size-affect-the-performance-of-stochastic-gradient-descent
7) 正则化
格点搜索不同的丢失比例。 分别在输入,隐藏层和输出层中试验dropout方法 dropout方法也有一些拓展,比如你也可以尝试drop connect方法。
权重衰减(Weight decay)去惩罚大的权重 激活约束(Activation constraint)去惩罚大的激活值
Dropout Regularization in Deep Learning Models With Keras http://machinelearningmastery.com/dropout-regularization-deep-learning-models-keras/ What is Weight Decay? ftp://ftp.sas.com/pub/neural/FAQ3.html#A_decay
8) 优化和损失
随机梯度下降法是默认的选择。先好好利用它,配以不同的学习率和动量。
ADAM RMSprop
An overview of gradient descent optimization algorithms http://sebastianruder.com/optimizing-gradient-descent/ What are conjugate gradients, Levenberg-Marquardt, etc.? ftp://ftp.sas.com/pub/neural/FAQ2.html#A_numanal On Optimization Methods for Deep Learning, 2011 PDF http://ai.stanford.edu/~ang/papers/icml11-OptimizationForDeepLearning.pdf
9) Early Stopping/早停法
How to Check-Point Deep Learning Models in Keras http://machinelearningmastery.com/check-point-deep-learning-models-keras/ What is early stopping? ftp://ftp.sas.com/pub/neural/FAQ3.html#A_stop
通过嵌套模型提升性能
组合模型 组合视角 堆叠(Stacking)
1) 组合模型
Ensemble Machine Learning Algorithms in Python with scikit-learn http://machinelearningmastery.com/ensemble-machine-learning-algorithms-python-scikit-learn/ How to Improve Machine Learning Results http://machinelearningmastery.com/how-to-improve-machine-learning-results/
2) 组合视角
3) stacking/堆叠
Stacked Generalization (Stacking) http://machine-learning.martinsewell.com/ensembles/stacking/
其余的可参考资源
Neural Network FAQ ftp://ftp.sas.com/pub/neural/FAQ.html How to Grid Search Hyperparameters for Deep Learning Models in Python With Keras http://machinelearningmastery.com/grid-search-hyperparameters-deep-learning-models-python-keras/ Must Know Tips/Tricks in Deep Neural Networks http://lamda.nju.edu.cn/weixs/project/CNNTricks/CNNTricks.html How to increase validation accuracy with deep neural net? http://stackoverflow.com/questions/37020754/how-to-increase-validation-accuracy-with-deep-neural-net
编辑:于腾凯 校对:龚力
评论