19、深度学习神经网络的参数调优与性能优化

深度学习神经网络的参数调优与性能优化

1. 神经网络权重计算与影响

在神经网络中,权重数量对训练速度有着重要影响。例如,考虑一个 100x100 的网络,当有 10 个数值输入并分类为 3 个状态时,权重数量为 (10 * 100) + (100 * 100) + (100 * 3) = 11,300。若将输入改为 5 个数值输入和 5 个枚举输入(如性别、喜爱颜色、迈尔斯 - 布里格斯性格类型、星座和中国生肖),每个枚举级别成为一个输入神经元(每个类别还额外有一个输入神经元处理缺失或未见过的值),此时输入神经元变为 5 + 3 + 11 + 17 + 13 + 13 = 62 个,总权重数量变为 (62 * 100) + (100 * 100) + (100 * 3) = 16,500,比之前增加了 50%。

这表明,权重越多,训练速度越慢。如果天真地使用一个有 50,000 个级别的因子(如邮政编码),且第一层隐藏层有 1000 个神经元,可能会比预期多出 5000 万个权重。

2. 激活函数

神经元有多个加权输入和一个输出,输入求和后,激活函数决定输出值。H2O 支持三种激活函数:
- Rectifier :最常用的激活函数,也是默认值。它输出加权输入的总和,但将所有负值裁剪为零。这意味着会产生很多零值(零值对训练更深的网络有好处),但正值无界。
- Tanh :双曲正切的缩写。它将输入范围从负无穷到正无穷转换为输出范围 -1 到 +1,在输入总和接近零时变化最快。
- Maxout :直接输出输入中的最大值,即加权输入直接使用,不进行求和。

每种激活函数都有“最佳”的说法,但实际上取决于数据。尽可能使用网格搜索尝试所有三种选项。通常 Rectifier 更快,若有疑问可选择它。若 Rectifier 或 Maxout 出现数值不稳定问题,可切换到 Tanh。

此外,H2O 支持的激活参数有六个可能值,因为每个激活函数都有“WithDropout”变体,可使用 hidden_dropout_ratios 控制输出随机置零的速率,作为正则化技术避免过拟合。

3. 深度学习参数

3.1 隐藏层设置

hidden 参数用于设置隐藏层的大小,默认是 200,200,表示有两个隐藏层,每层 200 个神经元。若设置为 60,40,20,则有三个隐藏层,分别有 60、40 和 20 个神经元。

3.2 自动编码器设置

auto-encoder 参数默认值为 false,表示进行监督学习。若设置为 true,则进行自动编码,通常此时应将 activation 设置为 Tanh。

3.3 深度学习正则化

深度学习的正则化主要有两种方法:
- 丢弃连接 :在连接一层到下一层时丢弃部分连接。
- 正则化 :通过设置相关参数实现。

激活函数选择

activation 参数有六个可能值,先选择三种激活函数之一,再选择是否使用丢弃。若要使用 hidden_dropout_ratios ,必须指定 “TanhWithDropout”、“RectifierWithDropout” 或 “MaxoutWithDropout” 之一。在使用检查点时,激活函数的选择不能更改,且不能在网格中部分模型使用隐藏比率,部分不使用。在这些情况下,建议始终使用 “WithDropout” 激活函数,并在不需要丢弃时将 hidden_dropout_ratios 设置为 0.0。

隐藏层丢弃比率

hidden_dropout_ratios 为每个隐藏层指定一个比率,默认值为 0.5,表示每个训练行通过网络时,神经元有 50% 的概率将其值传递到下一个隐藏层,50% 的概率传递零。若不使用支持丢弃的激活函数,则该参数被忽略。此参数难以直观选择,最好在网格中进行实验,在层数较多的网络中尝试更高的丢弃率。

输入丢弃比率

input_dropout_ratio 表示输入神经元输入到第一个隐藏层的百分比,默认值为 0.0(无输入丢弃)。若为 0.5,则每个训练数据行中的每个特征有 50% 的概率被使用,即每次训练样本和每个 epoch 中会将一半的列置零。如果数据中有很多噪声,此参数可能有效,但 0.5 是比较高的值。可在网格中使用此参数,初始时使用较宽的范围,如 0.0、0.1、0.2、0.3、0.4 和 0.5。

L1 正则化

