机器学习调参神器 NNI使用简介

NNI自动调参使用简介

前言

  • NNI是微软于2021年8月推出的一款用于支持机器学习实验的工具,它可以以自动化的方式辅助用户进行神经网络架构的设计、模型参数的调节等。NNI具有方便易用、可扩展性强、灵活度高和调节效率高等优点。
  • NNI有中英文官方文档中文地址, 英文地址,其中有详细的使用介绍。这里我们只需要使用其自动调参功能,因此,本文将结合NNI, 基于Pytorch,就自动调参这一需求作详细介绍。使用NNI进行自动架构搜索等内容不再本文讨论范围之内。
  • NNI的整体架构如图所示:


    NNI整体架构

使用概述

  • NNI式一款非侵入的工具,简而言之就是,几乎不用改变原代码的任何内容,就可以实现自动调参、自动架构搜索等功能。如下图所示,假设我们已经有了一个完整的机器学习模型,我们现在需要对部分参数进行网格搜索来确定其最优值,我们可以按照下面的步骤进行:


    NNI工作原理
  1. 确定搜索空间,在search_space.json文件中写下参数名和取值范围
  2. 更新代码,在原代码中加入少量几行代码,将参数传入模型
  3. 编辑配置文件,config.yaml,确定自动调参一些参数,如是否使用GPU,最大搜索轮次等
  4. 执行自动搜索,打开WebUI即可实时查看参数搜索的过程

详细介绍

  • 在本节中,我们将对上述几个步骤作详细介绍
  1. 确定参数搜索空间 search_space.json
    在让框架进行自动参数搜索之前,每一个参数我们可以确定几个候选值或者一定的搜索范围。每一个key代表参数的名称。
    可选的类型有离散和连续等,离散值就是在_value的候选中选择,例如dropout_rate的可选值有0.10.5
    连续值就是一个均匀分布,例如lr的可选值就是上下界为0.00010.1的均匀分布
{
    "dropout_rate": {"_type": "uniform", "_value": [0.1, 0.5]},
    "conv_size": {"_type": "choice", "_value": [2, 3, 5, 7]},
    "hidden_size": {"_type": "choice", "_value": [124, 512, 1024]},
    "batch_size": {"_type": "choice", "_value": [50, 250, 500]},
    "lr": {"_type": "uniform", "_value": [0.0001, 0.1]}
}
  1. 更新代码

由于nni是非侵入的,即只需要在原代码中添加数行由于引入可变参数,而无需删除或者修改原来的代码。
假设我们原来的代码中,参数都存储在名为config的字典(dict)对象中,而我们使用以下方式来传递参数

optimizer = AdamW(optimizer_grouped_parameters, lr=config['lr'])

那么使用NNI,只需要将NNI得到的参数名和参数值更新到原来的config中即可,如下所示:

import nni
params = nni.get_next_parameter()
for k, v in params.items():
    config[k] = v

后续我们再使用下面代码时,config['lr']存储的就是nni传入的参数值

optimizer = AdamW(optimizer_grouped_parameters, lr=config['lr'])

除了参数部分,我们还需要报告当前模型的结果,包括每一个epoch的中间结果和本次实验的最终结果:

# 以下两行看情况插入原代码的合适位置
nni.report_intermediate_result(cur_f1) # 打印每一轮的F1
nni.report_final_result(best_f1)# 打印最终的F1
  1. 编辑配置文件

在使用NNI使用,除了确定模型的参数范围,NNI调参过程本身也有一些参数可以控制,一个典型的配置文件config.yaml内容如下所示:

authorName: unik
experimentName: example_mnist
trialConcurrency: 2
maxExecDuration: 100h
maxTrialNum: 200
trainingServicePlatform: local
searchSpacePath: search_space.json
useAnnotation: false
tuner:
  builtinTunerName: TPE
trial:
  #command: CUDA_VISIBLE_DEVICES=0 python main.py
  command: python main.py
  codeDir: .
  gpuNum: 1
localConfig:
  useActiveGpu: true
  maxTrialNumPerGpu: 1

其中

  • command: python main.py代表模型运行的入口,和手动运行模型的使用的命令保持一致
  • gpuNum: 代表单个实例使用的GPU数量
  • maxTrialNumPerGpu代表一块gpu上最多可以运行几个实例
    其他参数的详细意义可以查阅官网,上述参数配置可以实现利用机器上的多块GPU同时进行多个实例的训练。
    需要注意的是,我们建议在模型中使用下面的方式将模型迁移到cuda
device = torch.device('cuda:0')
model.to(device)
  1. 执行自动搜索
    使用以下命令,开启自动搜索
nnictl create --config config.yaml

打开浏览器,输入http://127.0.0.1:8080即可查看调参过程。网页界面比较友好,功能比较齐全,这里就不做过多介绍。

示例代码

为了方面大家进行后续的探索,笔者实现了一个基本的示例代码,使用NNI+PyTorch框架,对文本情感分类任务进行自动参数调节。
完整代码见 https://github.com/unikcc/nni_experiment

你可能感兴趣的:(机器学习调参神器 NNI使用简介)