NNI—微软开源的⼀个⾃动帮你做机器学习调参的神器
NNI ⾃动机器学习调参,是微软开源的⼜⼀个神器,它能帮助你到最好的神经⽹络架构或超参数,⽀持各种训练环境。 它常⽤的使⽤场景如下:
•想要在⾃⼰的代码、模型中试验不同的机器学习算法。 •想要在不同的环境中加速运⾏机器学习。
•想要更容易实现或试验新的机器学习算法的研究员或数据科学家,包括:超参调优算法,神经⽹络搜索算法以及模型压缩算法。 它⽀持的框架有:
•PyTorch
•Keras
•TensorFlow
•MXNet
神经生长因子•Caffe2
•Scikit-learn
•XGBoost
•LightGBM
基本上市⾯上所有的深度学习和机器学习的框架它都⽀持。
下⾯就来看看怎么使⽤这个⼯具。
1.准备
pip installnni
2.运⾏⽰例
让我们运⾏⼀个⽰例来验证是否安装成功,⾸先克隆项⽬:
运⾏ MNIST-PYTORCH ⽰例, Linux/macOS:
运⾏ MNIST-PYTORCH ⽰例, Linux/macOS:
nnictl create --config nni/examples/trials/l Windows:
nnictl create --config nni\examples\trials\mnist-pytorch\l 出现这样的界⾯就说明安装成功,⽰例运⾏正常:线粒体基因组测序
3.模型⾃动调参配置
那么如何让 NNI 和我们⾃⼰的模型适配呢?
观察 config_windows.yaml 会发现:
searchSpaceFile: search_space.json
trialCommand: python mnist.py
trialGpuNumber: 0
trialConcurrency: 1
tuner:
name: TPE
classArgs:
optimize_mode: maximize
trainingService:
platform: local
我们先看看 trialCommand, 这很明显是训练使⽤的命令,训练代码位于 mnist.py,其中有部分代码如下:defget_params:
# Training settings
parser = argparse.ArgumentParser(deion= 'PyTorch MNIST Example')
parser.add_argument( "--data_dir", type=str,
default= './data', help= "data directory")
parser.add_argument( '--batch_size', type=int, default= 64, metavar= 'N',
help= 'input batch size for training (default: 64)')
parser.add_argument( "--batch_num", type=int, default= None)
parser.add_argument( "--hidden_size", type=int, default= 512, metavar= 'N',
help= 'hidden layer size (default: 512)')
parser.add_argument( '--lr', type=float, default= 0.01, metavar= 'LR',
help= 'learning rate (default: 0.01)')
parser.add_argument( '--momentum', type=float, default= 0.5, metavar= 'M',
help= 'SGD momentum (default: 0.5)')
parser.add_argument( '--epochs', type=int, default= 10, metavar= 'N',考古墓地
help= 'number of epochs to train (default: 10)')
parser.add_argument( '--seed', type=int, default= 1, metavar= 'S',
help= 'random seed (default: 1)')
parser.add_argument( '--no_cuda', action= 'store_true', default= False,中学语文教学参考
help= 'disables CUDA training')
parser.add_argument( '--log_interval', type=int, default= 1000, metavar= 'N',
help= 'how many batches to wait before logging training status')
args, _ = parser.parse_known_args
returnargs
如上所⽰,这个模型⾥提供了 10 个参数选择。也就是说 NNI 可以帮我们⾃动测试这10个参数。
那么这些参数在哪⾥设定?答案是在 searchSpaceFile 中,对应的值也就是 search_space.json:
{
"batch_size": { "_type": "choice", "_value": [ 16, 32, 64, 128]},
"hidden_size":{ "_type": "choice", "_value":[ 128, 256, 512, 1024]},
"lr":{ "_type": "choice", "_value":[ 0.0001, 0.001, 0.01, 0.1]},
"momentum":{ "_type": "uniform", "_value":[ 0, 1]}
}
加尔文教这⾥有4个选项,NNI 是怎么组合这些参数的呢?这是 tuner 参数⼲的事,为了让机器学习和深度学习模型适应不同的任务和问题,我们需要进⾏超参数调优,⽽⾃动化调优依赖于优秀的调优算法。NNI 内置了先进的调优算法,并且提供了易于使⽤的 API。
在 NNI 中,Tuner 向 trial 发送超参数,接收运⾏结果从⽽评估这组超参的性能,然后将下⼀组超参发送给新的 trial。
下表简要介绍了 NNI 内置的调优算法。
Tuner算法简介
TPE Tree-structured Parzen Estimator (TPE) 是⼀种基于序列模型的优化⽅法。SMBO⽅法根据历史数据来顺序地构造模型,从⽽预估超参性能,并基于此模型来选择新的超参。
Random Search (随机搜索)随机搜索在超算优化中表现出了令⼈意外的性能。如果没有对超参分布的先验知识,我们推荐使⽤随机搜索作为基线⽅法。
Anneal (退⽕)朴素退⽕算法⾸先基于先验进⾏采样,然后逐渐逼近实际性能较好的采样点。该算法是随即搜索的变体,利⽤了反应曲⾯的平滑性。该实现中退⽕率不是⾃适应的。
Naive Evolution(朴素进化)朴素进化算法来⾃于 Large-Scale Evolution of Image Classifiers。它基于搜索空间随机⽣成⼀个种,在每⼀代中选择较好的结果,并对其下⼀代进⾏变异。朴素进化算法需要很多 Trial 才能取得最优效果,但它也⾮常简单,易于扩展。
SMAC SMAC 是基于序列模型的优化⽅法 (SMBO)。它利⽤使⽤过的最突出的模型(⾼斯随机过程模型),并将随机森林引⼊到SMBO中,来处理分类参数。NNI 的 SMAC tuner 封装了 GitHub 上的 SMAC3。参考论⽂注意:SMAC 算法需要使⽤ pip install nni[SMAC]安装依赖,暂不⽀持 Windows 操作系统。
Batch(批处
理)
批处理允许⽤户直接提供若⼲组配置,为每种配置运⾏⼀个 trial。Grid
Search(⽹格
遍历)
⽹格遍历会穷举搜索空间中的所有超参组合。
Hyperband Hyperband 试图⽤有限的资源探索尽可能多的超参组合。该算法的思路是,⾸先⽣成⼤量超参配置,将每组超参运⾏较短的⼀段时间,随后抛弃其中效果较差的⼀半,让较好的超参继续运⾏,如此重复多轮。参考论⽂
Metis ⼤多数调参⼯具仅仅预测最优配置,⽽ Metis 的优势在于它有两个输出:(a) 最优配置的当前预测结果,以及 (b) 下⼀次 trial 的建议。⼤多数⼯具假设训练集没有噪声数据,但 Metis 会知道是否需要对某个超参重新采样。参考论⽂
BOHB BOHB 是 Hyperband 算法的后续⼯作。Hyperband 在⽣成新的配置时,没有利⽤已有的 trial 结果,⽽本算法利⽤了 trial 结果。BOHB 中,HB 表⽰ Hyperband,BO 表⽰贝叶斯优化(Byesian Optimization)。BOHB 会建⽴多个 TPE 模型,从⽽利⽤已完成的 Trial ⽣成新的配置。参考论⽂
GP (⾼斯过
程)
GP Tuner 是基于序列模型的优化⽅法 (SMBO),使⽤⾼斯过程进⾏ surrogate。参考论⽂
PBT PBT Tuner 是⼀种简单的异步优化算法,在固定的计算资源下,它能有效的联合优化⼀组模型及其超参来最优化性能。参考论⽂
DNGO DNGO 是基于序列模型的优化⽅法 (SMBO),该算法使⽤神经⽹络(⽽不是⾼斯过程)去建模贝叶斯优化中所需要的函数分布。
苗逢春可以看到本⽰例中,选择的是TPE tuner.
其他的参数⽐如 trialGpuNumber,指的是使⽤的gpu数量,trialConcurrency 指的是并发数。trainingService 中platform 为 local,指的是本地训练。
当然,还有许多参数可以选,⽐如:
trialConcurrency: 2# 同时运⾏ 2个 trial
maxTrialNumber: 10# 最多⽣成 10个 trial
maxExperimentDuration: 1h # 1⼩时后停⽌⽣成 trial
不过这些参数在调优开始时的web页⾯上是可以进⾏调整的。
所以其实NNI⼲的事情就很清楚了,也很简单。你只需要在你的模型训练⽂件中增加你想要调优的参数作为输⼊,就能使⽤NNI内置的调优算法对不同的参数进⾏调优,⽽且允许从页⾯UI上观察调优的整个过程,相对⽽⾔还是很⽅便的。
不过,NNI可能不太适⽤⼀些数据量极⼤或模型⽐较复杂的情况。⽐如基于DDP开发的模型,在NNI中可能⽆法实现⼤型的分布式计算。
当然,绝⼤多数情况下的训练任务,NNI都可以⽤得上。⼤家有兴趣深⼊使⽤的可以阅读NNI官⽅⽂档:
- EOF -
点击标题可跳转
1、如何⾼效地在⽹上开源项⽬?
2、对⽩嫖彻底失望,著名开源软件作者不愿再⾃费
3、微软⼜⼀个数据可视化神器开源了!⾮常酷炫
觉得本⽂对你有帮助?请分享给更多⼈
推荐关注「Python开发者」,提升Python技能
点赞和在看就是最⼤的⽀持❤