l1 即 L1 正则化,也称为套索正则化,默认值为 0,典型尝试值为 0.0001 或更小。

L2 正则化

l2 即 L2 正则化,也称为岭正则化,默认值为 0,典型尝试值为 0.0001 或更小。

最大权重平方和

max_w2 为神经元输入权重的平方和设置上限,默认无限制,这是一种直接防止权重增长过大的方法。

3.4 深度学习评分参数

有大量参数可控制评分频率,它们用于平衡以下几个概念:
- 需要准确的分数来判断模型和进行早停。
- 评分花费的时间不能用于训练。
- 定期评分可更精细地选择最佳模型。
- 考虑集群因素。
- 考虑训练数据大小。

以下是一些重要的评分参数:
- train_samples_per_iteration :控制每次迭代使用的训练行数,通常使用 -2(默认,让 H2O 决定)、0 和 -1 这三个特殊值。0 和 -1 在单节点上含义相同,即每个 epoch 评分一次。在多节点使用时,它们的含义不同。
- score_interval :评分模型的最小时间间隔(秒),默认值为 5。若 stopping_rounds 也为 5,则模型至少构建 50 秒。若其他参数(如低 score_duty_cycle 、高 train_samples_per_iteration )导致评分间隔已经较长,更改此参数可能无效。
- score_duty_cycle :评分与训练花费时间的比例,范围从 0.0 到 1.0,较低值表示更多时间用于训练,较高值表示更多时间用于评分。默认值为 0.1(10% 的时间用于评分,90% 用于训练)。
- target_ratio_comm_to_comp :通信开销与计算的目标比率,默认值为 0.05,即 5% 的时间用于节点间通信,95% 的时间用于每个节点的训练。此参数仅对多节点集群有意义,且仅在 train_samples_per_iteration = -2 时使用。降低此值可能使评分间隔变长或无效果。
- replicate_training_data :默认值为 true,表示将整个训练数据集复制到集群的每个节点。对于小数据集,这可以加快训练速度。
- shuffle_training_data :默认值为 false,若设置为 true,则训练数据随机排序。例如,若设置了 balance_classes ,建议使用此参数。
- score_validation_samples :评分时使用的验证数据集行数,默认值为 0,表示使用所有验证数据。若验证数据较大或评分更频繁,可选择较低值以加快评分速度(但会牺牲准确性)。
- score_training_samples :与 score_validation_samples 类似,但用于训练数据评分。默认值为 10,000,以确保非常大的数据集不会使评分过慢。若评分频繁,可将此值设置得更低。
- score_validation_sampling :仅在 score_validation_samples 从默认值 0 更改时使用,默认值为 “Uniform”,也可以是 “Stratified”(在进行分类且目标类不平衡时可能有更好的结果)。

如果觉得评分过于频繁,降低 score_duty_cycle 或增加 score_interval 通常是好的选择,显式设置 train_samples_per_iteration 也可以达到同样的效果。如果觉得早停触发过早,也可以采取这些措施,但最好的解决方法通常是增加 stopping_rounds

4. 建筑能源效率案例:默认深度学习模型

建筑能源效率问题是一个回归问题。使用 10 折交叉验证,而不是验证集。运行相应代码设置 H2O、加载数据并定义训练集、测试集、特征和目标变量:

m <- h2o.deeplearning(x, y, train, nfolds = 10, model_id = "DL_defaults")
m = h2o.estimators.H2ODeepLearningEstimator(model_id="DL_defaults")
m.train(x, y, train, nfolds=10)

该模型运行时间略超过 10 秒,使用了所有 8 个核心。10 折交叉验证的平均均方误差(MSE)为 8.15(标准差为 1.40),测试数据的 MSE 为 6.60。与随机森林、GBM 相比,默认模型的结果较差,仅略好于 GLM。

5. 建筑能源效率案例:调优深度学习模型

5.1 早停设置

为了给每个模型更多的 epoch 并避免担忧,使用早停技术。对于前几个网格,采用更严格的早停标准:如果在最后三次评分中没有至少提高 0.5%,则停止训练。相关参数设置如下:

stopping_metric = "MSE",
stopping_tolerance = 0.005,
stopping_rounds = 3,
epochs = 1000,
train_samples_per_iteration = 0,
score_interval = 3

5.2 增加 epoch 的效果

