深度学习超参数调优指南
文章目录
- 深度学习超参数调优指南
- 一、超参数相关基础知识
- 1. 神经网络中包含哪些超参数
- 2. 超参数的重要性顺序
- 3. 部分超参数如何影响模型性能
- 4. 部分超参数合适的范围
- 二、超参数调整技巧
- 1. 如何选择激活函数
- 2. 如何调整 Batch Size
- 3. 如何调整学习率
- 三、自动调参方法
- 1. 网格搜索与随机搜索
- 2. 贝叶斯优化
- 四、调试模型技巧
- 1. 探索和清洗数据
- 2. 探索模型结果
- 3. 监控训练和验证误差
- 参考
深度学习超参数调优指南
对于深度学习模型的训练,处理大量的参数是最具挑战性的任务之一。无论是网络的宽度和深度、连接结构,还是损失函数的超参数设计与调试,亦或是学习率、批量大小、优化器的参数等,这些参数都会直接或间接地影响模型的性能。若要逐一调整这些参数,将耗费大量的时间与资源,这在实际操作中是不现实的。研究表明,某些超参数的重要性远超其他参数,因此,理解各个超参数的作用及其潜在影响,是成功训练深度学习模型的关键技能之一。
超参数调整是连接深度学习理论与实践的核心环节之一。当前,深度学习领域仍存在许多未解之谜,如何设计和优化出优秀的模型结构对于推动深度学习理论的发展具有重要意义。超参数调整的方法大致分为手动调整和自动优化两类。
一、超参数相关基础知识
1. 神经网络中包含哪些超参数
通常可以将超参数分为三类:网络参数、优化参数、正则化参数。
- 网络参数:包括网络层之间的交互方式(如相加、相乘或串接)、卷积核的数量和尺寸、网络层数(深度)和激活函数等。
- 优化参数:一般指学习率、批样本数量、不同优化器的参数及部分损失函数的可调参数。
- 正则化参数:如权重衰减系数、丢弃比率(dropout)。
2. 超参数的重要性顺序
- 学习率,损失函数上的可调参数
- 学习率控制着训练中网络梯度更新的幅度,直接影响模型的有效容限能力。
- 损失函数的可调参数需要结合具体的损失函数来调整,影响模型的有效容限能力。
- 批样本数量,动量优化器的动量参数β
- 批样本数量决定了梯度下降的方向。过小的批样本数量会导致难以收敛,尤其在存在批归一化时,而过大的批样本数量容易陷入局部最优解。
- 动量参数β用于加快训练,帮助避免陷入局部最优解。
- Adam优化器的超参数、权重衰减系数、丢弃比率和网络参数
- 这些参数在大部分实践中不建议过多尝试。
- Adam优化器中的β1,β2,ϵ,常设为0.9、0.999、10^-8即有不错表现。
- 权重衰减系数建议值为0.0005,dropout建议比率控制在0.2到0.5之间。
3. 部分超参数如何影响模型性能
超参数 | 影响模型容量的方式 | 原因 | 注意事项 |
---|---|---|---|
学习率 | 调至最优,提升有效容量 | 过高或过低的学习率都会影响优化效果,降低模型有效容限。 | 学习率的最优点在训练的不同阶段可能变化,需要有效的学习率衰减策略。 |
损失函数部分超参数 | 调至最优,提升有效容量 | 损失函数的超参数会影响优化过程,错误的超参数设置会使模型难以优化。 | 部分损失函数超参数对结果敏感,调整时建议参考论文的推荐值。 |
批样本数量 | 过大或过小,降低有效容量 | 大部分情况下,选择适合硬件容量的批样本数量即可。 | 特殊任务(如度量学习中的N-pair loss)可能依赖于批样本数量。 |
丢弃法 | 比率降低提升模型容量 | 较少的丢弃参数意味着参数量的增加,提升模型容量。 | - |
权重衰减系数 | 调至最优,提升有效容量 | 权重衰减可以限制参数变化幅度,起到正则作用。 | - |
优化器动量 | 调至最优,可能提升有效容量 | 动量参数用于加快训练,避免陷入局部最优解。 | - |
模型深度 | 同条件下,深度增加,模型容量提升 | 增加模型深度意味着参数增多,拟合能力增强。 | 模型深度越深,所需时间和硬件资源也越多。 |
卷积核尺寸 | 尺寸增加,模型容量提升 | 增加卷积核尺寸意味着参数量的增加。 | - |
4. 部分超参数合适的范围
超参数 | 建议范围 | 注意事项 |
---|---|---|
初始learning-rate | SGD: [1e-2, 1e-1] momentum: [1e-3, 1e-2] Adagrad: [1e-3, 1e-2] Adadelta: [1e-2, 1e-1] RMSprop: [1e-3, 1e-2] Adam: [1e-3, 1e-2] Adamax: [1e-3, 1e-2] Nadam: [1e-3, 1e-2] | 这些范围适用于从头开始训练的情况。微调时,初始学习率可降低一到两个数量级。 |
损失函数部分超参数 | 多个损失函数之间,损失值尽量相近,不建议超过或低于两个数量级 | 这是指多个损失组合的情况,单个损失超参数需结合实际情况。 |
batch-size大小 | [1:1024] | 批样本数量过大(大于6000)或为1时,需调整学习策略或内部归一化方式。 |
dropout 比率 | [0, 0.5] | - |
权重衰减系数 | [0, 1e-4] | - |
卷积核尺寸 | [7x7], [5x5], [3x3], [1x1] | - |
二、超参数调整技巧
在手动调整超参数的过程中,可按照以下步骤进行:
- 初始训练:首先设置合适的初始学习率,测试小范围不同批样本数量下的效果。
- 单一超参数调整:针对一个超参数,固定其他参数,进行调整和验证。
- 重复和精细调整:逐步缩小范围,重复调整和验证,直到获得较为稳定的超参数组合。
1. 如何选择激活函数
选择一个适合的激活函数并不容易,需要考虑很多因素。通常的做法是,如果不确定哪一个激活函数效果更好,可以把它们都试试,然后在验证集或测试集上进行评价,选择表现更好的那个。
以下是常见的选择情况:
- 如果输出是 0、1 值(二分类问题),输出层选择 sigmoid 函数,其他的所有单元都选择 ReLU 函数。
- 如果在隐藏层上不确定使用哪个激活函数,通常使用 ReLU 激活函数。有时,也会使用 tanh 激活函数,但 ReLU 的一个优点是:当是负值时,导数等于 0。
- sigmoid 激活函数:除了输出层是一个二分类问题外,基本不会使用它。
- tanh 激活函数:tanh 是非常优秀的,几乎适合所有场合。
- ReLU 激活函数:最常用的默认函数,如果不确定用哪个激活函数,就使用 ReLU 或者 Leaky ReLU,再去尝试其他的激活函数。
- 如果遇到了一些死的神经元,可以使用 Leaky ReLU 函数。
2. 如何调整 Batch Size
- Batch Size 太小,模型表现效果极其糟糕(error 飙升)。
- 随着 Batch Size 增大,处理相同数据量的速度越快。
- 随着 Batch Size 增大,达到相同精度所需要的 epoch 数量越来越多。
- 由于上述两种因素的矛盾,Batch Size 增大到某个时候,达到时间上的最优。
- 由于最终收敛精度会陷入不同的局部极值,因此 Batch Size 增大到某些时候,达到最终收敛精度上的最优。
- 根据自身显卡显存情况,一般使用 32/64 倍数调整。
3. 如何调整学习率
在深度学习中,通过定义一个模型,并根据训练集上的数据估计最优参数。梯度下降法是一个广泛被用来最小化模型误差的参数优化算法。梯度下降法通过多次迭代,并在每一步中最小化成本函数(cost)来估计模型的参数。学习率 (learning rate) 控制模型的学习进度。在梯度下降法中,通常给定统一的学习率,整个优化过程中都以确定的步长进行更新。 在迭代优化的前期,学习率较大则步长较长,可以较快地进行梯度下降;而在迭代优化的后期,逐步减小学习率的值,减小步长,这样将有助于算法的收敛,更容易接近最优解。在模型优化中,常用的几种学习率衰减方法有:分段常数衰减、多项式衰减、指数衰减、自然指数衰减、余弦衰减、线性余弦衰减、噪声线性余弦衰减。
学习率范围参考:
- SGD: [1e-2, 1e-1]
- momentum: [1e-3, 1e-2]
- Adagrad: [1e-3, 1e-2]
- Adadelta: [1e-2, 1e-1]
- RMSprop: [1e-3, 1e-2]
- Adam: [1e-3, 1e-2]
- Adamax: [1e-3, 1e-2]
- Nadam: [1e-3, 1e-2]
不同的优化算法按理说适合不同的任务,但在实际应用中常用的还是 Adam 和 SGD+Momentum。
Adam 可以解决许多奇怪的问题(例如 loss 降不下去时,换成 Adam 往往会迅速改善),但也可能引发一些意想不到的问题(例如,单词词频差异较大时,即使当前 batch 中没有某个单词,它的词向量也会被更新;或者在与 L2 正则结合时产生复杂效果)。使用 Adam 时需要谨慎,一旦出现问题,可以尝试各种改进版 Adam(如 MaskedAdam、AdamW 等)来应对。不过,一些博客指出,虽然 Adam 收敛快,但其泛化能力不如 SGD,想要取得更优结果可能需要精细调参 SGD。Adam 和 Adadelta 在小数据集上的效果不如 SGD。虽然 SGD 的收敛速度较慢,但最终的收敛结果通常更好。如果使用 SGD,可以从较大的学习率(如 1.0 或 0.1)开始,定期在验证集上检查 cost,如果不再下降,则将学习率减半。我看到过很多论文采用这种策略,自己实验的效果也很不错。当然,也可以先用自适应优化器(如 Ada 系列)进行初期训练,接近收敛时再切换到 SGD,这样也能带来提升。有研究表明,Adadelta 在分类问题上表现较好,而 Adam 则更适合生成任务。虽然 Adam 收敛更快,但得到的解往往不如 SGD+Momentum 稳定,如果不急于求成,选择 SGD 可能是更好的选择。Adam 不需要频繁调整学习率,而 SGD 则需要更多时间来调节学习率和初始权重。
三、自动调参方法
1. 网格搜索与随机搜索
网格搜索是超参数调优中较为基础的方法。将各超参数分别在一个给定的范围内按固定步长进行遍历,并组合成不同的超参数集进行实验测试。
随机搜索是一种改进的网格搜索方法,通过随机采样给定范围内的超参数组合,相较于网格搜索效率更高。
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
from sklearn.ensemble import RandomForestClassifier
# 假设已准备好训练数据
X_train, y_train = ...
# 定义模型
model = RandomForestClassifier()
# 定义超参数范围
param_grid = {
'n_estimators': [100, 200, 300],
'max_depth': [5, 10, 15],
'min_samples_split': [2, 5, 10]
}
# 创建网格搜索实例
grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=3)
# 进行训练
grid_search.fit(X_train, y_train)
# 输出最佳参数
print("Best parameters found: ", grid_search.best_params_)
2. 贝叶斯优化
贝叶斯优化是一种高级的自动调参方法,通过构建代理模型对超参数空间进行探索。相比于网格搜索和随机搜索,贝叶斯优化能够更有效地找到最优超参数。
from skopt import BayesSearchCV
from sklearn.ensemble import RandomForestClassifier
# 定义模型
model = RandomForestClassifier()
# 定义超参数搜索空间
param_space = {
'n_estimators': (10, 500),
'max_depth': (1, 50),
'min_samples_split': (2, 10)
}
# 创建贝叶斯优化搜索实例
bayes_search = BayesSearchCV(estimator=model, search_spaces=param_space, n_iter=32, cv=3)
# 进行训练
bayes_search.fit(X_train, y_train)
# 输出最佳参数
print("Best parameters found: ", bayes_search.best_params_)
四、调试模型技巧
在讨论如何调试模型之前,需要澄清一个误区:数据是模型的根本。如果有一批质量优秀的数据,或者能够将数据质量处理得很好,往往比挑选或设计模型带来的收益更大。之后才是模型的设计和训练技巧。
1. 探索和清洗数据
探索数据集是设计算法之前最重要的一步。例如,在图像分类任务中,我们需要了解数据集的样本类别及其数量是否平衡,图像之间是否存在质量差异等。如果类别数远超样本数,那么普通方法可能效果不佳,此时可以考虑few-shot learning或数据增强。
2. 探索模型结果
在验证集上对模型结果进行深入分析是提升模型性能的重要步骤。通过训练集和验证集的结果对比,可以直观地分析模型的偏差和结果的正确性。例如,在样本不平衡的情况下,关注少样本类别的表现,进行数值和可视化分析,以确定模型的行为。
3. 监控训练和验证误差
首先,确认代码的正确性至关重要,特别是在训练和验证均存在问题时。其次,根据训练和验证误差追踪模型的拟合状态,对于小数据集过拟合问题可能会更加显著,但并不是过拟合一定比欠拟合表现差,因此需结合具体任务衡量。
- Dropout 对小数据防止过拟合有很好的效果,值一般设为0.5。
- Adam 不需要频繁调整学习率,而 SGD 则需要更多时间来调节学习率和初始权重。
- 小数据集上 Dropout+SGD 效果提升都非常明显,因此可能的话,建议一定要尝试一下。
- 除了gate之类的地方,需要把输出限制成0-1之外,尽量不要用sigmoid激活函数。可以用tanh或者relu之类的激活函数。
- 超参上,learning rate 最重要,推荐了解 cosine learning rate 和 cyclic learning rate,其次是 batchsize 和 weight decay。当模型还不错的时候,就可以试着做数据增广和改损失函数锦上添花了。
- 初始学习率和批样本数量的选择极其重要,决定了训练过程的稳定性和效率。可以采用指数递减或余弦退火等学习率衰减策略。
- 损失函数的选取和其可调参数的设置对模型最终效果有着至关重要的影响,特别是在多任务学习或存在多种损失组合的情况下。
参考
- 极市:深度学习调参有哪些技巧?
- 机器之心:2020年深度学习调参技巧合集
- 深度学习调优指南中文版
- 10分钟带你学会深度学习模型调参,让你的模型性能达到极致
😃😃😃