仅增加 epoch 数量(其他设置保持默认),结果显示模型在所有三个数据集上都有显著改善:
| | Default | Early#1 | Early#2 |
| — | — | — | — |
| Train - MSE | 5.587 | 0.223 | 0.092 |
| CV - MSE | 17.510 | 4.854 | 4.908 |
| Test - MSE | 7.089 | 0.580 | 0.437 |
| Epochs | 11.519 | 194.000 | 192.000 |

5.3 网络布局实验

由于问题是非线性的,认为需要两个隐藏层,但不认为需要超过三个层。尝试不同的隐藏层大小组合,共得到 14 种组合。为了加快速度,将交叉验证折数从 10 折减少到 6 折。实验结果如下:
| hidden | train.mse | xval.mse | sd | epochs | time |
| — | — | — | — | — | — |
| 324,324,324 | 0.347 | 4.368 | 0.494 | 177 | 23.4 |
| 54,54 | 0.087 | 4.712 | 0.556 | 982 | 5.2 |
| 162,162 | 0.059 | 4.744 | 0.446 | 525 | 10.4 |
| 324,162 | 0.096 | 4.788 | 0.503 | 236 | 7.0 |
| 324,162,162 | 0.162 | 4.946 | 0.479 | 171 | 9.9 |
| 162,81,81 | 0.270 | 4.978 | 0.457 | 418 | 8.0 |
| 54,108,108 | 0.022 | 5.005 | 0.581 | 518 | 7.4 |
| 162,324,324 | 0.135 | 5.026 | 0.322 | 158 | 17.5 |
| 162,162,162 | 0.152 | 5.065 | 0.629 | 243 | 10.0 |
| 162,81 | 0.035 | 5.077 | 0.649 | 623 | 7.9 |
| 162,324 | 0.087 | 5.147 | 0.520 | 244 | 9.3 |
| 54,108 | 0.015 | 5.242 | 0.573 | 836 | 6.3 |
| 324,324 | 0.131 | 5.456 | 0.627 | 205 | 8.4 |
| 54,54,54 | 0.049 | 5.983 | 1.173 | 720 | 6.5 |

从这些结果来看,没有强烈的需求增加更多的神经元或层,但更多的 epoch 可能会有更好的效果。

5.4 激活函数、丢弃和正则化实验

考虑激活函数的最佳值以及丢弃和正则化是否有帮助。有两种丢弃类型:输入层与第一个隐藏层之间的丢弃( input_dropout_ratio )和隐藏层输出的丢弃( hidden_dropout_ratios )。由于只有 8 个输入列(18 个输入神经元),较高的 input_dropout_ratio 值可能效果不佳。

使用以下超参数进行网格搜索:
- 若为 3 层网络,使用 324,162,162;若为 2 层网络,尝试 54,54 和 162,162。
- 激活函数选择 RectifierWithDropout、TanhWithDropout 或 MaxoutWithDropout。
- 隐藏层丢弃比率为 0(无丢弃)、0.1(每次少量丢弃)、0.2(丢弃 20%)和 0.5(丢弃 50%,默认值)。
- 输入丢弃比率为 0(无丢弃)或 0.1(忽略 10% 的输入)。
- L1 正则化为 0(无正则化)或 0.00001(1e - 05)。
- L2 正则化为 0(无正则化)、0.00001(1e - 05)或 0.0001(1e - 04)。

结果表明,最佳模型完全不使用丢弃。激活函数的选择影响较小,Rectifier 比 Tanh 或 Maxout 更快。对于 L2 正则化,约一半的顶级模型使用 0.00001,一半使用 0。对于 L1 正则化,0 和 0.00001 各占约 50%,但 0.0001 似乎会使结果变差。

5.5 最佳模型训练

选择最佳模型并进行重新训练,使用 10 折交叉验证,较宽松的早停标准,并允许最多 2000 个 epoch:

m <- h2o.deeplearning(
  x, y, train,
  nfolds = 10,
  model_id = "DL_best",
  activation = "Tanh",
  l2 = 0.00001,  #1e-05
  hidden = c(162,162),
  stopping_metric = "MSE",
  stopping_tolerance = 0.0005,
  stopping_rounds = 5,
  epochs = 2000,
  train_samples_per_iteration = 0,
  score_interval = 3
)

该模型最终使用了 479 个 epoch,训练数据的 MSE 为 0.148,测试数据的 MSE 为 0.434,是目前最好的结果。但实际上,大部分改进来自于增加 epoch 数量。

5.6 交叉验证指标之谜

交叉验证结果与测试数据结果差异较大。例如,10 折交叉验证模型的 MSE 平均值为 4.661(标准差为 0.63),而模型信息中显示的另一个 MSE 指标为 4.724274,基于所有训练数据的模型在训练数据上的 MSE 为 0.128,优于测试数据的 0.425。

这可能是因为该数据集没有噪声和重复,包含每种建筑类型的一个样本。训练数据量 562 可能不足以代表整体,但当使用全部 625 个训练行时,模型性能有了显著提升。深度学习是唯一表现出这种行为的算法,其他算法的交叉验证 MSE 与测试数据 MSE 相近。

综上所述,通过合理调整神经网络的参数,如激活函数、隐藏层大小、丢弃率和正则化参数,并结合早停技术和增加 epoch 数量,可以显著提高模型性能。但在实际应用中,需要根据具体数据集和问题进行细致的调优。

6. 总结与建议

6.1 权重与训练速度

权重数量对训练速度影响显著。在设计神经网络时,要谨慎考虑输入特征的类型和数量,尤其是枚举类型特征,避免因过多的输入神经元导致权重数量大幅增加,从而降低训练效率。例如,对于具有大量级别的因子(如邮政编码),可参考相关视频中使用 H2O 和额外数据集降低维度的方法。

6.2 激活函数选择

  • 一般情况下,Rectifier 激活函数速度较快,可作为首选。若遇到数值不稳定问题,可切换到 Tanh。
  • 利用网格搜索尝试不同的激活函数及其 “WithDropout” 变体,根据数据特点选择最适合的激活函数。

6.3 参数调优

  • 隐藏层设置 :根据问题的复杂程度合理设置隐藏层的数量和大小。可通过实验不同的组合,找到性能和训练时间的平衡点。
  • 正则化 :L1 和 L2 正则化可用于防止过拟合,但具体效果因数据集而异。在建筑能源效率案例中,L2 正则化的效果不明显,L1 正则化使用较小值(如 0.00001)时表现较好。
  • 丢弃率 :在大多数情况下,不使用丢弃或使用较小的丢弃率效果更好。对于输入丢弃比率,由于输入特征较少,较高的值可能会导致性能下降。
  • 早停设置 :合理设置早停参数可以避免过度训练,节省计算资源。在建筑能源效率案例中,增加 stopping_rounds 可以解决早停触发过早的问题。

6.4 交叉验证

交叉验证结果与测试数据结果可能存在差异,这可能与数据集的特点有关。在评估模型性能时,要综合考虑多种指标,并结合实际情况进行分析。

6.5 整体流程建议

以下是一个深度学习模型调优的基本流程:

graph LR
    A[数据准备] --> B[默认模型训练]
    B --> C[早停设置]
    C --> D[增加 epoch 实验]
    D --> E[网络布局实验]
    E --> F[激活函数、丢弃和正则化实验]
    F --> G[选择最佳模型重新训练]
    G --> H[模型评估]

7. 未来研究方向

虽然在建筑能源效率案例中通过参数调优取得了较好的结果,但仍有一些方面值得进一步研究:
- 更复杂的网络结构 :尝试使用更复杂的神经网络结构,如卷积神经网络(CNN)或循环神经网络(RNN),看是否能进一步提高模型性能。
- 集成学习 :将深度学习模型与其他机器学习算法进行集成,如随机森林、GBM 等,可能会获得更好的预测效果。
- 自动化调优 :开发自动化的参数调优工具,减少人工调优的时间和工作量。

8. 结论

深度学习在解决复杂问题方面具有强大的能力,但模型的性能高度依赖于参数的调优。通过本文的介绍和建筑能源效率案例的分析,我们了解了神经网络中权重计算、激活函数、参数设置等关键知识,并掌握了一套有效的参数调优方法。在实际应用中,要根据具体问题和数据集的特点,灵活运用这些方法,不断尝试和优化,以获得最佳的模型性能。同时,持续关注深度学习领域的新发展和新技术,将有助于我们更好地应对各种挑战。

希望本文能为读者在深度学习模型调优方面提供有价值的参考,帮助大家在实际项目中取得更好的成果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值